diff --git a/gold/ChangeLog b/gold/ChangeLog index 884feb8a13..20f84af51a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,9 @@ +2014-09-30 Kito Cheng + + PR gold/13597 + * layout.cc (Layout::create_dynamic_symtab): Build gnu-style + hash table before sysv-style hash table. + 2014-09-29 Sriraman Tallam * options.h (--pic-executable): Add negative to alias to -no-pie. diff --git a/gold/layout.cc b/gold/layout.cc index ef0a879b41..7cbbe39b87 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -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.