* merge.h (Output_merge_string::Merged_string): Remove object, shndx,
authorCary Coutant <ccoutant@google.com>
Wed, 21 Jul 2010 21:03:54 +0000 (21:03 +0000)
committerCary Coutant <ccoutant@google.com>
Wed, 21 Jul 2010 21:03:54 +0000 (21:03 +0000)
string, and length fields.
(Output_merge_string::Merged_strings_list): New type.
(Output_merge_string::Merged_strings_lists): New typedef.
(Output_merge_string): Replace merged_strings_ with
merged_strings_lists_.
* merge.cc (Output_merge_string::do_add_input_section): Allocate new
Merged_strings_list per input object and section.  Don't store pointer
to the string.  Don't store length with each merged string entry.
(Output_merge_string::finalize_merged_data): Loop over list of merged
strings lists.  Recompute length of each merged string.

gold/ChangeLog
gold/merge.cc
gold/merge.h

index 17113fb..c6741b6 100644 (file)
@@ -1,3 +1,17 @@
+2010-07-21  Cary Coutant  <ccoutant@google.com>
+
+       * merge.h (Output_merge_string::Merged_string): Remove object, shndx,
+       string, and length fields.
+       (Output_merge_string::Merged_strings_list): New type.
+       (Output_merge_string::Merged_strings_lists): New typedef.
+       (Output_merge_string): Replace merged_strings_ with
+       merged_strings_lists_.
+       * merge.cc (Output_merge_string::do_add_input_section): Allocate new
+       Merged_strings_list per input object and section.  Don't store pointer
+       to the string.  Don't store length with each merged string entry.
+       (Output_merge_string::finalize_merged_data): Loop over list of merged
+       strings lists.  Recompute length of each merged string.
+
 2010-07-15  Cary Coutant  <ccoutant@google.com>
 
        * plugin.cc (Plugin_finish::run): Don't call cleanup handlers from
index ec11c90..6c512a8 100644 (file)
@@ -545,6 +545,11 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
 
   size_t count = 0;
 
+  Merged_strings_list* merged_strings_list =
+      new Merged_strings_list(object, shndx);
+  this->merged_strings_lists_.push_back(merged_strings_list);
+  Merged_strings& merged_strings = merged_strings_list->merged_strings;
+
   // The index I is in bytes, not characters.
   section_size_type i = 0;
   while (i < len)
@@ -563,18 +568,20 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
        }
 
       Stringpool::Key key;
-      const Char_type* str = this->stringpool_.add_with_length(p, pl - p, true,
-                                                              &key);
+      this->stringpool_.add_with_length(p, pl - p, true, &key);
 
       section_size_type bytelen_with_null = ((pl - p) + 1) * sizeof(Char_type);
-      this->merged_strings_.push_back(Merged_string(object, shndx, i, str,
-                                                   bytelen_with_null, key));
+      merged_strings.push_back(Merged_string(i, key));
 
       p = pl + 1;
       i += bytelen_with_null;
       ++count;
     }
 
+  // Record the last offset in the input section so that we can
+  // compute the length of the last string.
+  merged_strings.push_back(Merged_string(i, 0));
+
   this->input_count_ += count;
 
   // For script processing, we keep the input sections.
@@ -596,20 +603,34 @@ Output_merge_string<Char_type>::finalize_merged_data()
 {
   this->stringpool_.set_string_offsets();
 
-  for (typename Merged_strings::const_iterator p =
-        this->merged_strings_.begin();
-       p != this->merged_strings_.end();
-       ++p)
+  for (typename Merged_strings_lists::const_iterator l =
+        this->merged_strings_lists_.begin();
+       l != this->merged_strings_lists_.end();
+       ++l)
     {
-      section_offset_type offset =
-       this->stringpool_.get_offset_from_key(p->stringpool_key);
-      this->add_mapping(p->object, p->shndx, p->offset, p->length, offset);
+      section_offset_type last_input_offset = 0;
+      section_offset_type last_output_offset = 0;
+      for (typename Merged_strings::const_iterator p =
+            (*l)->merged_strings.begin();
+          p != (*l)->merged_strings.end();
+          ++p)
+       {
+         section_size_type length = p->offset - last_input_offset;
+         if (length > 0)
+           this->add_mapping((*l)->object, (*l)->shndx, last_input_offset,
+                             length, last_output_offset);
+         last_input_offset = p->offset;
+         if (p->stringpool_key != 0)
+           last_output_offset =
+               this->stringpool_.get_offset_from_key(p->stringpool_key);
+       }
+      delete *l;
     }
 
   // Save some memory.  This also ensures that this function will work
   // if called twice, as may happen if Layout::set_segment_offsets
   // finds a better alignment.
-  this->merged_strings_.clear();
+  this->merged_strings_lists_.clear();
 
   return this->stringpool_.get_strtab_size();
 }
index c2d305b..b1284ae 100644 (file)
@@ -462,7 +462,7 @@ class Output_merge_string : public Output_merge_base
  public:
   Output_merge_string(uint64_t addralign)
     : Output_merge_base(sizeof(Char_type), addralign), stringpool_(),
-      merged_strings_(), input_count_(0)
+      merged_strings_lists_(), input_count_(0)
   {
     gold_assert(addralign <= sizeof(Char_type));
     this->stringpool_.set_no_zero_null();
@@ -531,34 +531,39 @@ class Output_merge_string : public Output_merge_base
   // index and offset to strings.
   struct Merged_string
   {
-    // The input object where the string was found.
-    Relobj* object;
-    // The input section in the input object.
-    unsigned int shndx;
     // The offset in the input section.
     section_offset_type offset;
-    // The string itself, a pointer into a Stringpool.
-    const Char_type* string;
-    // The length of the string in bytes, including the null terminator.
-    size_t length;
     // The key in the Stringpool.
     Stringpool::Key stringpool_key;
 
-    Merged_string(Relobj *objecta, unsigned int shndxa,
-                 section_offset_type offseta, const Char_type* stringa,
-                 size_t lengtha, Stringpool::Key stringpool_keya)
-      : object(objecta), shndx(shndxa), offset(offseta), string(stringa),
-       length(lengtha), stringpool_key(stringpool_keya)
+    Merged_string(section_offset_type offseta, Stringpool::Key stringpool_keya)
+      : offset(offseta), stringpool_key(stringpool_keya)
     { }
   };
 
   typedef std::vector<Merged_string> Merged_strings;
 
+  struct Merged_strings_list
+  {
+    // The input object where the strings were found.
+    Relobj* object;
+    // The input section in the input object.
+    unsigned int shndx;
+    // The list of merged strings.
+    Merged_strings merged_strings;
+
+    Merged_strings_list(Relobj* objecta, unsigned int shndxa)
+      : object(objecta), shndx(shndxa), merged_strings()
+    { }
+  };
+
+  typedef std::vector<Merged_strings_list*> Merged_strings_lists;
+
   // As we see the strings, we add them to a Stringpool.
   Stringpool_template<Char_type> stringpool_;
   // Map from a location in an input object to an entry in the
   // Stringpool.
-  Merged_strings merged_strings_;
+  Merged_strings_lists merged_strings_lists_;
   // The number of entries seen in input files.
   size_t input_count_;
 };