diff options
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/layout.cc | 42 |
2 files changed, 28 insertions, 20 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 884feb8..20f84af 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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. diff --git a/gold/layout.cc b/gold/layout.cc index ef0a879..7cbbe39 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -4308,18 +4308,20 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, } } - // Create the hash tables. + // 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(), "sysv") == 0 + if (strcmp(parameters->options().hash_style(), "gnu") == 0 || strcmp(parameters->options().hash_style(), "both") == 0) { unsigned char* phash; unsigned int hashlen; - Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount, + Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount, &phash, &hashlen); Output_section* hashsec = - this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH, + this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, false); @@ -4334,23 +4336,28 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, { if (dynsym != NULL) hashsec->set_link_section(dynsym); - hashsec->set_entsize(4); - } - if (odyn != NULL) - odyn->add_section_address(elfcpp::DT_HASH, hashsec); + // For a 64-bit target, the entries in .gnu.hash do not have + // a uniform size, so we only set the entry size for a + // 32-bit target. + if (parameters->target().get_size() == 32) + hashsec->set_entsize(4); + + if (odyn != NULL) + odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec); + } } - if (strcmp(parameters->options().hash_style(), "gnu") == 0 + if (strcmp(parameters->options().hash_style(), "sysv") == 0 || strcmp(parameters->options().hash_style(), "both") == 0) { unsigned char* phash; unsigned int hashlen; - Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount, + Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount, &phash, &hashlen); Output_section* hashsec = - this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH, + this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, false); @@ -4365,16 +4372,11 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, { if (dynsym != NULL) hashsec->set_link_section(dynsym); - - // For a 64-bit target, the entries in .gnu.hash do not have - // a uniform size, so we only set the entry size for a - // 32-bit target. - if (parameters->target().get_size() == 32) - hashsec->set_entsize(4); - - if (odyn != NULL) - odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec); + hashsec->set_entsize(4); } + + if (odyn != NULL) + odyn->add_section_address(elfcpp::DT_HASH, hashsec); } } |