summaryrefslogtreecommitdiff
path: root/gold/common.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-12-31 05:07:22 +0000
committerIan Lance Taylor <ian@airs.com>2009-12-31 05:07:22 +0000
commiteda294df6d71e405810e6b56e2bab2bff91a1799 (patch)
treecae358d1e57adf539483db13d65defa840bf0397 /gold/common.cc
parentd7bb5745008bb111becc3dc87e7ce243f59b7170 (diff)
downloadbinutils-gdb-eda294df6d71e405810e6b56e2bab2bff91a1799.tar.gz
PR 10979
* common.cc (Sort_commons::operator()): Stabilize sort when both entries are NULL. (Symbol_table::do_allocate_commons_list): When allocating common symbols, skip a symbol which is no longer common. * symtab.h (Symbol::is_common): Test whether the symbol comes from an object before checking its type. * testsuite/common_test_2.c: New file. * testsuite/common_test_3.c: New file. * testsuite/Makefile.am (check_PROGRAMS): Add common_test_2. (common_test_2_SOURCES, common_test_2_DEPENDENCIES): Define. (common_test_2_LDFLAGS, common_test_2_LDADD): Define. (common_test_2_pic.o, common_test_2.so): New targets. (common_test_3_pic.o, common_test_3.so): New targets. * testsuite/Makefile.in: Rebuild.
Diffstat (limited to 'gold/common.cc')
-rw-r--r--gold/common.cc22
1 files changed, 21 insertions, 1 deletions
diff --git a/gold/common.cc b/gold/common.cc
index c4ff047d47a..885933807c6 100644
--- a/gold/common.cc
+++ b/gold/common.cc
@@ -91,7 +91,16 @@ bool
Sort_commons<size>::operator()(const Symbol* pa, const Symbol* pb) const
{
if (pa == NULL)
- return false;
+ {
+ if (pb == NULL)
+ {
+ // Stabilize sort. The order really doesn't matter, because
+ // these entries will be discarded, but we want to return
+ // the same result every time we compare pa and pb.
+ return pa < pb;
+ }
+ return false;
+ }
if (pb == NULL)
return true;
@@ -312,6 +321,17 @@ Symbol_table::do_allocate_commons_list(
Symbol* sym = *p;
if (sym == NULL)
break;
+
+ // Because we followed forwarding symbols above, but we didn't
+ // do it reliably before adding symbols to the list, it is
+ // possible for us to have the same symbol on the list twice.
+ // This can happen in the horrible case where a program defines
+ // a common symbol with the same name as a versioned libc
+ // symbol. That will show up here as a symbol which has already
+ // been allocated and is therefore no longer a common symbol.
+ if (!sym->is_common())
+ continue;
+
Sized_symbol<size>* ssym = this->get_sized_symbol<size>(sym);
// Record the symbol in the map file now, before we change its