diff --git a/gold/dynobj.cc b/gold/dynobj.cc index 805d869f2e..f2cf8e156e 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -1250,7 +1250,7 @@ Versions::record_version(const General_options* options, gold_assert(sym->version() != NULL); Stringpool::Key version_key; - const char* version = dynpool->add(sym->version(), &version_key); + const char* version = dynpool->add(sym->version(), false, &version_key); if (!sym->is_from_dynobj()) { @@ -1326,7 +1326,7 @@ Versions::add_need(Stringpool* dynpool, const char* filename, const char* name, Stringpool::Key name_key) { Stringpool::Key filename_key; - filename = dynpool->add(filename, &filename_key); + filename = dynpool->add(filename, true, &filename_key); Key k(name_key, filename_key); Version_base* const vbnull = NULL; diff --git a/gold/layout.cc b/gold/layout.cc index 5bcdbe1a81..e5c6492b8d 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -220,7 +220,7 @@ Layout::layout(Relobj* object, unsigned int shndx, const char* name, // Canonicalize the section name. Stringpool::Key name_key; - name = this->namepool_.add(name, len, &name_key); + name = this->namepool_.add_prefix(name, len, &name_key); // Find the output section. The output section is selected based on // the section name, type, and flags. @@ -265,6 +265,7 @@ Layout::layout_eh_frame(Relobj* object, { Stringpool::Key hdr_name_key; const char* hdr_name = this->namepool_.add(".eh_frame_hdr", + false, &hdr_name_key); Output_section* hdr_os = this->get_output_section(hdr_name, hdr_name_key, @@ -295,7 +296,7 @@ Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type, { // Canonicalize the name. Stringpool::Key name_key; - name = this->namepool_.add(name, &name_key); + name = this->namepool_.add(name, true, &name_key); Output_section* os = this->get_output_section(name, name_key, type, flags); os->add_output_section_data(posd); @@ -413,7 +414,7 @@ Layout::create_initial_dynamic_sections(const Input_objects* input_objects, if (!input_objects->any_dynamic()) return; - const char* dynamic_name = this->namepool_.add(".dynamic", NULL); + const char* dynamic_name = this->namepool_.add(".dynamic", false, NULL); this->dynamic_section_ = this->make_output_section(dynamic_name, elfcpp::SHT_DYNAMIC, (elfcpp::SHF_ALLOC @@ -694,7 +695,7 @@ Layout::create_note_section() memcpy(buffer + 3 * (size / 8), name, namesz); memcpy(buffer + 3 * (size / 8) + aligned_namesz, desc.data(), descsz); - const char* note_name = this->namepool_.add(".note", NULL); + const char* note_name = this->namepool_.add(".note", false, NULL); Output_section* os = this->make_output_section(note_name, elfcpp::SHT_NOTE, 0); @@ -999,7 +1000,7 @@ Layout::create_symtab_sections(const Input_objects* input_objects, { this->sympool_.set_string_offsets(); - const char* symtab_name = this->namepool_.add(".symtab", NULL); + const char* symtab_name = this->namepool_.add(".symtab", false, NULL); Output_section* osymtab = this->make_output_section(symtab_name, elfcpp::SHT_SYMTAB, 0); @@ -1009,7 +1010,7 @@ Layout::create_symtab_sections(const Input_objects* input_objects, align); osymtab->add_output_section_data(pos); - const char* strtab_name = this->namepool_.add(".strtab", NULL); + const char* strtab_name = this->namepool_.add(".strtab", false, NULL); Output_section* ostrtab = this->make_output_section(strtab_name, elfcpp::SHT_STRTAB, 0); @@ -1036,7 +1037,7 @@ Layout::create_shstrtab() // FIXME: We don't need to create a .shstrtab section if we are // stripping everything. - const char* name = this->namepool_.add(".shstrtab", NULL); + const char* name = this->namepool_.add(".shstrtab", false, NULL); this->namepool_.set_string_offsets(); @@ -1128,7 +1129,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, // Create the dynamic symbol table section. - const char* dynsym_name = this->namepool_.add(".dynsym", NULL); + const char* dynsym_name = this->namepool_.add(".dynsym", false, NULL); Output_section* dynsym = this->make_output_section(dynsym_name, elfcpp::SHT_DYNSYM, elfcpp::SHF_ALLOC); @@ -1149,7 +1150,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, // Create the dynamic string table section. - const char* dynstr_name = this->namepool_.add(".dynstr", NULL); + const char* dynstr_name = this->namepool_.add(".dynstr", false, NULL); Output_section* dynstr = this->make_output_section(dynstr_name, elfcpp::SHT_STRTAB, elfcpp::SHF_ALLOC); @@ -1174,7 +1175,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount, &phash, &hashlen); - const char* hash_name = this->namepool_.add(".hash", NULL); + const char* hash_name = this->namepool_.add(".hash", false, NULL); Output_section* hashsec = this->make_output_section(hash_name, elfcpp::SHT_HASH, elfcpp::SHF_ALLOC); @@ -1266,7 +1267,7 @@ Layout::sized_create_version_sections( const Output_section* dynstr ACCEPT_SIZE_ENDIAN) { - const char* vname = this->namepool_.add(".gnu.version", NULL); + const char* vname = this->namepool_.add(".gnu.version", false, NULL); Output_section* vsec = this->make_output_section(vname, elfcpp::SHT_GNU_versym, elfcpp::SHF_ALLOC); @@ -1288,7 +1289,7 @@ Layout::sized_create_version_sections( if (versions->any_defs()) { - const char* vdname = this->namepool_.add(".gnu.version_d", NULL); + const char* vdname = this->namepool_.add(".gnu.version_d", false, NULL); Output_section *vdsec; vdsec = this->make_output_section(vdname, elfcpp::SHT_GNU_verdef, elfcpp::SHF_ALLOC); @@ -1314,7 +1315,7 @@ Layout::sized_create_version_sections( if (versions->any_needs()) { - const char* vnname = this->namepool_.add(".gnu.version_r", NULL); + const char* vnname = this->namepool_.add(".gnu.version_r", false, NULL); Output_section* vnsec; vnsec = this->make_output_section(vnname, elfcpp::SHT_GNU_verneed, elfcpp::SHF_ALLOC); @@ -1355,7 +1356,7 @@ Layout::create_interp(const Target* target) Output_section_data* odata = new Output_data_const(interp, len, 1); - const char* interp_name = this->namepool_.add(".interp", NULL); + const char* interp_name = this->namepool_.add(".interp", false, NULL); Output_section* osec = this->make_output_section(interp_name, elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC); diff --git a/gold/merge.cc b/gold/merge.cc index 75cbc18666..dc293abebd 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -276,7 +276,7 @@ Output_merge_string::do_add_input_section(Relobj* object, } } - const Char_type* str = this->stringpool_.add(p, NULL); + const Char_type* str = this->stringpool_.add(p, true, NULL); this->merged_strings_.push_back(Merged_string(object, shndx, i, str)); diff --git a/gold/object.cc b/gold/object.cc index b8843e9c61..bbd754b94c 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -652,7 +652,7 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, } const char* name = pnames + sym.get_st_name(); - pool->add(name, NULL); + pool->add(name, true, NULL); lv.set_output_symtab_index(index); ++index; ++count; diff --git a/gold/output.h b/gold/output.h index 997a821bc0..c525a329c0 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1041,7 +1041,7 @@ class Output_data_dynamic : public Output_section_data // Add a new dynamic entry with a string. void add_string(elfcpp::DT tag, const char* str) - { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, NULL))); } + { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, true, NULL))); } void add_string(elfcpp::DT tag, const std::string& str) diff --git a/gold/stringpool.cc b/gold/stringpool.cc index d8b52119aa..bb571f0fba 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -36,7 +36,7 @@ namespace gold template Stringpool_template::Stringpool_template() : string_set_(), strings_(), strtab_size_(0), next_index_(1), - zero_null_(true) + next_uncopied_key_(-1), zero_null_(true) { } @@ -205,7 +205,8 @@ Stringpool_template::add_string(const Stringpool_char* s, template const Stringpool_char* -Stringpool_template::add(const Stringpool_char* s, Key* pkey) +Stringpool_template::add(const Stringpool_char* s, bool copy, + Key* pkey) { // FIXME: This will look up the entry twice in the hash table. The // problem is that we can't insert S before we canonicalize it. I @@ -222,7 +223,15 @@ Stringpool_template::add(const Stringpool_char* s, Key* pkey) } Key k; - const Stringpool_char* ret = this->add_string(s, &k); + const Stringpool_char* ret; + if (copy) + ret = this->add_string(s, &k); + else + { + ret = s; + k = this->next_uncopied_key_; + --this->next_uncopied_key_; + } const off_t ozero = 0; std::pair element(ret, @@ -241,13 +250,14 @@ Stringpool_template::add(const Stringpool_char* s, Key* pkey) template const Stringpool_char* -Stringpool_template::add(const Stringpool_char* s, size_t len, - Key* pkey) +Stringpool_template::add_prefix(const Stringpool_char* s, + size_t len, + Key* pkey) { // FIXME: This implementation should be rewritten when we rewrite // the hash table to avoid copying. std::basic_string st(s, len); - return this->add(st, pkey); + return this->add(st.c_str(), true, pkey); } template diff --git a/gold/stringpool.h b/gold/stringpool.h index 85532758b6..80e53bef52 100644 --- a/gold/stringpool.h +++ b/gold/stringpool.h @@ -47,8 +47,9 @@ class Output_file; // string pointer so that repeated runs of the linker will generate // precisely the same output. -// When you add a string to a Stringpool, Stringpool will make a copy -// of it. Thus there is no need to keep a copy elsewhere. +// When you add a string to a Stringpool, Stringpool will optionally +// make a copy of it. Thus there is no requirement to keep a copy +// elsewhere. // A Stringpool can be turned into a string table, a sequential series // of null terminated strings. The first string may optionally be a @@ -91,19 +92,15 @@ class Stringpool_template { this->zero_null_ = false; } // Add the string S to the pool. This returns a canonical permanent - // pointer to the string in the pool. If PKEY is not NULL, this - // sets *PKEY to the key for the string. + // pointer to the string in the pool. If COPY is true, the string + // is copied into permanent storage. If PKEY is not NULL, this sets + // *PKEY to the key for the string. const Stringpool_char* - add(const Stringpool_char* s, Key* pkey); - - // Add the string S to the pool. - const Stringpool_char* - add(const std::basic_string& s, Key* pkey) - { return this->add(s.c_str(), pkey); } + add(const Stringpool_char* s, bool copy, Key* pkey); // Add the prefix of length LEN of string S to the pool. const Stringpool_char* - add(const Stringpool_char* s, size_t len, Key* pkey); + add_prefix(const Stringpool_char* s, size_t len, Key* pkey); // If the string S is present in the pool, return the canonical // string pointer. Otherwise, return NULL. If PKEY is not NULL, @@ -232,6 +229,8 @@ class Stringpool_template off_t strtab_size_; // Next Stringdata index. unsigned int next_index_; + // Next key value for a string we don't copy. + int next_uncopied_key_; // Whether to reserve offset 0 to hold the null string. bool zero_null_; }; diff --git a/gold/symtab.cc b/gold/symtab.cc index 5237b8cb91..00caed7224 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -547,14 +547,14 @@ Symbol_table::add_from_relobj( if (ver == NULL) { Stringpool::Key name_key; - name = this->namepool_.add(name, &name_key); + name = this->namepool_.add(name, true, &name_key); res = this->add_from_object(relobj, name, name_key, NULL, 0, false, *psym); } else { Stringpool::Key name_key; - name = this->namepool_.add(name, ver - name, &name_key); + name = this->namepool_.add_prefix(name, ver - name, &name_key); bool def = false; ++ver; @@ -565,7 +565,7 @@ Symbol_table::add_from_relobj( } Stringpool::Key ver_key; - ver = this->namepool_.add(ver, &ver_key); + ver = this->namepool_.add(ver, true, &ver_key); res = this->add_from_object(relobj, name, name_key, ver, ver_key, def, *psym); @@ -625,7 +625,7 @@ Symbol_table::add_from_dynobj( if (versym == NULL) { Stringpool::Key name_key; - name = this->namepool_.add(name, &name_key); + name = this->namepool_.add(name, true, &name_key); this->add_from_object(dynobj, name, name_key, NULL, 0, false, sym); continue; @@ -654,7 +654,7 @@ Symbol_table::add_from_dynobj( // At this point we are definitely going to add this symbol. Stringpool::Key name_key; - name = this->namepool_.add(name, &name_key); + name = this->namepool_.add(name, true, &name_key); if (v == static_cast(elfcpp::VER_NDX_LOCAL) || v == static_cast(elfcpp::VER_NDX_GLOBAL)) @@ -681,7 +681,7 @@ Symbol_table::add_from_dynobj( } Stringpool::Key version_key; - version = this->namepool_.add(version, &version_key); + version = this->namepool_.add(version, true, &version_key); // If this is an absolute symbol, and the version name and // symbol name are the same, then this is the version definition @@ -731,11 +731,11 @@ Symbol_table::define_special_symbol(const Target* target, const char** pname, { // Canonicalize NAME and VERSION. Stringpool::Key name_key; - *pname = this->namepool_.add(*pname, &name_key); + *pname = this->namepool_.add(*pname, true, &name_key); Stringpool::Key version_key = 0; if (*pversion != NULL) - *pversion = this->namepool_.add(*pversion, &version_key); + *pversion = this->namepool_.add(*pversion, true, &version_key); Symbol* const snull = NULL; std::pair ins = @@ -1138,7 +1138,7 @@ Symbol_table::set_dynsym_indexes(const General_options* options, sym->set_dynsym_index(index); ++index; syms->push_back(sym); - dynpool->add(sym->name(), NULL); + dynpool->add(sym->name(), false, NULL); // Record any version information. if (sym->version() != NULL) @@ -1322,7 +1322,7 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool) else { sym->set_symtab_index(index); - pool->add(sym->name(), NULL); + pool->add(sym->name(), false, NULL); ++index; off += sym_size; } diff --git a/gold/symtab.h b/gold/symtab.h index 258c99f9a7..0dabd517d1 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -872,7 +872,7 @@ class Symbol_table // Canonicalize a symbol name for use in the hash table. const char* canonicalize_name(const char* name) - { return this->namepool_.add(name, NULL); } + { return this->namepool_.add(name, true, NULL); } // Possibly issue a warning for a reference to SYM at LOCATION which // is in OBJ.