mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 12:33:36 +08:00
PR gold/11985
* layout.cc (Layout::create_initial_dynamic_sections): Don't crash if linker script discards key sections. (Layout::create_dynamic_symtab): Likewise. (Layout::assign_local_dynsym_offsets): Likewise. (Layout::sized_create_version_sections): Likewise. (Layout::create_interp): Likewise. (Layout::finish_dynamic_section): Likewise. (Layout::set_dynamic_symbol_size): Likewise.
This commit is contained in:
parent
0c51100021
commit
6daf5215b7
@ -1,3 +1,15 @@
|
|||||||
|
2011-07-08 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
PR gold/11985
|
||||||
|
* layout.cc (Layout::create_initial_dynamic_sections): Don't crash
|
||||||
|
if linker script discards key sections.
|
||||||
|
(Layout::create_dynamic_symtab): Likewise.
|
||||||
|
(Layout::assign_local_dynsym_offsets): Likewise.
|
||||||
|
(Layout::sized_create_version_sections): Likewise.
|
||||||
|
(Layout::create_interp): Likewise.
|
||||||
|
(Layout::finish_dynamic_section): Likewise.
|
||||||
|
(Layout::set_dynamic_symbol_size): Likewise.
|
||||||
|
|
||||||
2011-07-08 Ian Lance Taylor <iant@google.com>
|
2011-07-08 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
PR gold/12386
|
PR gold/12386
|
||||||
|
243
gold/layout.cc
243
gold/layout.cc
@ -1786,15 +1786,20 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab)
|
|||||||
false, ORDER_RELRO,
|
false, ORDER_RELRO,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
this->dynamic_symbol_ =
|
// A linker script may discard .dynamic, so check for NULL.
|
||||||
symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED,
|
if (this->dynamic_section_ != NULL)
|
||||||
this->dynamic_section_, 0, 0,
|
{
|
||||||
elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
|
this->dynamic_symbol_ =
|
||||||
elfcpp::STV_HIDDEN, 0, false, false);
|
symtab->define_in_output_data("_DYNAMIC", NULL,
|
||||||
|
Symbol_table::PREDEFINED,
|
||||||
|
this->dynamic_section_, 0, 0,
|
||||||
|
elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
|
||||||
|
elfcpp::STV_HIDDEN, 0, false, false);
|
||||||
|
|
||||||
this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_);
|
this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_);
|
||||||
|
|
||||||
this->dynamic_section_->add_output_section_data(this->dynamic_data_);
|
this->dynamic_section_->add_output_section_data(this->dynamic_data_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each output section whose name can be represented as C symbol,
|
// For each output section whose name can be represented as C symbol,
|
||||||
@ -3708,20 +3713,27 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||||||
ORDER_DYNAMIC_LINKER,
|
ORDER_DYNAMIC_LINKER,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
Output_section_data* odata = new Output_data_fixed_space(index * symsize,
|
// Check for NULL as a linker script may discard .dynsym.
|
||||||
align,
|
if (dynsym != NULL)
|
||||||
"** dynsym");
|
{
|
||||||
dynsym->add_output_section_data(odata);
|
Output_section_data* odata = new Output_data_fixed_space(index * symsize,
|
||||||
|
align,
|
||||||
|
"** dynsym");
|
||||||
|
dynsym->add_output_section_data(odata);
|
||||||
|
|
||||||
dynsym->set_info(local_symcount);
|
dynsym->set_info(local_symcount);
|
||||||
dynsym->set_entsize(symsize);
|
dynsym->set_entsize(symsize);
|
||||||
dynsym->set_addralign(align);
|
dynsym->set_addralign(align);
|
||||||
|
|
||||||
this->dynsym_section_ = dynsym;
|
this->dynsym_section_ = dynsym;
|
||||||
|
}
|
||||||
|
|
||||||
Output_data_dynamic* const odyn = this->dynamic_data_;
|
Output_data_dynamic* const odyn = this->dynamic_data_;
|
||||||
odyn->add_section_address(elfcpp::DT_SYMTAB, dynsym);
|
if (odyn != NULL)
|
||||||
odyn->add_constant(elfcpp::DT_SYMENT, symsize);
|
{
|
||||||
|
odyn->add_section_address(elfcpp::DT_SYMTAB, dynsym);
|
||||||
|
odyn->add_constant(elfcpp::DT_SYMENT, symsize);
|
||||||
|
}
|
||||||
|
|
||||||
// If there are more than SHN_LORESERVE allocated sections, we
|
// If there are more than SHN_LORESERVE allocated sections, we
|
||||||
// create a .dynsym_shndx section. It is possible that we don't
|
// create a .dynsym_shndx section. It is possible that we don't
|
||||||
@ -3738,20 +3750,23 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||||||
elfcpp::SHF_ALLOC,
|
elfcpp::SHF_ALLOC,
|
||||||
false, ORDER_DYNAMIC_LINKER, false);
|
false, ORDER_DYNAMIC_LINKER, false);
|
||||||
|
|
||||||
this->dynsym_xindex_ = new Output_symtab_xindex(index);
|
if (dynsym_xindex != NULL)
|
||||||
|
{
|
||||||
|
this->dynsym_xindex_ = new Output_symtab_xindex(index);
|
||||||
|
|
||||||
dynsym_xindex->add_output_section_data(this->dynsym_xindex_);
|
dynsym_xindex->add_output_section_data(this->dynsym_xindex_);
|
||||||
|
|
||||||
dynsym_xindex->set_link_section(dynsym);
|
dynsym_xindex->set_link_section(dynsym);
|
||||||
dynsym_xindex->set_addralign(4);
|
dynsym_xindex->set_addralign(4);
|
||||||
dynsym_xindex->set_entsize(4);
|
dynsym_xindex->set_entsize(4);
|
||||||
|
|
||||||
dynsym_xindex->set_after_input_sections();
|
dynsym_xindex->set_after_input_sections();
|
||||||
|
|
||||||
// This tells the driver code to wait until the symbol table has
|
// This tells the driver code to wait until the symbol table
|
||||||
// written out before writing out the postprocessing sections,
|
// has written out before writing out the postprocessing
|
||||||
// including the .dynsym_shndx section.
|
// sections, including the .dynsym_shndx section.
|
||||||
this->any_postprocessing_sections_ = true;
|
this->any_postprocessing_sections_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the dynamic string table section.
|
// Create the dynamic string table section.
|
||||||
@ -3763,16 +3778,24 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||||||
ORDER_DYNAMIC_LINKER,
|
ORDER_DYNAMIC_LINKER,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
Output_section_data* strdata = new Output_data_strtab(&this->dynpool_);
|
if (dynstr != NULL)
|
||||||
dynstr->add_output_section_data(strdata);
|
{
|
||||||
|
Output_section_data* strdata = new Output_data_strtab(&this->dynpool_);
|
||||||
|
dynstr->add_output_section_data(strdata);
|
||||||
|
|
||||||
dynsym->set_link_section(dynstr);
|
if (dynsym != NULL)
|
||||||
this->dynamic_section_->set_link_section(dynstr);
|
dynsym->set_link_section(dynstr);
|
||||||
|
if (this->dynamic_section_ != NULL)
|
||||||
|
this->dynamic_section_->set_link_section(dynstr);
|
||||||
|
|
||||||
odyn->add_section_address(elfcpp::DT_STRTAB, dynstr);
|
if (odyn != NULL)
|
||||||
odyn->add_section_size(elfcpp::DT_STRSZ, dynstr);
|
{
|
||||||
|
odyn->add_section_address(elfcpp::DT_STRTAB, dynstr);
|
||||||
|
odyn->add_section_size(elfcpp::DT_STRSZ, dynstr);
|
||||||
|
}
|
||||||
|
|
||||||
*pdynstr = dynstr;
|
*pdynstr = dynstr;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the hash tables.
|
// Create the hash tables.
|
||||||
|
|
||||||
@ -3793,12 +3816,18 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||||||
hashlen,
|
hashlen,
|
||||||
align,
|
align,
|
||||||
"** hash");
|
"** hash");
|
||||||
hashsec->add_output_section_data(hashdata);
|
if (hashsec != NULL && hashdata != NULL)
|
||||||
|
hashsec->add_output_section_data(hashdata);
|
||||||
|
|
||||||
hashsec->set_link_section(dynsym);
|
if (hashsec != NULL)
|
||||||
hashsec->set_entsize(4);
|
{
|
||||||
|
if (dynsym != NULL)
|
||||||
|
hashsec->set_link_section(dynsym);
|
||||||
|
hashsec->set_entsize(4);
|
||||||
|
}
|
||||||
|
|
||||||
odyn->add_section_address(elfcpp::DT_HASH, hashsec);
|
if (odyn != NULL)
|
||||||
|
odyn->add_section_address(elfcpp::DT_HASH, hashsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(parameters->options().hash_style(), "gnu") == 0
|
if (strcmp(parameters->options().hash_style(), "gnu") == 0
|
||||||
@ -3818,17 +3847,23 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||||||
hashlen,
|
hashlen,
|
||||||
align,
|
align,
|
||||||
"** hash");
|
"** hash");
|
||||||
hashsec->add_output_section_data(hashdata);
|
if (hashsec != NULL && hashdata != NULL)
|
||||||
|
hashsec->add_output_section_data(hashdata);
|
||||||
|
|
||||||
hashsec->set_link_section(dynsym);
|
if (hashsec != NULL)
|
||||||
|
{
|
||||||
|
if (dynsym != NULL)
|
||||||
|
hashsec->set_link_section(dynsym);
|
||||||
|
|
||||||
// For a 64-bit target, the entries in .gnu.hash do not have a
|
// For a 64-bit target, the entries in .gnu.hash do not have
|
||||||
// uniform size, so we only set the entry size for a 32-bit
|
// a uniform size, so we only set the entry size for a
|
||||||
// target.
|
// 32-bit target.
|
||||||
if (parameters->target().get_size() == 32)
|
if (parameters->target().get_size() == 32)
|
||||||
hashsec->set_entsize(4);
|
hashsec->set_entsize(4);
|
||||||
|
|
||||||
odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
|
if (odyn != NULL)
|
||||||
|
odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3838,7 +3873,8 @@ void
|
|||||||
Layout::assign_local_dynsym_offsets(const Input_objects* input_objects)
|
Layout::assign_local_dynsym_offsets(const Input_objects* input_objects)
|
||||||
{
|
{
|
||||||
Output_section* dynsym = this->dynsym_section_;
|
Output_section* dynsym = this->dynsym_section_;
|
||||||
gold_assert(dynsym != NULL);
|
if (dynsym == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
off_t off = dynsym->offset();
|
off_t off = dynsym->offset();
|
||||||
|
|
||||||
@ -3919,46 +3955,59 @@ Layout::sized_create_version_sections(
|
|||||||
ORDER_DYNAMIC_LINKER,
|
ORDER_DYNAMIC_LINKER,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
unsigned char* vbuf;
|
// Check for NULL since a linker script may discard this section.
|
||||||
unsigned int vsize;
|
if (vsec != NULL)
|
||||||
versions->symbol_section_contents<size, big_endian>(symtab, &this->dynpool_,
|
{
|
||||||
local_symcount,
|
unsigned char* vbuf;
|
||||||
dynamic_symbols,
|
unsigned int vsize;
|
||||||
&vbuf, &vsize);
|
versions->symbol_section_contents<size, big_endian>(symtab,
|
||||||
|
&this->dynpool_,
|
||||||
|
local_symcount,
|
||||||
|
dynamic_symbols,
|
||||||
|
&vbuf, &vsize);
|
||||||
|
|
||||||
Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2,
|
Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2,
|
||||||
"** versions");
|
"** versions");
|
||||||
|
|
||||||
vsec->add_output_section_data(vdata);
|
vsec->add_output_section_data(vdata);
|
||||||
vsec->set_entsize(2);
|
vsec->set_entsize(2);
|
||||||
vsec->set_link_section(this->dynsym_section_);
|
vsec->set_link_section(this->dynsym_section_);
|
||||||
|
}
|
||||||
|
|
||||||
Output_data_dynamic* const odyn = this->dynamic_data_;
|
Output_data_dynamic* const odyn = this->dynamic_data_;
|
||||||
odyn->add_section_address(elfcpp::DT_VERSYM, vsec);
|
if (odyn != NULL && vsec != NULL)
|
||||||
|
odyn->add_section_address(elfcpp::DT_VERSYM, vsec);
|
||||||
|
|
||||||
if (versions->any_defs())
|
if (versions->any_defs())
|
||||||
{
|
{
|
||||||
Output_section* vdsec;
|
Output_section* vdsec;
|
||||||
vdsec= this->choose_output_section(NULL, ".gnu.version_d",
|
vdsec = this->choose_output_section(NULL, ".gnu.version_d",
|
||||||
elfcpp::SHT_GNU_verdef,
|
elfcpp::SHT_GNU_verdef,
|
||||||
elfcpp::SHF_ALLOC,
|
elfcpp::SHF_ALLOC,
|
||||||
false, ORDER_DYNAMIC_LINKER, false);
|
false, ORDER_DYNAMIC_LINKER, false);
|
||||||
|
|
||||||
unsigned char* vdbuf;
|
if (vdsec != NULL)
|
||||||
unsigned int vdsize;
|
{
|
||||||
unsigned int vdentries;
|
unsigned char* vdbuf;
|
||||||
versions->def_section_contents<size, big_endian>(&this->dynpool_, &vdbuf,
|
unsigned int vdsize;
|
||||||
&vdsize, &vdentries);
|
unsigned int vdentries;
|
||||||
|
versions->def_section_contents<size, big_endian>(&this->dynpool_,
|
||||||
|
&vdbuf, &vdsize,
|
||||||
|
&vdentries);
|
||||||
|
|
||||||
Output_section_data* vddata =
|
Output_section_data* vddata =
|
||||||
new Output_data_const_buffer(vdbuf, vdsize, 4, "** version defs");
|
new Output_data_const_buffer(vdbuf, vdsize, 4, "** version defs");
|
||||||
|
|
||||||
vdsec->add_output_section_data(vddata);
|
vdsec->add_output_section_data(vddata);
|
||||||
vdsec->set_link_section(dynstr);
|
vdsec->set_link_section(dynstr);
|
||||||
vdsec->set_info(vdentries);
|
vdsec->set_info(vdentries);
|
||||||
|
|
||||||
odyn->add_section_address(elfcpp::DT_VERDEF, vdsec);
|
if (odyn != NULL)
|
||||||
odyn->add_constant(elfcpp::DT_VERDEFNUM, vdentries);
|
{
|
||||||
|
odyn->add_section_address(elfcpp::DT_VERDEF, vdsec);
|
||||||
|
odyn->add_constant(elfcpp::DT_VERDEFNUM, vdentries);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (versions->any_needs())
|
if (versions->any_needs())
|
||||||
@ -3969,22 +4018,28 @@ Layout::sized_create_version_sections(
|
|||||||
elfcpp::SHF_ALLOC,
|
elfcpp::SHF_ALLOC,
|
||||||
false, ORDER_DYNAMIC_LINKER, false);
|
false, ORDER_DYNAMIC_LINKER, false);
|
||||||
|
|
||||||
unsigned char* vnbuf;
|
if (vnsec != NULL)
|
||||||
unsigned int vnsize;
|
{
|
||||||
unsigned int vnentries;
|
unsigned char* vnbuf;
|
||||||
versions->need_section_contents<size, big_endian>(&this->dynpool_,
|
unsigned int vnsize;
|
||||||
&vnbuf, &vnsize,
|
unsigned int vnentries;
|
||||||
&vnentries);
|
versions->need_section_contents<size, big_endian>(&this->dynpool_,
|
||||||
|
&vnbuf, &vnsize,
|
||||||
|
&vnentries);
|
||||||
|
|
||||||
Output_section_data* vndata =
|
Output_section_data* vndata =
|
||||||
new Output_data_const_buffer(vnbuf, vnsize, 4, "** version refs");
|
new Output_data_const_buffer(vnbuf, vnsize, 4, "** version refs");
|
||||||
|
|
||||||
vnsec->add_output_section_data(vndata);
|
vnsec->add_output_section_data(vndata);
|
||||||
vnsec->set_link_section(dynstr);
|
vnsec->set_link_section(dynstr);
|
||||||
vnsec->set_info(vnentries);
|
vnsec->set_info(vnentries);
|
||||||
|
|
||||||
odyn->add_section_address(elfcpp::DT_VERNEED, vnsec);
|
if (odyn != NULL)
|
||||||
odyn->add_constant(elfcpp::DT_VERNEEDNUM, vnentries);
|
{
|
||||||
|
odyn->add_section_address(elfcpp::DT_VERNEED, vnsec);
|
||||||
|
odyn->add_constant(elfcpp::DT_VERNEEDNUM, vnentries);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4011,7 +4066,8 @@ Layout::create_interp(const Target* target)
|
|||||||
elfcpp::SHF_ALLOC,
|
elfcpp::SHF_ALLOC,
|
||||||
false, ORDER_INTERP,
|
false, ORDER_INTERP,
|
||||||
false);
|
false);
|
||||||
osec->add_output_section_data(odata);
|
if (osec != NULL)
|
||||||
|
osec->add_output_section_data(odata);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dynamic tags for the PLT and the dynamic relocs. This is
|
// Add dynamic tags for the PLT and the dynamic relocs. This is
|
||||||
@ -4117,7 +4173,8 @@ void
|
|||||||
Layout::finish_dynamic_section(const Input_objects* input_objects,
|
Layout::finish_dynamic_section(const Input_objects* input_objects,
|
||||||
const Symbol_table* symtab)
|
const Symbol_table* symtab)
|
||||||
{
|
{
|
||||||
if (!this->script_options_->saw_phdrs_clause())
|
if (!this->script_options_->saw_phdrs_clause()
|
||||||
|
&& this->dynamic_section_ != NULL)
|
||||||
{
|
{
|
||||||
Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC,
|
Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC,
|
||||||
(elfcpp::PF_R
|
(elfcpp::PF_R
|
||||||
@ -4127,6 +4184,8 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Output_data_dynamic* const odyn = this->dynamic_data_;
|
Output_data_dynamic* const odyn = this->dynamic_data_;
|
||||||
|
if (odyn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
|
for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
|
||||||
p != input_objects->dynobj_end();
|
p != input_objects->dynobj_end();
|
||||||
@ -4322,7 +4381,11 @@ void
|
|||||||
Layout::set_dynamic_symbol_size(const Symbol_table* symtab)
|
Layout::set_dynamic_symbol_size(const Symbol_table* symtab)
|
||||||
{
|
{
|
||||||
Output_data_dynamic* const odyn = this->dynamic_data_;
|
Output_data_dynamic* const odyn = this->dynamic_data_;
|
||||||
|
if (odyn == NULL)
|
||||||
|
return;
|
||||||
odyn->finalize_data_size();
|
odyn->finalize_data_size();
|
||||||
|
if (this->dynamic_symbol_ == NULL)
|
||||||
|
return;
|
||||||
off_t data_size = odyn->data_size();
|
off_t data_size = odyn->data_size();
|
||||||
const int size = parameters->target().get_size();
|
const int size = parameters->target().get_size();
|
||||||
if (size == 32)
|
if (size == 32)
|
||||||
|
Loading…
Reference in New Issue
Block a user