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
This commit is contained in:
Rafael Espindola 2015-03-24 23:48:44 +00:00
parent d639e1975d
commit 4e86f54fdb
2 changed files with 21 additions and 1 deletions

View File

@ -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);

12
test/MC/ELF/weak-diff.s Normal file
View File

@ -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