aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-10-14 07:27:10 +0000
committerIan Lance Taylor <iant@google.com>2007-10-14 07:27:10 +0000
commitad435a24655b0c6a0247862c084f8d205b5d6ecc (patch)
treedeb296239af78155de66d20ee8b644dfc437fc7f
parentd20222a1e7d31611f3a805133ea6f37cd6174fa2 (diff)
downloadgdb-ad435a24655b0c6a0247862c084f8d205b5d6ecc.zip
gdb-ad435a24655b0c6a0247862c084f8d205b5d6ecc.tar.gz
gdb-ad435a24655b0c6a0247862c084f8d205b5d6ecc.tar.bz2
Adjust linkonce symbol name algorithm to work for
.gnu.linkonce.t.__i686.get_pc_thunk.bx.
-rw-r--r--gold/object.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/gold/object.cc b/gold/object.cc
index d655a41..64cecc8 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -383,7 +383,20 @@ Sized_relobj<size, big_endian>::include_linkonce_section(
const char* name,
const elfcpp::Shdr<size, big_endian>&)
{
- const char* symname = strrchr(name, '.') + 1;
+ // In general the symbol name we want will be the string following
+ // the last '.'. However, we have to handle the case of
+ // .gnu.linkonce.t.__i686.get_pc_thunk.bx, which was generated by
+ // some versions of gcc. So we use a heuristic: if the name starts
+ // with ".gnu.linkonce.t.", we use everything after that. Otherwise
+ // we look for the last '.'. We can't always simply skip
+ // ".gnu.linkonce.X", because we have to deal with cases like
+ // ".gnu.linkonce.d.rel.ro.local".
+ const char* const linkonce_t = ".gnu.linkonce.t.";
+ const char* symname;
+ if (strncmp(name, linkonce_t, strlen(linkonce_t)) == 0)
+ symname = name + strlen(linkonce_t);
+ else
+ symname = strrchr(name, '.') + 1;
bool include1 = layout->add_comdat(symname, false);
bool include2 = layout->add_comdat(name, true);
return include1 && include2;