Add an option for Stringpools to not copy strings.
authorIan Lance Taylor <iant@google.com>
Fri, 12 Oct 2007 06:06:34 +0000 (06:06 +0000)
committerIan Lance Taylor <iant@google.com>
Fri, 12 Oct 2007 06:06:34 +0000 (06:06 +0000)
gold/dynobj.cc
gold/layout.cc
gold/merge.cc
gold/object.cc
gold/output.h
gold/stringpool.cc
gold/stringpool.h
gold/symtab.cc
gold/symtab.h

index 805d869f2e9f3b2840430807848b58d9a02ce975..f2cf8e156ea6cc04d8541c22a06edd13429cf62a 100644 (file)
@@ -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;
index 5bcdbe1a81c5ed14a58c0c1c078340d0d4e46410..e5c6492b8d743dc740a34ebe3832f0117ec4bbeb 100644 (file)
@@ -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);
index 75cbc18666bccd54b7487d451965da3bc80a2475..dc293abebdfc8ef06083ba04b737f376d708f4cf 100644 (file)
@@ -276,7 +276,7 @@ Output_merge_string<Char_type>::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));
 
index b8843e9c61597b8b9ffc11f73e55a751715d2aa5..bbd754b94ca505783764d2083cdd394bb24fa351 100644 (file)
@@ -652,7 +652,7 @@ Sized_relobj<size, big_endian>::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;
index 997a821bc0cefc030bb828547623eb4a42a9ac49..c525a329c038c78633c10b58c6f2f3ad6954be77 100644 (file)
@@ -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)
index d8b52119aaa085229a13be1d4a4a32fe4f6d29d4..bb571f0fba2e90d80dd5b1ae76333d8018ab282b 100644 (file)
@@ -36,7 +36,7 @@ namespace gold
 template<typename Stringpool_char>
 Stringpool_template<Stringpool_char>::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<Stringpool_char>::add_string(const Stringpool_char* s,
 
 template<typename Stringpool_char>
 const Stringpool_char*
-Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, Key* pkey)
+Stringpool_template<Stringpool_char>::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<Stringpool_char>::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<const Stringpool_char*, Val> element(ret,
@@ -241,13 +250,14 @@ Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, Key* pkey)
 
 template<typename Stringpool_char>
 const Stringpool_char*
-Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, size_t len,
-                                Key* pkey)
+Stringpool_template<Stringpool_char>::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<Stringpool_char> st(s, len);
-  return this->add(st, pkey);
+  return this->add(st.c_str(), true, pkey);
 }
 
 template<typename Stringpool_char>
index 85532758b6d03bc3550e24c386637e4f3e91e994..80e53bef52bf0623cb9bba9a908d71896fc1ade1 100644 (file)
@@ -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<Stringpool_char>& 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_;
 };
index 5237b8cb916d107596c301fd4f2b47cebb35fc70..00caed7224a2c3e050fa7a3b891ed15cdbf1ed6d 100644 (file)
@@ -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<unsigned int>(elfcpp::VER_NDX_LOCAL)
           || v == static_cast<unsigned int>(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<typename Symbol_table_type::iterator, bool> 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;
        }
index 258c99f9a722f0a20de29a07c053c8a60e87c2ec..0dabd517d1b74de518432b14ff907c7d7f91ce33 100644 (file)
@@ -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.