aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKito Cheng <kito@0xlab.org>2014-09-30 14:36:46 -0700
committerCary Coutant <ccoutant@google.com>2014-09-30 14:36:46 -0700
commitcd6da0366dc6684d32f349b729b5558258fc3af4 (patch)
tree46eeee4b1d28fffb526e73cff7b068c737355ac7
parentd83ad864a285fe3127e1a98830197e8461ad2745 (diff)
downloadgdb-cd6da0366dc6684d32f349b729b5558258fc3af4.zip
gdb-cd6da0366dc6684d32f349b729b5558258fc3af4.tar.gz
gdb-cd6da0366dc6684d32f349b729b5558258fc3af4.tar.bz2
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.
-rw-r--r--gold/ChangeLog6
-rw-r--r--gold/layout.cc42
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);
}
}