1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

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.

llvm-svn: 234165
This commit is contained in:
Rafael Espindola 2015-04-06 15:27:57 +00:00
parent 3e664c2fee
commit 91f7164378
8 changed files with 40 additions and 32 deletions

View File

@ -262,6 +262,7 @@ public:
bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA, const MCSymbolData &DataA,
const MCSymbolData *DataB,
const MCFragment &FB, const MCFragment &FB,
bool InSet, bool InSet,
bool IsPCRel) const override; bool IsPCRel) const override;

View File

@ -91,12 +91,12 @@ public:
const MCSymbolRefExpr *B, const MCSymbolRefExpr *B,
bool InSet) const; bool InSet) const;
virtual bool virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA,
const MCSymbolData &DataA, const MCSymbolData *DataB,
const MCFragment &FB, const MCFragment &FB,
bool InSet, bool InSet,
bool IsPCRel) const; bool IsPCRel) const;
/// \brief True if this symbol (which is a variable) is weak. This is not /// \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 /// just STB_WEAK, but more generally whether or not we can evaluate

View File

@ -300,6 +300,7 @@ class ELFObjectWriter : public MCObjectWriter {
bool bool
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA, const MCSymbolData &DataA,
const MCSymbolData *DataB,
const MCFragment &FB, const MCFragment &FB,
bool InSet, bool InSet,
bool IsPCRel) const override; bool IsPCRel) const override;
@ -619,7 +620,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
if (ESize) { if (ESize) {
int64_t Res; int64_t Res;
if (!ESize->EvaluateAsAbsolute(Res, Layout)) if (!ESize->evaluateKnownAbsolute(Res, Layout))
report_fatal_error("Size expression must be absolute."); report_fatal_error("Size expression must be absolute.");
Size = Res; Size = Res;
} }
@ -1765,16 +1766,14 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
WriteDataSectionData(Asm, Layout, *Sections[i]); WriteDataSectionData(Asm, Layout, *Sections[i]);
} }
bool bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCAssembler &Asm, const MCSymbolData &DataA,
const MCSymbolData &DataA, const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
const MCFragment &FB, bool IsPCRel) const {
bool InSet, if (!InSet && (::isWeak(DataA) || (DataB && ::isWeak(*DataB))))
bool IsPCRel) const {
if (::isWeak(DataA))
return false; return false;
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
Asm, DataA, FB,InSet, IsPCRel); Asm, DataA, DataB, FB, InSet, IsPCRel);
} }
bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const { bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {

View File

@ -502,9 +502,8 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
IsResolved = false; IsResolved = false;
} else { } else {
const MCSymbolData &DataA = getSymbolData(SA); const MCSymbolData &DataA = getSymbolData(SA);
IsResolved = IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl(
getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, *this, DataA, nullptr, *DF, false, true);
*DF, false, true);
} }
} }
} else { } else {

View File

@ -35,18 +35,14 @@ bool MCObjectWriter::IsSymbolRefDifferenceFullyResolved(
if(!DataA.getFragment() || !DataB.getFragment()) if(!DataA.getFragment() || !DataB.getFragment())
return false; return false;
return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, return IsSymbolRefDifferenceFullyResolvedImpl(
*DataB.getFragment(), Asm, DataA, &DataB, *DataB.getFragment(), InSet, false);
InSet,
false);
} }
bool bool MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCAssembler &Asm, const MCSymbolData &DataA,
const MCSymbolData &DataA, const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
const MCFragment &FB, bool IsPCRel) const {
bool InSet,
bool IsPCRel) const {
const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection(); const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
const MCSection &SecB = FB.getParent()->getSection(); const MCSection &SecB = FB.getParent()->getSection();
// On ELF and COFF A - B is absolute if A and B are in the same section. // On ELF and COFF A - B is absolute if A and B are in the same section.

View File

@ -660,6 +660,7 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
bool MachObjectWriter:: bool MachObjectWriter::
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA, const MCSymbolData &DataA,
const MCSymbolData *DataB,
const MCFragment &FB, const MCFragment &FB,
bool InSet, bool InSet,
bool IsPCRel) const { bool IsPCRel) const {

View File

@ -172,6 +172,7 @@ public:
bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA, const MCSymbolData &DataA,
const MCSymbolData *DataB,
const MCFragment &FB, bool InSet, const MCFragment &FB, bool InSet,
bool IsPCRel) const override; bool IsPCRel) const override;
@ -649,16 +650,17 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
} }
bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, const MCAssembler &Asm, const MCSymbolData &DataA,
bool InSet, bool IsPCRel) const { 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 // 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 // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
// away any relocations to functions. // away any relocations to functions.
if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >> if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >>
COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
return false; return false;
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB, return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
InSet, IsPCRel); Asm, DataA, DataB, FB, InSet, IsPCRel);
} }
bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const { bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const {

10
test/MC/ELF/weak-diff2.s Normal file
View File

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