diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index a06f44a15f1..7feeec3bc8f 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -264,7 +264,6 @@ public: bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index f8e2821c4dc..b490e92c521 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -94,7 +94,6 @@ public: virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const; diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 32ec969c369..1646fe59ce4 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -275,7 +275,6 @@ class ELFObjectWriter : public MCObjectWriter { bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; @@ -1669,13 +1668,15 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, } bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, - bool IsPCRel) const { - if (!InSet && (::isWeak(DataA) || (DataB && ::isWeak(*DataB)))) - return false; - return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - Asm, DataA, DataB, FB, InSet, IsPCRel); + const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { + if (IsPCRel) { + assert(!InSet); + if (::isWeak(DataA)) + return false; + } + return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB, + InSet, IsPCRel); } bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const { diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index d09e383f73f..a7df95a384f 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -504,7 +504,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } else { const MCSymbolData &DataA = getSymbolData(SA); IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl( - *this, DataA, nullptr, *DF, false, true); + *this, DataA, *DF, false, true); } } } else { diff --git a/lib/MC/MCObjectWriter.cpp b/lib/MC/MCObjectWriter.cpp index e40c07d5527..e90dea81479 100644 --- a/lib/MC/MCObjectWriter.cpp +++ b/lib/MC/MCObjectWriter.cpp @@ -36,13 +36,12 @@ bool MCObjectWriter::IsSymbolRefDifferenceFullyResolved( return false; return IsSymbolRefDifferenceFullyResolvedImpl( - Asm, DataA, &DataB, *DataB.getFragment(), InSet, false); + Asm, DataA, *DataB.getFragment(), InSet, false); } bool MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, - bool IsPCRel) const { + const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { const MCSection &SecA = DataA.getSymbol().getSection(); const MCSection &SecB = FB.getParent()->getSection(); // On ELF and COFF A - B is absolute if A and B are in the same section. diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 97143a94fb1..dc68a89e6ea 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -669,13 +669,9 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, BindIndirectSymbols(Asm); } -bool MachObjectWriter:: -IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCSymbolData *DataB, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { +bool MachObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { if (InSet) return true; diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index a4b6bf9b08f..58546307255 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -172,7 +172,6 @@ public: bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; @@ -649,17 +648,16 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, } bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - const MCAssembler &Asm, const MCSymbolData &DataA, - const MCSymbolData *DataB, const MCFragment &FB, bool InSet, - bool IsPCRel) const { + const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { // MS LINK expects to be able to replace all references to a function with a // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize // away any relocations to functions. if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) return false; - return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - Asm, DataA, DataB, FB, InSet, IsPCRel); + return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB, + InSet, IsPCRel); } bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const { diff --git a/test/MC/ELF/weak-diff.s b/test/MC/ELF/weak-diff.s index d270bbb7334..ded89b8f833 100644 --- a/test/MC/ELF/weak-diff.s +++ b/test/MC/ELF/weak-diff.s @@ -1,6 +1,10 @@ -// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2>&1 | FileCheck %s +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu < %s | llvm-readobj -r | FileCheck %s -// CHECK: error: Cannot represent a subtraction with a weak symbol +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.text { +// CHECK-NEXT: 0x1D R_X86_64_PC32 f2 0xFFFFFFFFFFFFFFFC +// CHECK-NEXT: } +// CHECK-NEXT: ] .weak f .weak g @@ -10,3 +14,13 @@ g: nop .quad g - f + + +.weak f2 +f2: + nop +g2: + nop +.quad g2 - f2 +.quad f2 - g2 +call f2 diff --git a/test/MC/ELF/weak-diff2.s b/test/MC/ELF/weak-diff2.s deleted file mode 100644 index daf64a44232..00000000000 --- a/test/MC/ELF/weak-diff2.s +++ /dev/null @@ -1,10 +0,0 @@ -// 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 -f: - nop -g: - nop -.quad g - f