Adjust linkonce symbol name algorithm to work for
authorIan Lance Taylor <iant@google.com>
Sun, 14 Oct 2007 07:27:10 +0000 (07:27 +0000)
committerIan Lance Taylor <iant@google.com>
Sun, 14 Oct 2007 07:27:10 +0000 (07:27 +0000)
.gnu.linkonce.t.__i686.get_pc_thunk.bx.

gold/object.cc

index d655a4102fd86cdff90ed2a06001e578ac47963f..64cecc83762c83efa0cde4d78975de5d57192d1e 100644 (file)
@@ -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;