MC/Mach-O: Implement IsSymbolRefDifferenceFullyResolved.

- Unlike for fixups, we always do the "reliable" thing (not just for x86_64).
 - Since Darwin 'as' would typically reject things that using this will allow,
   we don't need to worry about compatibility.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122038 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2010-12-17 04:54:58 +00:00
parent 1f3662abba
commit 32c1c5ae5f

View File

@ -1126,6 +1126,31 @@ public:
bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolRefExpr *A,
const MCSymbolRefExpr *B) const {
// The effective address is
// addr(atom(A)) + offset(A)
// - addr(atom(B)) - offset(B)
// and the offsets are not relocatable, so the fixup is fully resolved when
// addr(atom(A)) - addr(atom(B)) == 0.
const MCSymbolData *A_Base = 0, *B_Base = 0;
// Modified symbol references cannot be resolved.
if (A->getKind() != MCSymbolRefExpr::VK_None ||
B->getKind() != MCSymbolRefExpr::VK_None)
return false;
A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol()));
if (!A_Base)
return false;
B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol()));
if (!B_Base)
return false;
// If the atoms are the same, they are guaranteed to have the same address.
if (A_Base == B_Base)
return true;
// Otherwise, we can't prove this is fully resolved.
return false;
}