aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MachObjectWriter.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-24 21:22:02 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-24 21:22:02 +0000
commitfea753b397823c340608925eb7f3256a64a30017 (patch)
tree91016581c74485267516a02e4066ef865445cc0d /lib/MC/MachObjectWriter.cpp
parenta112087e4298ca8ec1bc8aef8a2b272e49faa7ac (diff)
Merge IsFixupFullyResolved and IsSymbolRefDifferenceFullyResolved. We now
have a single point where targets test if a relocation is needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122549 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MachObjectWriter.cpp')
-rw-r--r--lib/MC/MachObjectWriter.cpp157
1 files changed, 33 insertions, 124 deletions
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index c8fe40e2f4..24ad99879f 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -64,86 +64,6 @@ static bool doesSymbolRequireExternRelocation(MCSymbolData *SD) {
return false;
}
-static bool isScatteredFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- const MCSymbolData *BaseSymbol) {
- // The effective fixup address is
- // addr(atom(A)) + offset(A)
- // - addr(atom(B)) - offset(B)
- // - addr(BaseSymbol) + <fixup offset from base symbol>
- // and the offsets are not relocatable, so the fixup is fully resolved when
- // addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0.
- //
- // Note that "false" is almost always conservatively correct (it means we emit
- // a relocation which is unnecessary), except when it would force us to emit a
- // relocation which the target cannot encode.
-
- const MCSymbolData *A_Base = 0, *B_Base = 0;
- if (const MCSymbolRefExpr *A = Target.getSymA()) {
- // Modified symbol references cannot be resolved.
- if (A->getKind() != MCSymbolRefExpr::VK_None)
- return false;
-
- A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol()));
- if (!A_Base)
- return false;
- }
-
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- // Modified symbol references cannot be resolved.
- if (B->getKind() != MCSymbolRefExpr::VK_None)
- return false;
-
- B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol()));
- if (!B_Base)
- return false;
- }
-
- // If there is no base, A and B have to be the same atom for this fixup to be
- // fully resolved.
- if (!BaseSymbol)
- return A_Base == B_Base;
-
- // Otherwise, B must be missing and A must be the base.
- return !B_Base && BaseSymbol == A_Base;
-}
-
-static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm,
- const MCValue Target,
- const MCSection *BaseSection) {
- // The effective fixup address is
- // addr(atom(A)) + offset(A)
- // - addr(atom(B)) - offset(B)
- // - addr(<base symbol>) + <fixup offset from base symbol>
- // and the offsets are not relocatable, so the fixup is fully resolved when
- // addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0.
- //
- // The simple (Darwin, except on x86_64) way of dealing with this was to
- // assume that any reference to a temporary symbol *must* be a temporary
- // symbol in the same atom, unless the sections differ. Therefore, any PCrel
- // relocation to a temporary symbol (in the same section) is fully
- // resolved. This also works in conjunction with absolutized .set, which
- // requires the compiler to use .set to absolutize the differences between
- // symbols which the compiler knows to be assembly time constants, so we don't
- // need to worry about considering symbol differences fully resolved.
-
- // Non-relative fixups are only resolved if constant.
- if (!BaseSection)
- return Target.isAbsolute();
-
- // Otherwise, relative fixups are only resolved if not a difference and the
- // target is a temporary in the same section.
- if (Target.isAbsolute() || Target.getSymB())
- return false;
-
- const MCSymbol *A = &Target.getSymA()->getSymbol();
- if (!A->isTemporary() || !A->isInSection() ||
- &A->getSection() != BaseSection)
- return false;
-
- return true;
-}
-
namespace {
class MachObjectWriter : public MCObjectWriter {
@@ -1325,16 +1245,14 @@ public:
UndefinedSymbolData);
}
- bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
- const MCSymbolRefExpr *A,
- const MCSymbolRefExpr *B,
- bool InSet) const {
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const {
if (InSet)
return true;
- if (!TargetObjectWriter->useAggressiveSymbolFolding())
- return false;
-
// The effective address is
// addr(atom(A)) + offset(A)
// - addr(atom(B)) - offset(B)
@@ -1342,16 +1260,38 @@ public:
// 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;
+ const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
+ const MCSection &SecA = SA.getSection();
+ const MCSection &SecB = FB.getParent()->getSection();
+
+ if (IsPCRel) {
+ // The simple (Darwin, except on x86_64) way of dealing with this was to
+ // assume that any reference to a temporary symbol *must* be a temporary
+ // symbol in the same atom, unless the sections differ. Therefore, any
+ // PCrel relocation to a temporary symbol (in the same section) is fully
+ // resolved. This also works in conjunction with absolutized .set, which
+ // requires the compiler to use .set to absolutize the differences between
+ // symbols which the compiler knows to be assembly time constants, so we
+ // don't need to worry about considering symbol differences fully
+ // resolved.
+
+ if (!Asm.getBackend().hasReliableSymbolDifference()) {
+ if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB)
+ return false;
+ return true;
+ }
+ } else {
+ if (!TargetObjectWriter->useAggressiveSymbolFolding())
+ return false;
+ }
+
+ const MCFragment &FA = *Asm.getSymbolData(SA).getFragment();
- A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol()));
+ A_Base = FA.getAtom();
if (!A_Base)
return false;
- B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol()));
+ B_Base = FB.getAtom();
if (!B_Base)
return false;
@@ -1363,37 +1303,6 @@ public:
return false;
}
- bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const {
- // Otherwise, determine whether this value is actually resolved; scattering
- // may cause atoms to move.
-
- // Check if we are using the "simple" resolution algorithm (e.g.,
- // i386).
- if (!Asm.getBackend().hasReliableSymbolDifference()) {
- const MCSection *BaseSection = 0;
- if (IsPCRel)
- BaseSection = &DF->getParent()->getSection();
-
- return isScatteredFixupFullyResolvedSimple(Asm, Target, BaseSection);
- }
-
- // Otherwise, compute the proper answer as reliably as possible.
-
- // If this is a PCrel relocation, find the base atom (identified by its
- // symbol) that the fixup value is relative to.
- const MCSymbolData *BaseSymbol = 0;
- if (IsPCRel) {
- BaseSymbol = DF->getAtom();
- if (!BaseSymbol)
- return false;
- }
-
- return isScatteredFixupFullyResolved(Asm, Target, BaseSymbol);
- }
-
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
unsigned NumSections = Asm.size();