Fix SysV-style hash table when --hash-style=both.
When --hash-style-both is used, gold currently builds the sysv hash table first, then the gnu hash table. Building the gnu hash table renumbers the dynamic symbol table, invalidating the sysv hash table. This patch reverses the order in which the hash tables are build so that both hash tables are correct. gold/ PR gold/13597 * layout.cc (Layout::create_dynamic_symtab): Build gnu-style hash table before sysv-style hash table.
This commit is contained in:
parent
d83ad864a2
commit
cd6da0366d
2 changed files with 40 additions and 32 deletions
|
@ -1,3 +1,9 @@
|
|||
2014-09-30 Kito Cheng <kito@0xlab.org>
|
||||
|
||||
PR gold/13597
|
||||
* layout.cc (Layout::create_dynamic_symtab): Build gnu-style
|
||||
hash table before sysv-style hash table.
|
||||
|
||||
2014-09-29 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* options.h (--pic-executable): Add negative to alias to -no-pie.
|
||||
|
|
|
@ -4308,38 +4308,9 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||
}
|
||||
}
|
||||
|
||||
// Create the hash tables.
|
||||
|
||||
if (strcmp(parameters->options().hash_style(), "sysv") == 0
|
||||
|| strcmp(parameters->options().hash_style(), "both") == 0)
|
||||
{
|
||||
unsigned char* phash;
|
||||
unsigned int hashlen;
|
||||
Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
|
||||
&phash, &hashlen);
|
||||
|
||||
Output_section* hashsec =
|
||||
this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
|
||||
elfcpp::SHF_ALLOC, false,
|
||||
ORDER_DYNAMIC_LINKER, false);
|
||||
|
||||
Output_section_data* hashdata = new Output_data_const_buffer(phash,
|
||||
hashlen,
|
||||
align,
|
||||
"** hash");
|
||||
if (hashsec != NULL && hashdata != NULL)
|
||||
hashsec->add_output_section_data(hashdata);
|
||||
|
||||
if (hashsec != NULL)
|
||||
{
|
||||
if (dynsym != NULL)
|
||||
hashsec->set_link_section(dynsym);
|
||||
hashsec->set_entsize(4);
|
||||
}
|
||||
|
||||
if (odyn != NULL)
|
||||
odyn->add_section_address(elfcpp::DT_HASH, hashsec);
|
||||
}
|
||||
// Create the hash tables. The Gnu-style hash table must be
|
||||
// built first, because it changes the order of the symbols
|
||||
// in the dynamic symbol table.
|
||||
|
||||
if (strcmp(parameters->options().hash_style(), "gnu") == 0
|
||||
|| strcmp(parameters->options().hash_style(), "both") == 0)
|
||||
|
@ -4376,6 +4347,37 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
|||
odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(parameters->options().hash_style(), "sysv") == 0
|
||||
|| strcmp(parameters->options().hash_style(), "both") == 0)
|
||||
{
|
||||
unsigned char* phash;
|
||||
unsigned int hashlen;
|
||||
Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
|
||||
&phash, &hashlen);
|
||||
|
||||
Output_section* hashsec =
|
||||
this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
|
||||
elfcpp::SHF_ALLOC, false,
|
||||
ORDER_DYNAMIC_LINKER, false);
|
||||
|
||||
Output_section_data* hashdata = new Output_data_const_buffer(phash,
|
||||
hashlen,
|
||||
align,
|
||||
"** hash");
|
||||
if (hashsec != NULL && hashdata != NULL)
|
||||
hashsec->add_output_section_data(hashdata);
|
||||
|
||||
if (hashsec != NULL)
|
||||
{
|
||||
if (dynsym != NULL)
|
||||
hashsec->set_link_section(dynsym);
|
||||
hashsec->set_entsize(4);
|
||||
}
|
||||
|
||||
if (odyn != NULL)
|
||||
odyn->add_section_address(elfcpp::DT_HASH, hashsec);
|
||||
}
|
||||
}
|
||||
|
||||
// Assign offsets to each local portion of the dynamic symbol table.
|
||||
|
|
Loading…
Add table
Reference in a new issue