aboutsummaryrefslogtreecommitdiff
path: root/gold/archive.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-09-20 05:56:14 +0000
committerIan Lance Taylor <iant@google.com>2007-09-20 05:56:14 +0000
commita93d6d0708cec0f69b8aaa28c847dd43195fe106 (patch)
treebd5fdc9f5a4c2a07a201dd58b359b1a3c764acc7 /gold/archive.cc
parente243ffc6679a8e119e2e6041e507c234e90bc796 (diff)
downloadgdb-a93d6d0708cec0f69b8aaa28c847dd43195fe106.zip
gdb-a93d6d0708cec0f69b8aaa28c847dd43195fe106.tar.gz
gdb-a93d6d0708cec0f69b8aaa28c847dd43195fe106.tar.bz2
Rework patch to check by both armap entry and archive offset. Also,
preserve information for --group.
Diffstat (limited to 'gold/archive.cc')
-rw-r--r--gold/archive.cc45
1 files changed, 24 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<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;
}
}