diff options
author | Ian Lance Taylor <ian@airs.com> | 2009-12-31 05:07:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2009-12-31 05:07:22 +0000 |
commit | eda294df6d71e405810e6b56e2bab2bff91a1799 (patch) | |
tree | cae358d1e57adf539483db13d65defa840bf0397 /gold/common.cc | |
parent | d7bb5745008bb111becc3dc87e7ce243f59b7170 (diff) | |
download | gdb-eda294df6d71e405810e6b56e2bab2bff91a1799.zip gdb-eda294df6d71e405810e6b56e2bab2bff91a1799.tar.gz gdb-eda294df6d71e405810e6b56e2bab2bff91a1799.tar.bz2 |
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.cc | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/gold/common.cc b/gold/common.cc index c4ff047..8859338 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 |