From a93d6d0708cec0f69b8aaa28c847dd43195fe106 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 20 Sep 2007 05:56:14 +0000 Subject: [PATCH] Rework patch to check by both armap entry and archive offset. Also, preserve information for --group. --- gold/archive.cc | 45 ++++++++++++++++++++++++--------------------- gold/archive.h | 13 +++++++++++++ 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/gold/archive.cc b/gold/archive.cc index 64523d2..8603dc6 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -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(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 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; } } diff --git a/gold/archive.h b/gold/archive.h index 33a7233..4f4c7f3 100644 --- a/gold/archive.h +++ b/gold/archive.h @@ -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(val); } + }; + // Name of object as printed to user. std::string name_; // For reading the file. @@ -123,6 +131,11 @@ class Archive std::vector 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 armap_checked_; + // Track which elements have been included by offset. + Unordered_set seen_offsets_; }; // This class is used to read an archive and pick out the desired -- 2.7.4