Rework patch to check by both armap entry and archive offset. Also,
authorIan Lance Taylor <iant@google.com>
Thu, 20 Sep 2007 05:56:14 +0000 (05:56 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 20 Sep 2007 05:56:14 +0000 (05:56 +0000)
preserve information for --group.

gold/archive.cc
gold/archive.h

index 64523d2712d147a63eed8102ca9fe5f6b69901f9..8603dc693eaa00eac541f892782f4b17d69255ec 100644 (file)
@@ -121,6 +121,10 @@ Archive::read_armap(off_t start, off_t size)
              program_name, this->name().c_str());
       gold_exit(false);
     }
+
+  // This array keeps track of which symbols are for archive elements
+  // which we have already included in the link.
+  this->armap_checked_.resize(nsyms);
 }
 
 // Read the header of an archive member at OFF.  Fail if something
@@ -226,14 +230,6 @@ Archive::interpret_header(const Archive_header* hdr, off_t off,
   return member_size;
 }
 
-// A simple hash code for off_t values.
-class Seen_hash
-{
- public:
-  size_t operator()(off_t val) const
-  { return static_cast<size_t>(val); }
-};
-
 // Select members from the archive and add them to the link.  We walk
 // through the elements in the archive map, and look each one up in
 // the symbol table.  If it exists as a strong undefined symbol, we
@@ -250,13 +246,13 @@ Archive::add_symbols(const General_options& options, Symbol_table* symtab,
 
   const size_t armap_size = this->armap_.size();
 
-  // Track which elements in the archive map have already been included
-  // in the link.  Elements are identified by their offset.
-  Unordered_set<off_t, Seen_hash> seen;
   // This is a quick optimization, since we usually see many symbols
   // in a row with the same offset.  last_seen holds the last offset
   // we saw that was present in the seen_ set.
-  off_t last_seen = -1;
+  off_t last_seen_offset = -1;
+
+  // Track which symbols in the symbol table we've already found to be
+  // defined.
 
   bool added_new_object;
   do
@@ -264,11 +260,18 @@ Archive::add_symbols(const General_options& options, Symbol_table* symtab,
       added_new_object = false;
       for (size_t i = 0; i < armap_size; ++i)
        {
-         if (this->armap_[i].offset == last_seen)
-           continue;
-         if (seen.find(this->armap_[i].offset) != seen.end())
+          if (this->armap_checked_[i])
+            continue;
+         if (this->armap_[i].offset == last_seen_offset)
+            {
+              this->armap_checked_[i] = true;
+              continue;
+            }
+         if (this->seen_offsets_.find(this->armap_[i].offset)
+              != this->seen_offsets_.end())
            {
-             last_seen = this->armap_[i].offset;
+              this->armap_checked_[i] = true;
+             last_seen_offset = this->armap_[i].offset;
              continue;
            }
 
@@ -277,18 +280,18 @@ Archive::add_symbols(const General_options& options, Symbol_table* symtab,
            continue;
          else if (!sym->is_undefined())
            {
-             seen.insert(this->armap_[i].offset);
-             last_seen = this->armap_[i].offset;
+              this->armap_checked_[i] = true;
              continue;
            }
          else if (sym->binding() == elfcpp::STB_WEAK)
            continue;
 
          // We want to include this object in the link.
-         last_seen = this->armap_[i].offset;
-         seen.insert(last_seen);
+         last_seen_offset = this->armap_[i].offset;
+         this->seen_offsets_.insert(last_seen_offset);
+          this->armap_checked_[i] = true;
          this->include_member(options, symtab, layout, input_objects,
-                              last_seen);
+                              last_seen_offset);
          added_new_object = true;
        }
     }
index 33a7233a9a60595841ef89d42b74df202e95d008..4f4c7f33061d4f416031731b37bae00af120f52f 100644 (file)
@@ -115,6 +115,14 @@ class Archive
     off_t offset;
   };
 
+  // A simple hash code for off_t values.
+  class Seen_hash
+  {
+   public:
+    size_t operator()(off_t val) const
+    { return static_cast<size_t>(val); }
+  };
+
   // Name of object as printed to user.
   std::string name_;
   // For reading the file.
@@ -123,6 +131,11 @@ class Archive
   std::vector<Armap_entry> armap_;
   // The extended name table.
   std::string extended_names_;
+  // Track which symbols in the archive map are for elements which are
+  // defined or which have already been included in the link.
+  std::vector<bool> armap_checked_;
+  // Track which elements have been included by offset.
+  Unordered_set<off_t, Seen_hash> seen_offsets_;
 };
 
 // This class is used to read an archive and pick out the desired