mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-30 00:52:16 +08:00
Fix issue where first reserved word of GOT is not initialized if there
is no PLT. gold/ PR gold/16900 * i386.cc (Output_data_got_plt_i386): New class. (Output_data_plt_i386::Output_data_plt_i386): Change type of got_plt parameter. Change all callers. (Output_data_plt_i386::layout_): Remove. (Output_data_plt_i386::got_plt_): Change type. (Target_i386::got_plt_): Change type. Change all references. (Target_i386::got_section): Create instance of new class. (Output_data_got_plt_i386::do_write): New function. * x86_64.cc (Output_data_got_plt_x86_64): New class. (Output_data_plt_x86_64::Output_data_plt_x86_64): Change type of got_plt parameter. Change all callers. (Output_data_plt_x86_64::layout_): Remove. (Output_data_plt_x86_64::got_plt_): Change type. (Target_x86_64::got_plt_): Change type. Change all references. (Target_x86_64::got_section): Create instance of new class. (Output_data_got_plt_x86_64::do_write): New function. (Output_data_plt_x86_64::do_write): Don't write reserved words in GOT. (Target_x86_64<size>::init_got_plt_for_update): Create instance of new class.
This commit is contained in:
@ -1,3 +1,26 @@
|
|||||||
|
2014-05-06 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
|
PR gold/16900
|
||||||
|
* i386.cc (Output_data_got_plt_i386): New class.
|
||||||
|
(Output_data_plt_i386::Output_data_plt_i386): Change type of got_plt
|
||||||
|
parameter. Change all callers.
|
||||||
|
(Output_data_plt_i386::layout_): Remove.
|
||||||
|
(Output_data_plt_i386::got_plt_): Change type.
|
||||||
|
(Target_i386::got_plt_): Change type. Change all references.
|
||||||
|
(Target_i386::got_section): Create instance of new class.
|
||||||
|
(Output_data_got_plt_i386::do_write): New function.
|
||||||
|
* x86_64.cc (Output_data_got_plt_x86_64): New class.
|
||||||
|
(Output_data_plt_x86_64::Output_data_plt_x86_64): Change type of got_plt
|
||||||
|
parameter. Change all callers.
|
||||||
|
(Output_data_plt_x86_64::layout_): Remove.
|
||||||
|
(Output_data_plt_x86_64::got_plt_): Change type.
|
||||||
|
(Target_x86_64::got_plt_): Change type. Change all references.
|
||||||
|
(Target_x86_64::got_section): Create instance of new class.
|
||||||
|
(Output_data_got_plt_x86_64::do_write): New function.
|
||||||
|
(Output_data_plt_x86_64::do_write): Don't write reserved words in GOT.
|
||||||
|
(Target_x86_64<size>::init_got_plt_for_update): Create instance of new
|
||||||
|
class.
|
||||||
|
|
||||||
2014-05-05 Cary Coutant <ccoutant@google.com>
|
2014-05-05 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
* gdb-index.cc (Gdb_index_info_reader): Don't complain about language
|
* gdb-index.cc (Gdb_index_info_reader): Don't complain about language
|
||||||
|
102
gold/i386.cc
102
gold/i386.cc
@ -47,6 +47,32 @@ namespace
|
|||||||
|
|
||||||
using namespace gold;
|
using namespace gold;
|
||||||
|
|
||||||
|
// A class to handle the .got.plt section.
|
||||||
|
|
||||||
|
class Output_data_got_plt_i386 : public Output_section_data_build
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Output_data_got_plt_i386(Layout* layout)
|
||||||
|
: Output_section_data_build(4),
|
||||||
|
layout_(layout)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Write out the PLT data.
|
||||||
|
void
|
||||||
|
do_write(Output_file*);
|
||||||
|
|
||||||
|
// Write to a map file.
|
||||||
|
void
|
||||||
|
do_print_to_mapfile(Mapfile* mapfile) const
|
||||||
|
{ mapfile->print_output_data(this, "** GOT PLT"); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// A pointer to the Layout class, so that we can find the .dynamic
|
||||||
|
// section when we write out the GOT PLT section.
|
||||||
|
Layout* layout_;
|
||||||
|
};
|
||||||
|
|
||||||
// A class to handle the PLT data.
|
// A class to handle the PLT data.
|
||||||
// This is an abstract base class that handles most of the linker details
|
// This is an abstract base class that handles most of the linker details
|
||||||
// but does not know the actual contents of PLT entries. The derived
|
// but does not know the actual contents of PLT entries. The derived
|
||||||
@ -58,7 +84,7 @@ class Output_data_plt_i386 : public Output_section_data
|
|||||||
typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
|
typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
|
||||||
|
|
||||||
Output_data_plt_i386(Layout*, uint64_t addralign,
|
Output_data_plt_i386(Layout*, uint64_t addralign,
|
||||||
Output_data_space*, Output_data_space*);
|
Output_data_got_plt_i386*, Output_data_space*);
|
||||||
|
|
||||||
// Add an entry to the PLT.
|
// Add an entry to the PLT.
|
||||||
void
|
void
|
||||||
@ -201,9 +227,6 @@ class Output_data_plt_i386 : public Output_section_data
|
|||||||
unsigned int got_offset;
|
unsigned int got_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A pointer to the Layout class, so that we can find the .dynamic
|
|
||||||
// section when we write out the GOT PLT section.
|
|
||||||
Layout* layout_;
|
|
||||||
// The reloc section.
|
// The reloc section.
|
||||||
Reloc_section* rel_;
|
Reloc_section* rel_;
|
||||||
// The TLS_DESC relocations, if necessary. These must follow the
|
// The TLS_DESC relocations, if necessary. These must follow the
|
||||||
@ -213,7 +236,7 @@ class Output_data_plt_i386 : public Output_section_data
|
|||||||
// regular relocatoins and the TLS_DESC relocations.
|
// regular relocatoins and the TLS_DESC relocations.
|
||||||
Reloc_section* irelative_rel_;
|
Reloc_section* irelative_rel_;
|
||||||
// The .got.plt section.
|
// The .got.plt section.
|
||||||
Output_data_space* got_plt_;
|
Output_data_got_plt_i386* got_plt_;
|
||||||
// The part of the .got.plt section used for IRELATIVE relocs.
|
// The part of the .got.plt section used for IRELATIVE relocs.
|
||||||
Output_data_space* got_irelative_;
|
Output_data_space* got_irelative_;
|
||||||
// The number of PLT entries.
|
// The number of PLT entries.
|
||||||
@ -236,7 +259,7 @@ class Output_data_plt_i386_standard : public Output_data_plt_i386
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_standard(Layout* layout,
|
Output_data_plt_i386_standard(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
|
: Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -267,7 +290,7 @@ class Output_data_plt_i386_exec : public Output_data_plt_i386_standard
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_exec(Layout* layout,
|
Output_data_plt_i386_exec(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386_standard(layout, got_plt, got_irelative)
|
: Output_data_plt_i386_standard(layout, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -298,7 +321,7 @@ class Output_data_plt_i386_dyn : public Output_data_plt_i386_standard
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_dyn(Layout* layout,
|
Output_data_plt_i386_dyn(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386_standard(layout, got_plt, got_irelative)
|
: Output_data_plt_i386_standard(layout, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -506,14 +529,14 @@ class Target_i386 : public Sized_target<32, false>
|
|||||||
// This chooses the right PLT flavor for an executable or a shared object.
|
// This chooses the right PLT flavor for an executable or a shared object.
|
||||||
Output_data_plt_i386*
|
Output_data_plt_i386*
|
||||||
make_data_plt(Layout* layout,
|
make_data_plt(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
bool dyn)
|
bool dyn)
|
||||||
{ return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }
|
{ return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }
|
||||||
|
|
||||||
virtual Output_data_plt_i386*
|
virtual Output_data_plt_i386*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
bool dyn)
|
bool dyn)
|
||||||
{
|
{
|
||||||
@ -720,7 +743,7 @@ class Target_i386 : public Sized_target<32, false>
|
|||||||
got_section(Symbol_table*, Layout*);
|
got_section(Symbol_table*, Layout*);
|
||||||
|
|
||||||
// Get the GOT PLT section.
|
// Get the GOT PLT section.
|
||||||
Output_data_space*
|
Output_data_got_plt_i386*
|
||||||
got_plt_section() const
|
got_plt_section() const
|
||||||
{
|
{
|
||||||
gold_assert(this->got_plt_ != NULL);
|
gold_assert(this->got_plt_ != NULL);
|
||||||
@ -813,7 +836,7 @@ class Target_i386 : public Sized_target<32, false>
|
|||||||
// The PLT section.
|
// The PLT section.
|
||||||
Output_data_plt_i386* plt_;
|
Output_data_plt_i386* plt_;
|
||||||
// The GOT PLT section.
|
// The GOT PLT section.
|
||||||
Output_data_space* got_plt_;
|
Output_data_got_plt_i386* got_plt_;
|
||||||
// The GOT section for IRELATIVE relocations.
|
// The GOT section for IRELATIVE relocations.
|
||||||
Output_data_space* got_irelative_;
|
Output_data_space* got_irelative_;
|
||||||
// The GOT section for TLSDESC relocations.
|
// The GOT section for TLSDESC relocations.
|
||||||
@ -885,7 +908,7 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout)
|
|||||||
| elfcpp::SHF_WRITE),
|
| elfcpp::SHF_WRITE),
|
||||||
this->got_, got_order, true);
|
this->got_, got_order, true);
|
||||||
|
|
||||||
this->got_plt_ = new Output_data_space(4, "** GOT PLT");
|
this->got_plt_ = new Output_data_got_plt_i386(layout);
|
||||||
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
||||||
(elfcpp::SHF_ALLOC
|
(elfcpp::SHF_ALLOC
|
||||||
| elfcpp::SHF_WRITE),
|
| elfcpp::SHF_WRITE),
|
||||||
@ -972,18 +995,39 @@ Target_i386::rel_irelative_section(Layout* layout)
|
|||||||
return this->rel_irelative_;
|
return this->rel_irelative_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the first three reserved words of the .got.plt section.
|
||||||
|
// The remainder of the section is written while writing the PLT
|
||||||
|
// in Output_data_plt_i386::do_write.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_data_got_plt_i386::do_write(Output_file* of)
|
||||||
|
{
|
||||||
|
// The first entry in the GOT is the address of the .dynamic section
|
||||||
|
// aka the PT_DYNAMIC segment. The next two entries are reserved.
|
||||||
|
// We saved space for them when we created the section in
|
||||||
|
// Target_i386::got_section.
|
||||||
|
const off_t got_file_offset = this->offset();
|
||||||
|
gold_assert(this->data_size() >= 12);
|
||||||
|
unsigned char* const got_view = of->get_output_view(got_file_offset, 12);
|
||||||
|
Output_section* dynamic = this->layout_->dynamic_section();
|
||||||
|
uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
|
||||||
|
elfcpp::Swap<32, false>::writeval(got_view, dynamic_addr);
|
||||||
|
memset(got_view + 4, 0, 8);
|
||||||
|
of->write_output_view(got_file_offset, 12, got_view);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the PLT section. The ordinary .got section is an argument,
|
// Create the PLT section. The ordinary .got section is an argument,
|
||||||
// since we need to refer to the start. We also create our own .got
|
// since we need to refer to the start. We also create our own .got
|
||||||
// section just for PLT entries.
|
// section just for PLT entries.
|
||||||
|
|
||||||
Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
|
Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
|
||||||
uint64_t addralign,
|
uint64_t addralign,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_section_data(addralign),
|
: Output_section_data(addralign),
|
||||||
layout_(layout), tls_desc_rel_(NULL),
|
tls_desc_rel_(NULL), irelative_rel_(NULL), got_plt_(got_plt),
|
||||||
irelative_rel_(NULL), got_plt_(got_plt), got_irelative_(got_irelative),
|
got_irelative_(got_irelative), count_(0), irelative_count_(0),
|
||||||
count_(0), irelative_count_(0), global_ifuncs_(), local_ifuncs_()
|
global_ifuncs_(), local_ifuncs_()
|
||||||
{
|
{
|
||||||
this->rel_ = new Reloc_section(false);
|
this->rel_ = new Reloc_section(false);
|
||||||
layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
|
layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
|
||||||
@ -1323,6 +1367,7 @@ Output_data_plt_i386::do_write(Output_file* of)
|
|||||||
const section_size_type got_size =
|
const section_size_type got_size =
|
||||||
convert_to_section_size_type(this->got_plt_->data_size()
|
convert_to_section_size_type(this->got_plt_->data_size()
|
||||||
+ this->got_irelative_->data_size());
|
+ this->got_irelative_->data_size());
|
||||||
|
|
||||||
unsigned char* const got_view = of->get_output_view(got_file_offset,
|
unsigned char* const got_view = of->get_output_view(got_file_offset,
|
||||||
got_size);
|
got_size);
|
||||||
|
|
||||||
@ -1334,18 +1379,9 @@ Output_data_plt_i386::do_write(Output_file* of)
|
|||||||
this->fill_first_plt_entry(pov, got_address);
|
this->fill_first_plt_entry(pov, got_address);
|
||||||
pov += this->get_plt_entry_size();
|
pov += this->get_plt_entry_size();
|
||||||
|
|
||||||
unsigned char* got_pov = got_view;
|
// The first three entries in the GOT are reserved, and are written
|
||||||
|
// by Output_data_got_plt_i386::do_write.
|
||||||
// The first entry in the GOT is the address of the .dynamic section
|
unsigned char* got_pov = got_view + 12;
|
||||||
// aka the PT_DYNAMIC segment. The next two entries are reserved.
|
|
||||||
// We saved space for them when we created the section in
|
|
||||||
// Target_i386::got_section.
|
|
||||||
Output_section* dynamic = this->layout_->dynamic_section();
|
|
||||||
uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
|
|
||||||
elfcpp::Swap<32, false>::writeval(got_pov, dynamic_addr);
|
|
||||||
got_pov += 4;
|
|
||||||
memset(got_pov, 0, 8);
|
|
||||||
got_pov += 8;
|
|
||||||
|
|
||||||
const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
|
const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
|
||||||
|
|
||||||
@ -3834,7 +3870,7 @@ class Output_data_plt_i386_nacl : public Output_data_plt_i386
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_nacl(Layout* layout,
|
Output_data_plt_i386_nacl(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
|
: Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -3863,7 +3899,7 @@ class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_nacl_exec(Layout* layout,
|
Output_data_plt_i386_nacl_exec(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
|
: Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -3892,7 +3928,7 @@ class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Output_data_plt_i386_nacl_dyn(Layout* layout,
|
Output_data_plt_i386_nacl_dyn(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
|
: Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
|
||||||
{ }
|
{ }
|
||||||
@ -3926,7 +3962,7 @@ class Target_i386_nacl : public Target_i386
|
|||||||
protected:
|
protected:
|
||||||
virtual Output_data_plt_i386*
|
virtual Output_data_plt_i386*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_i386* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
bool dyn)
|
bool dyn)
|
||||||
{
|
{
|
||||||
|
110
gold/x86_64.cc
110
gold/x86_64.cc
@ -48,6 +48,37 @@ namespace
|
|||||||
|
|
||||||
using namespace gold;
|
using namespace gold;
|
||||||
|
|
||||||
|
// A class to handle the .got.plt section.
|
||||||
|
|
||||||
|
class Output_data_got_plt_x86_64 : public Output_section_data_build
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Output_data_got_plt_x86_64(Layout* layout)
|
||||||
|
: Output_section_data_build(8),
|
||||||
|
layout_(layout)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Output_data_got_plt_x86_64(Layout* layout, off_t data_size)
|
||||||
|
: Output_section_data_build(data_size, 8),
|
||||||
|
layout_(layout)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Write out the PLT data.
|
||||||
|
void
|
||||||
|
do_write(Output_file*);
|
||||||
|
|
||||||
|
// Write to a map file.
|
||||||
|
void
|
||||||
|
do_print_to_mapfile(Mapfile* mapfile) const
|
||||||
|
{ mapfile->print_output_data(this, "** GOT PLT"); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// A pointer to the Layout class, so that we can find the .dynamic
|
||||||
|
// section when we write out the GOT PLT section.
|
||||||
|
Layout* layout_;
|
||||||
|
};
|
||||||
|
|
||||||
// A class to handle the PLT data.
|
// A class to handle the PLT data.
|
||||||
// This is an abstract base class that handles most of the linker details
|
// This is an abstract base class that handles most of the linker details
|
||||||
// but does not know the actual contents of PLT entries. The derived
|
// but does not know the actual contents of PLT entries. The derived
|
||||||
@ -61,9 +92,9 @@ class Output_data_plt_x86_64 : public Output_section_data
|
|||||||
|
|
||||||
Output_data_plt_x86_64(Layout* layout, uint64_t addralign,
|
Output_data_plt_x86_64(Layout* layout, uint64_t addralign,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_section_data(addralign), layout_(layout), tlsdesc_rel_(NULL),
|
: Output_section_data(addralign), tlsdesc_rel_(NULL),
|
||||||
irelative_rel_(NULL), got_(got), got_plt_(got_plt),
|
irelative_rel_(NULL), got_(got), got_plt_(got_plt),
|
||||||
got_irelative_(got_irelative), count_(0), irelative_count_(0),
|
got_irelative_(got_irelative), count_(0), irelative_count_(0),
|
||||||
tlsdesc_got_offset_(-1U), free_list_()
|
tlsdesc_got_offset_(-1U), free_list_()
|
||||||
@ -71,12 +102,12 @@ class Output_data_plt_x86_64 : public Output_section_data
|
|||||||
|
|
||||||
Output_data_plt_x86_64(Layout* layout, uint64_t plt_entry_size,
|
Output_data_plt_x86_64(Layout* layout, uint64_t plt_entry_size,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
: Output_section_data((plt_count + 1) * plt_entry_size,
|
: Output_section_data((plt_count + 1) * plt_entry_size,
|
||||||
plt_entry_size, false),
|
plt_entry_size, false),
|
||||||
layout_(layout), tlsdesc_rel_(NULL), irelative_rel_(NULL), got_(got),
|
tlsdesc_rel_(NULL), irelative_rel_(NULL), got_(got),
|
||||||
got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
|
got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
|
||||||
irelative_count_(0), tlsdesc_got_offset_(-1U), free_list_()
|
irelative_count_(0), tlsdesc_got_offset_(-1U), free_list_()
|
||||||
{
|
{
|
||||||
@ -268,9 +299,6 @@ class Output_data_plt_x86_64 : public Output_section_data
|
|||||||
void
|
void
|
||||||
do_write(Output_file*);
|
do_write(Output_file*);
|
||||||
|
|
||||||
// A pointer to the Layout class, so that we can find the .dynamic
|
|
||||||
// section when we write out the GOT PLT section.
|
|
||||||
Layout* layout_;
|
|
||||||
// The reloc section.
|
// The reloc section.
|
||||||
Reloc_section* rel_;
|
Reloc_section* rel_;
|
||||||
// The TLSDESC relocs, if necessary. These must follow the regular
|
// The TLSDESC relocs, if necessary. These must follow the regular
|
||||||
@ -282,7 +310,7 @@ class Output_data_plt_x86_64 : public Output_section_data
|
|||||||
// The .got section.
|
// The .got section.
|
||||||
Output_data_got<64, false>* got_;
|
Output_data_got<64, false>* got_;
|
||||||
// The .got.plt section.
|
// The .got.plt section.
|
||||||
Output_data_space* got_plt_;
|
Output_data_got_plt_x86_64* got_plt_;
|
||||||
// The part of the .got.plt section used for IRELATIVE relocs.
|
// The part of the .got.plt section used for IRELATIVE relocs.
|
||||||
Output_data_space* got_irelative_;
|
Output_data_space* got_irelative_;
|
||||||
// The number of PLT entries.
|
// The number of PLT entries.
|
||||||
@ -303,7 +331,7 @@ class Output_data_plt_x86_64_standard : public Output_data_plt_x86_64<size>
|
|||||||
public:
|
public:
|
||||||
Output_data_plt_x86_64_standard(Layout* layout,
|
Output_data_plt_x86_64_standard(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
||||||
got, got_plt, got_irelative)
|
got, got_plt, got_irelative)
|
||||||
@ -311,7 +339,7 @@ class Output_data_plt_x86_64_standard : public Output_data_plt_x86_64<size>
|
|||||||
|
|
||||||
Output_data_plt_x86_64_standard(Layout* layout,
|
Output_data_plt_x86_64_standard(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
||||||
@ -618,7 +646,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
Output_data_plt_x86_64<size>*
|
Output_data_plt_x86_64<size>*
|
||||||
make_data_plt(Layout* layout,
|
make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
{
|
{
|
||||||
return this->do_make_data_plt(layout, got, got_plt, got_irelative);
|
return this->do_make_data_plt(layout, got, got_plt, got_irelative);
|
||||||
@ -627,7 +655,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
Output_data_plt_x86_64<size>*
|
Output_data_plt_x86_64<size>*
|
||||||
make_data_plt(Layout* layout,
|
make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
{
|
{
|
||||||
@ -638,7 +666,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
virtual Output_data_plt_x86_64<size>*
|
virtual Output_data_plt_x86_64<size>*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
{
|
{
|
||||||
return new Output_data_plt_x86_64_standard<size>(layout, got, got_plt,
|
return new Output_data_plt_x86_64_standard<size>(layout, got, got_plt,
|
||||||
@ -648,7 +676,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
virtual Output_data_plt_x86_64<size>*
|
virtual Output_data_plt_x86_64<size>*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
{
|
{
|
||||||
@ -847,7 +875,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
got_section(Symbol_table*, Layout*);
|
got_section(Symbol_table*, Layout*);
|
||||||
|
|
||||||
// Get the GOT PLT section.
|
// Get the GOT PLT section.
|
||||||
Output_data_space*
|
Output_data_got_plt_x86_64*
|
||||||
got_plt_section() const
|
got_plt_section() const
|
||||||
{
|
{
|
||||||
gold_assert(this->got_plt_ != NULL);
|
gold_assert(this->got_plt_ != NULL);
|
||||||
@ -958,7 +986,7 @@ class Target_x86_64 : public Sized_target<size, false>
|
|||||||
// The PLT section.
|
// The PLT section.
|
||||||
Output_data_plt_x86_64<size>* plt_;
|
Output_data_plt_x86_64<size>* plt_;
|
||||||
// The GOT PLT section.
|
// The GOT PLT section.
|
||||||
Output_data_space* got_plt_;
|
Output_data_got_plt_x86_64* got_plt_;
|
||||||
// The GOT section for IRELATIVE relocations.
|
// The GOT section for IRELATIVE relocations.
|
||||||
Output_data_space* got_irelative_;
|
Output_data_space* got_irelative_;
|
||||||
// The GOT section for TLSDESC relocations.
|
// The GOT section for TLSDESC relocations.
|
||||||
@ -1074,7 +1102,7 @@ Target_x86_64<size>::got_section(Symbol_table* symtab, Layout* layout)
|
|||||||
| elfcpp::SHF_WRITE),
|
| elfcpp::SHF_WRITE),
|
||||||
this->got_, got_order, true);
|
this->got_, got_order, true);
|
||||||
|
|
||||||
this->got_plt_ = new Output_data_space(8, "** GOT PLT");
|
this->got_plt_ = new Output_data_got_plt_x86_64(layout);
|
||||||
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
||||||
(elfcpp::SHF_ALLOC
|
(elfcpp::SHF_ALLOC
|
||||||
| elfcpp::SHF_WRITE),
|
| elfcpp::SHF_WRITE),
|
||||||
@ -1163,6 +1191,27 @@ Target_x86_64<size>::rela_irelative_section(Layout* layout)
|
|||||||
return this->rela_irelative_;
|
return this->rela_irelative_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the first three reserved words of the .got.plt section.
|
||||||
|
// The remainder of the section is written while writing the PLT
|
||||||
|
// in Output_data_plt_i386::do_write.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_data_got_plt_x86_64::do_write(Output_file* of)
|
||||||
|
{
|
||||||
|
// The first entry in the GOT is the address of the .dynamic section
|
||||||
|
// aka the PT_DYNAMIC segment. The next two entries are reserved.
|
||||||
|
// We saved space for them when we created the section in
|
||||||
|
// Target_x86_64::got_section.
|
||||||
|
const off_t got_file_offset = this->offset();
|
||||||
|
gold_assert(this->data_size() >= 24);
|
||||||
|
unsigned char* const got_view = of->get_output_view(got_file_offset, 24);
|
||||||
|
Output_section* dynamic = this->layout_->dynamic_section();
|
||||||
|
uint64_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
|
||||||
|
elfcpp::Swap<64, false>::writeval(got_view, dynamic_addr);
|
||||||
|
memset(got_view + 8, 0, 16);
|
||||||
|
of->write_output_view(got_file_offset, 24, got_view);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the PLT section.
|
// Initialize the PLT section.
|
||||||
|
|
||||||
template<int size>
|
template<int size>
|
||||||
@ -1198,7 +1247,7 @@ Output_data_plt_x86_64<size>::add_entry(Symbol_table* symtab, Layout* layout,
|
|||||||
unsigned int* pcount;
|
unsigned int* pcount;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
unsigned int reserved;
|
unsigned int reserved;
|
||||||
Output_data_space* got;
|
Output_section_data_build* got;
|
||||||
if (gsym->type() == elfcpp::STT_GNU_IFUNC
|
if (gsym->type() == elfcpp::STT_GNU_IFUNC
|
||||||
&& gsym->can_use_relative_reloc(false))
|
&& gsym->can_use_relative_reloc(false))
|
||||||
{
|
{
|
||||||
@ -1605,18 +1654,9 @@ Output_data_plt_x86_64<size>::do_write(Output_file* of)
|
|||||||
this->fill_first_plt_entry(pov, got_address, plt_address);
|
this->fill_first_plt_entry(pov, got_address, plt_address);
|
||||||
pov += this->get_plt_entry_size();
|
pov += this->get_plt_entry_size();
|
||||||
|
|
||||||
unsigned char* got_pov = got_view;
|
// The first three entries in the GOT are reserved, and are written
|
||||||
|
// by Output_data_got_plt_x86_64::do_write.
|
||||||
// The first entry in the GOT is the address of the .dynamic section
|
unsigned char* got_pov = got_view + 24;
|
||||||
// aka the PT_DYNAMIC segment. The next two entries are reserved.
|
|
||||||
// We saved space for them when we created the section in
|
|
||||||
// Target_x86_64::got_section.
|
|
||||||
Output_section* dynamic = this->layout_->dynamic_section();
|
|
||||||
uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
|
|
||||||
elfcpp::Swap<64, false>::writeval(got_pov, dynamic_addr);
|
|
||||||
got_pov += 8;
|
|
||||||
memset(got_pov, 0, 16);
|
|
||||||
got_pov += 16;
|
|
||||||
|
|
||||||
unsigned int plt_offset = this->get_plt_entry_size();
|
unsigned int plt_offset = this->get_plt_entry_size();
|
||||||
unsigned int got_offset = 24;
|
unsigned int got_offset = 24;
|
||||||
@ -1777,7 +1817,7 @@ Target_x86_64<size>::init_got_plt_for_update(Symbol_table* symtab,
|
|||||||
true);
|
true);
|
||||||
|
|
||||||
// Add the three reserved entries.
|
// Add the three reserved entries.
|
||||||
this->got_plt_ = new Output_data_space((plt_count + 3) * 8, 8, "** GOT PLT");
|
this->got_plt_ = new Output_data_got_plt_x86_64(layout, (plt_count + 3) * 8);
|
||||||
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
||||||
(elfcpp::SHF_ALLOC
|
(elfcpp::SHF_ALLOC
|
||||||
| elfcpp::SHF_WRITE),
|
| elfcpp::SHF_WRITE),
|
||||||
@ -4500,7 +4540,7 @@ class Output_data_plt_x86_64_nacl : public Output_data_plt_x86_64<size>
|
|||||||
public:
|
public:
|
||||||
Output_data_plt_x86_64_nacl(Layout* layout,
|
Output_data_plt_x86_64_nacl(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
||||||
got, got_plt, got_irelative)
|
got, got_plt, got_irelative)
|
||||||
@ -4508,7 +4548,7 @@ class Output_data_plt_x86_64_nacl : public Output_data_plt_x86_64<size>
|
|||||||
|
|
||||||
Output_data_plt_x86_64_nacl(Layout* layout,
|
Output_data_plt_x86_64_nacl(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
: Output_data_plt_x86_64<size>(layout, plt_entry_size,
|
||||||
@ -4581,7 +4621,7 @@ class Target_x86_64_nacl : public Target_x86_64<size>
|
|||||||
virtual Output_data_plt_x86_64<size>*
|
virtual Output_data_plt_x86_64<size>*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative)
|
Output_data_space* got_irelative)
|
||||||
{
|
{
|
||||||
return new Output_data_plt_x86_64_nacl<size>(layout, got, got_plt,
|
return new Output_data_plt_x86_64_nacl<size>(layout, got, got_plt,
|
||||||
@ -4591,7 +4631,7 @@ class Target_x86_64_nacl : public Target_x86_64<size>
|
|||||||
virtual Output_data_plt_x86_64<size>*
|
virtual Output_data_plt_x86_64<size>*
|
||||||
do_make_data_plt(Layout* layout,
|
do_make_data_plt(Layout* layout,
|
||||||
Output_data_got<64, false>* got,
|
Output_data_got<64, false>* got,
|
||||||
Output_data_space* got_plt,
|
Output_data_got_plt_x86_64* got_plt,
|
||||||
Output_data_space* got_irelative,
|
Output_data_space* got_irelative,
|
||||||
unsigned int plt_count)
|
unsigned int plt_count)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user