diff options
author | Fangrui Song <maskray@google.com> | 2020-01-03 21:44:57 -0800 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2020-01-12 13:46:24 -0800 |
commit | 2bfee35cb860859b436de0b780fbd00d68e198a4 (patch) | |
tree | fe4c42d800afca08c64c7f17c9e12d6146e6bf4f /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | 241f330d6bab52ab4e3a01cbb9a3edd417d07c59 (diff) | |
download | bcm5719-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.cpp | 22 |
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, |