From 9428f184be2492c6bae7d361bc3f44437641dc50 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 6 Apr 2015 15:27:57 +0000 Subject: [PATCH] Be consistent when deciding if a relocation is needed. Before when deciding if we needed a relocation in A-B, we wore only checking if A was weak. This fixes the asymmetry. The "InSet" argument should probably be renamed to "ForValue", since InSet is very MachO specific, but doing so in this patch would make it hard to read. This fixes PR22815. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234165 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCMachObjectWriter.h | 1 + include/llvm/MC/MCObjectWriter.h | 12 ++++++------ lib/MC/ELFObjectWriter.cpp | 17 ++++++++--------- lib/MC/MCAssembler.cpp | 5 ++--- lib/MC/MCObjectWriter.cpp | 16 ++++++---------- lib/MC/MachObjectWriter.cpp | 1 + lib/MC/WinCOFFObjectWriter.cpp | 10 ++++++---- test/MC/ELF/weak-diff2.s | 10 ++++++++++ 8 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 test/MC/ELF/weak-diff2.s diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 3d270ce7e0d..eb2789b90f9 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -262,6 +262,7 @@ 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 fcfa968362b..2965ce21b82 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -91,12 +91,12 @@ public: const MCSymbolRefExpr *B, bool InSet) const; - virtual bool - IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const; + virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCSymbolData *DataB, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; /// \brief True if this symbol (which is a variable) is weak. This is not /// just STB_WEAK, but more generally whether or not we can evaluate diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 2004b1b8a2d..6105b25b8bf 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -300,6 +300,7 @@ class ELFObjectWriter : public MCObjectWriter { bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; @@ -619,7 +620,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, if (ESize) { int64_t Res; - if (!ESize->EvaluateAsAbsolute(Res, Layout)) + if (!ESize->evaluateKnownAbsolute(Res, Layout)) report_fatal_error("Size expression must be absolute."); Size = Res; } @@ -1765,16 +1766,14 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, WriteDataSectionData(Asm, Layout, *Sections[i]); } -bool -ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { - if (::isWeak(DataA)) +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, FB,InSet, IsPCRel); + Asm, DataA, DataB, FB, InSet, IsPCRel); } bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const { diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 857eafc0b7e..d7ca875f297 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -502,9 +502,8 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, IsResolved = false; } else { const MCSymbolData &DataA = getSymbolData(SA); - IsResolved = - getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, - *DF, false, true); + IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl( + *this, DataA, nullptr, *DF, false, true); } } } else { diff --git a/lib/MC/MCObjectWriter.cpp b/lib/MC/MCObjectWriter.cpp index 3c536ecc9fd..33e4556e102 100644 --- a/lib/MC/MCObjectWriter.cpp +++ b/lib/MC/MCObjectWriter.cpp @@ -35,18 +35,14 @@ bool MCObjectWriter::IsSymbolRefDifferenceFullyResolved( if(!DataA.getFragment() || !DataB.getFragment()) return false; - return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, - *DataB.getFragment(), - InSet, - false); + return IsSymbolRefDifferenceFullyResolvedImpl( + Asm, DataA, &DataB, *DataB.getFragment(), InSet, false); } -bool -MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { +bool MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, const MCFragment &FB, bool InSet, + bool IsPCRel) const { const MCSection &SecA = DataA.getSymbol().AliasedSymbol().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 56cccab1d39..93ff75211c4 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -660,6 +660,7 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, bool MachObjectWriter:: IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const { diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index ff90b7c2cef..b62b342edd1 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -172,6 +172,7 @@ public: bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; @@ -649,16 +650,17 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, } bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, - bool InSet, bool IsPCRel) const { + const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, 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, FB, - InSet, IsPCRel); + return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + Asm, DataA, DataB, FB, InSet, IsPCRel); } bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const { diff --git a/test/MC/ELF/weak-diff2.s b/test/MC/ELF/weak-diff2.s new file mode 100644 index 00000000000..daf64a44232 --- /dev/null +++ b/test/MC/ELF/weak-diff2.s @@ -0,0 +1,10 @@ +// 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 -- 2.34.1