SHT_LOUSER = 0x80000000,
SHT_HIUSER = 0xffffffff,
// The remaining values are not in the standard.
+ // Object attributes.
+ SHT_GNU_ATTRIBUTES = 0x6ffffff5,
+ // GNU style dynamic hash table.
+ SHT_GNU_HASH = 0x6ffffff6,
// List of prelink dependencies.
SHT_GNU_LIBLIST = 0x6ffffff7,
// Versions defined by file.
// 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.
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"));