aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/layout.cc58
-rw-r--r--gold/options.h4
2 files changed, 46 insertions, 16 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index 1591cfb..124d3bc 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1924,27 +1924,53 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
// Create the hash tables.
- // FIXME: We need an option to create a GNU hash table.
+ 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);
+
+ Output_section_data* hashdata = new Output_data_const_buffer(phash,
+ hashlen,
+ align);
+ hashsec->add_output_section_data(hashdata);
+
+ hashsec->set_link_section(dynsym);
+ hashsec->set_entsize(4);
- unsigned char* phash;
- unsigned int hashlen;
- Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
- &phash, &hashlen);
+ odyn->add_section_address(elfcpp::DT_HASH, hashsec);
+ }
+
+ if (strcmp(parameters->options().hash_style(), "gnu") == 0
+ || strcmp(parameters->options().hash_style(), "both") == 0)
+ {
+ unsigned char* phash;
+ unsigned int hashlen;
+ Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
+ &phash, &hashlen);
- Output_section* hashsec = this->choose_output_section(NULL, ".hash",
- elfcpp::SHT_HASH,
- elfcpp::SHF_ALLOC,
- false);
+ Output_section* hashsec = this->choose_output_section(NULL, ".gnu.hash",
+ elfcpp::SHT_GNU_HASH,
+ elfcpp::SHF_ALLOC,
+ false);
- Output_section_data* hashdata = new Output_data_const_buffer(phash,
- hashlen,
- align);
- hashsec->add_output_section_data(hashdata);
+ Output_section_data* hashdata = new Output_data_const_buffer(phash,
+ hashlen,
+ align);
+ hashsec->add_output_section_data(hashdata);
- hashsec->set_link_section(dynsym);
- hashsec->set_entsize(4);
+ hashsec->set_link_section(dynsym);
+ hashsec->set_entsize(4);
- odyn->add_section_address(elfcpp::DT_HASH, hashsec);
+ odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+ }
}
// Assign offsets to each local portion of the dynamic symbol table.
diff --git a/gold/options.h b/gold/options.h
index 30ffb8c..7f5a561 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -465,6 +465,10 @@ class General_options
DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
_("Set shared library name"), _("FILENAME"));
+ DEFINE_enum(hash_style, options::TWO_DASHES, '\0', "sysv",
+ _("Dynamic hash style"), _("[sysv,gnu,both]"),
+ {"sysv", "gnu", "both"});
+
DEFINE_string(dynamic_linker, options::TWO_DASHES, 'I', NULL,
_("Set dynamic linker path"), _("PROGRAM"));