summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp31
-rw-r--r--llvm/test/MC/ELF/alias-to-local.s18
2 files changed, 48 insertions, 1 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index b293afc56a0..e3623997a44 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -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/llvm/test/MC/ELF/alias-to-local.s b/llvm/test/MC/ELF/alias-to-local.s
new file mode 100644
index 00000000000..4983833b33a
--- /dev/null
+++ b/llvm/test/MC/ELF/alias-to-local.s
@@ -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
OpenPOWER on IntegriCloud