summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2020-01-03 21:44:57 -0800
committerFangrui Song <maskray@google.com>2020-01-12 13:46:24 -0800
commit2bfee35cb860859b436de0b780fbd00d68e198a4 (patch)
treefe4c42d800afca08c64c7f17c9e12d6146e6bf4f /llvm/lib/MC/ELFObjectWriter.cpp
parent241f330d6bab52ab4e3a01cbb9a3edd417d07c59 (diff)
downloadbcm5719-llvm-2bfee35cb860859b436de0b780fbd00d68e198a4.tar.gz
bcm5719-llvm-2bfee35cb860859b436de0b780fbd00d68e198a4.zip
[MC][ELF] Emit a relocation if target is defined in the same section and is non-local
For a target symbol defined in the same section, currently we don't emit a relocation if VariantKind is VK_None (with few exceptions like RISC-V relaxation), while GNU as emits one. This causes program behavior differences with and without -ffunction-sections, and can break intended symbol interposition in a -shared link. ``` .globl foo foo: call foo # no relocation. On other targets, may be written as b foo, etc call bar # a relocation if bar is in another section (e.g. -ffunction-sections) call foo@plt # a relocation ``` Unify these cases by always emitting a relocation. If we ever want to optimize `call foo` in -shared links, we should emit a STB_LOCAL alias and call via the alias. ARM/thumb2-beq-fixup.s: we now emit a relocation to global_thumb_fn as GNU as does. X86/Inputs/align-branch-64-2.s: we now emit R_X86_64_PLT32 to foo as GNU does. ELF/relax.s: rewrite the test as target-in-same-section.s . We omitted relocations to `global` and now emit R_X86_64_PLT32. Note, GNU as does not emit a relocation for `jmp global` (maybe its own bug). Our new behavior is compatible except `jmp global`. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D72197
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp22
1 files changed, 1 insertions, 21 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index f8e93889344..b421d0b2bf6 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -569,26 +569,6 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
IsReserved);
}
-// True if the assembler knows nothing about the final value of the symbol.
-// This doesn't cover the comdat issues, since in those cases the assembler
-// can at least know that all symbols in the section will move together.
-static bool isWeak(const MCSymbolELF &Sym) {
- if (Sym.getType() == ELF::STT_GNU_IFUNC)
- return true;
-
- switch (Sym.getBinding()) {
- default:
- llvm_unreachable("Unknown binding");
- case ELF::STB_LOCAL:
- return false;
- case ELF::STB_GLOBAL:
- return false;
- case ELF::STB_WEAK:
- case ELF::STB_GNU_UNIQUE:
- return true;
- }
-}
-
bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
bool Used, bool Renamed) {
if (Symbol.isVariable()) {
@@ -1534,7 +1514,7 @@ bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
const auto &SymA = cast<MCSymbolELF>(SA);
if (IsPCRel) {
assert(!InSet);
- if (isWeak(SymA))
+ if (SymA.getBinding() != ELF::STB_LOCAL)
return false;
}
return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
OpenPOWER on IntegriCloud