summaryrefslogtreecommitdiff
path: root/lib/MC/MachObjectWriter.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-12-17 04:54:58 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-12-17 04:54:58 +0000
commit32c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cac (patch)
treef851141127fb636f4c6822bc8eedb4fc93786bfb /lib/MC/MachObjectWriter.cpp
parent1f3662abba2abdf5a0ab77095834271fcf846579 (diff)
downloadllvm-32c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cac.tar.gz
llvm-32c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cac.tar.bz2
llvm-32c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cac.tar.xz
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
Diffstat (limited to 'lib/MC/MachObjectWriter.cpp')
-rw-r--r--lib/MC/MachObjectWriter.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index e12daa708b..17615eef69 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -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;
}