mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
From Craig Silverstein: Implement GOTPLT64 and PLTOFF64.
This commit is contained in:
@ -289,7 +289,6 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout)
|
|||||||
// create another set of data in the .got section. Note that we
|
// create another set of data in the .got section. Note that we
|
||||||
// always create a PLT if we create a GOT, although the PLT
|
// always create a PLT if we create a GOT, although the PLT
|
||||||
// might be empty.
|
// might be empty.
|
||||||
// TODO(csilvers): do we really need an alignment of 8?
|
|
||||||
this->got_plt_ = new Output_data_space(8);
|
this->got_plt_ = new Output_data_space(8);
|
||||||
layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||||
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
|
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
|
||||||
@ -382,7 +381,6 @@ class Output_data_plt_x86_64 : public Output_section_data
|
|||||||
|
|
||||||
Output_data_plt_x86_64::Output_data_plt_x86_64(Layout* layout,
|
Output_data_plt_x86_64::Output_data_plt_x86_64(Layout* layout,
|
||||||
Output_data_space* got_plt)
|
Output_data_space* got_plt)
|
||||||
// TODO(csilvers): do we really need an alignment of 8?
|
|
||||||
: Output_section_data(8), got_plt_(got_plt), count_(0)
|
: Output_section_data(8), got_plt_(got_plt), count_(0)
|
||||||
{
|
{
|
||||||
this->rel_ = new Reloc_section();
|
this->rel_ = new Reloc_section();
|
||||||
@ -743,12 +741,15 @@ Target_x86_64::Scan::local(const General_options&,
|
|||||||
case elfcpp::R_X86_64_PLTOFF64:
|
case elfcpp::R_X86_64_PLTOFF64:
|
||||||
// We need a GOT section.
|
// We need a GOT section.
|
||||||
target->got_section(symtab, layout);
|
target->got_section(symtab, layout);
|
||||||
|
// For PLTOFF64, we'd normally want a PLT section, but since we
|
||||||
|
// know this is a local symbol, no PLT is needed.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_GOT64:
|
case elfcpp::R_X86_64_GOT64:
|
||||||
case elfcpp::R_X86_64_GOT32:
|
case elfcpp::R_X86_64_GOT32:
|
||||||
case elfcpp::R_X86_64_GOTPCREL64:
|
case elfcpp::R_X86_64_GOTPCREL64:
|
||||||
case elfcpp::R_X86_64_GOTPCREL:
|
case elfcpp::R_X86_64_GOTPCREL:
|
||||||
|
case elfcpp::R_X86_64_GOTPLT64:
|
||||||
{
|
{
|
||||||
// The symbol requires a GOT entry.
|
// The symbol requires a GOT entry.
|
||||||
Output_data_got<64, false>* got = target->got_section(symtab, layout);
|
Output_data_got<64, false>* got = target->got_section(symtab, layout);
|
||||||
@ -764,6 +765,8 @@ Target_x86_64::Scan::local(const General_options&,
|
|||||||
data_shndx, reloc.get_r_offset(), 0);
|
data_shndx, reloc.get_r_offset(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// For GOTPLT64, we'd normally want a PLT section, but since
|
||||||
|
// we know this is a local symbol, no PLT is needed.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -831,7 +834,6 @@ Target_x86_64::Scan::local(const General_options&,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_GOTPLT64:
|
|
||||||
case elfcpp::R_X86_64_SIZE32:
|
case elfcpp::R_X86_64_SIZE32:
|
||||||
case elfcpp::R_X86_64_SIZE64:
|
case elfcpp::R_X86_64_SIZE64:
|
||||||
default:
|
default:
|
||||||
@ -933,6 +935,11 @@ Target_x86_64::Scan::global(const General_options& options,
|
|||||||
gsym->got_offset(), 0);
|
gsym->got_offset(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// For GOTPLT64, we also need a PLT entry (but only if the
|
||||||
|
// symbol is not fully resolved).
|
||||||
|
if (r_type == elfcpp::R_X86_64_GOTPLT64
|
||||||
|
&& !gsym->final_value_is_known())
|
||||||
|
target->make_plt_entry(symtab, layout, gsym);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -950,6 +957,11 @@ Target_x86_64::Scan::global(const General_options& options,
|
|||||||
case elfcpp::R_X86_64_PLTOFF64:
|
case elfcpp::R_X86_64_PLTOFF64:
|
||||||
// We need a GOT section.
|
// We need a GOT section.
|
||||||
target->got_section(symtab, layout);
|
target->got_section(symtab, layout);
|
||||||
|
// For PLTOFF64, we also need a PLT entry (but only if the
|
||||||
|
// symbol is not fully resolved).
|
||||||
|
if (r_type == elfcpp::R_X86_64_PLTOFF64
|
||||||
|
&& !gsym->final_value_is_known())
|
||||||
|
target->make_plt_entry(symtab, layout, gsym);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_COPY:
|
case elfcpp::R_X86_64_COPY:
|
||||||
@ -1239,10 +1251,24 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
|
|||||||
gold_assert(gsym == NULL
|
gold_assert(gsym == NULL
|
||||||
|| gsym->has_plt_offset()
|
|| gsym->has_plt_offset()
|
||||||
|| gsym->final_value_is_known());
|
|| gsym->final_value_is_known());
|
||||||
|
// Note: while this code looks the same as for R_X86_64_PC32, it
|
||||||
|
// behaves differently because psymval was set to point to
|
||||||
|
// the PLT entry, rather than the symbol, in Scan::global().
|
||||||
Relocate_functions<64, false>::pcrela32(view, object, psymval, addend,
|
Relocate_functions<64, false>::pcrela32(view, object, psymval, addend,
|
||||||
address);
|
address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case elfcpp::R_X86_64_PLTOFF64:
|
||||||
|
{
|
||||||
|
gold_assert(gsym);
|
||||||
|
gold_assert(gsym->has_plt_offset()
|
||||||
|
|| gsym->final_value_is_known());
|
||||||
|
elfcpp::Elf_types<64>::Elf_Addr got_address;
|
||||||
|
got_address = target->got_section(NULL, NULL)->address();
|
||||||
|
Relocate_functions<64, false>::pcrela64(view, object, psymval, addend,
|
||||||
|
- got_address);
|
||||||
|
}
|
||||||
|
|
||||||
case elfcpp::R_X86_64_GOT32:
|
case elfcpp::R_X86_64_GOT32:
|
||||||
gold_assert(have_got_offset);
|
gold_assert(have_got_offset);
|
||||||
Relocate_functions<64, false>::rela32(view, got_offset, addend);
|
Relocate_functions<64, false>::rela32(view, got_offset, addend);
|
||||||
@ -1329,7 +1355,6 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
|
|||||||
|
|
||||||
case elfcpp::R_X86_64_SIZE32:
|
case elfcpp::R_X86_64_SIZE32:
|
||||||
case elfcpp::R_X86_64_SIZE64:
|
case elfcpp::R_X86_64_SIZE64:
|
||||||
case elfcpp::R_X86_64_PLTOFF64: // FIXME: implement me!
|
|
||||||
default:
|
default:
|
||||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
||||||
_("unsupported reloc %u"),
|
_("unsupported reloc %u"),
|
||||||
|
Reference in New Issue
Block a user