From 4e86f54fdbcc375e14fdfc61ded8a97e8e030996 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 24 Mar 2015 23:48:44 +0000 Subject: [PATCH] Don't be over eager in evaluating a subtraction with a weak symbol. In a subtraction of the form A - B, if B is weak, there is no way to represent that on ELF since all relocations add the value of a symbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233139 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/ELFObjectWriter.cpp | 10 +++++++++- test/MC/ELF/weak-diff.s | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/MC/ELF/weak-diff.s diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index c05241b53f7..0bc17ef3543 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -803,6 +803,10 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { return nullptr; } +static bool isWeak(const MCSymbolData &D) { + return D.getFlags() & ELF_STB_Weak || MCELF::GetType(D) == ELF::STT_GNU_IFUNC; +} + void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -843,6 +847,10 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, Fixup.getLoc(), "Cannot represent a difference across sections"); const MCSymbolData &SymBD = Asm.getSymbolData(SymB); + if (isWeak(SymBD)) + Asm.getContext().FatalError( + Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); + uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD); uint64_t K = SymBOffset - FixupOffset; IsPCRel = true; @@ -1809,7 +1817,7 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCFragment &FB, bool InSet, bool IsPCRel) const { - if (DataA.getFlags() & ELF_STB_Weak || MCELF::GetType(DataA) == ELF::STT_GNU_IFUNC) + if (isWeak(DataA)) return false; return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( Asm, DataA, FB,InSet, IsPCRel); diff --git a/test/MC/ELF/weak-diff.s b/test/MC/ELF/weak-diff.s new file mode 100644 index 00000000000..d270bbb7334 --- /dev/null +++ b/test/MC/ELF/weak-diff.s @@ -0,0 +1,12 @@ +// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2>&1 | FileCheck %s + +// CHECK: error: Cannot represent a subtraction with a weak symbol + +.weak f +.weak g +f: + nop +g: + nop + +.quad g - f