OSDN Git Service

Don't walk aliases from global to local symbols in comdats.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 17 Apr 2015 08:46:11 +0000 (08:46 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 17 Apr 2015 08:46:11 +0000 (08:46 +0000)
This fixes pr23196.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235167 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp
test/MC/ELF/alias-to-local.s [new file with mode: 0644]

index b293afc..e362399 100644 (file)
@@ -769,7 +769,36 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) {
 }
 
 static bool isWeak(const MCSymbolData &D) {
-  return D.getFlags() & ELF_STB_Weak || MCELF::GetType(D) == ELF::STT_GNU_IFUNC;
+  if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC)
+    return true;
+
+  switch (MCELF::GetBinding(D)) {
+  default:
+    llvm_unreachable("Unknown binding");
+  case ELF::STB_LOCAL:
+    return false;
+  case ELF::STB_GLOBAL:
+    break;
+  case ELF::STB_WEAK:
+  case ELF::STB_GNU_UNIQUE:
+    return true;
+  }
+
+  const MCSymbol &Sym = D.getSymbol();
+  if (!Sym.isInSection())
+    return false;
+
+  const auto &Sec = cast<MCSectionELF>(Sym.getSection());
+  if (!Sec.getGroup())
+    return false;
+
+  // It is invalid to replace a reference to a global in a comdat
+  // with a reference to a local since out of comdat references
+  // to a local are forbidden.
+  // We could try to return false for more cases, like the reference
+  // being in the same comdat or Sym being an alias to another global,
+  // but it is not clear if it is worth the effort.
+  return true;
 }
 
 void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
diff --git a/test/MC/ELF/alias-to-local.s b/test/MC/ELF/alias-to-local.s
new file mode 100644 (file)
index 0000000..4983833
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu < %s | llvm-readobj -r | FileCheck %s
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section {{.*}} .rela.text {
+// CHECK-NEXT:     0x1 R_X86_64_32 zed 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+foo:
+       movl    $zed, %eax
+
+
+       .section        .data.bar,"aGw",@progbits,zed,comdat
+bar:
+       .byte   42
+
+       .globl  zed
+zed = bar