[llvm-commits] [llvm] r122549 - in /llvm/trunk: include/llvm/MC/MCObjectWriter.h lib/MC/ELFObjectWriter.cpp lib/MC/MCAssembler.cpp lib/MC/MCObjectWriter.cpp lib/MC/MachObjectWriter.cpp lib/MC/WinCOFFObjectWriter.cpp
Rafael Espindola
rafael.espindola at gmail.com
Fri Dec 24 13:22:02 PST 2010
Author: rafael
Date: Fri Dec 24 15:22:02 2010
New Revision: 122549
URL: http://llvm.org/viewvc/llvm-project?rev=122549&view=rev
Log:
Merge IsFixupFullyResolved and IsSymbolRefDifferenceFullyResolved. We now
have a single point where targets test if a relocation is needed.
Modified:
llvm/trunk/include/llvm/MC/MCObjectWriter.h
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/MC/MCAssembler.cpp
llvm/trunk/lib/MC/MCObjectWriter.cpp
llvm/trunk/lib/MC/MachObjectWriter.cpp
llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
Modified: llvm/trunk/include/llvm/MC/MCObjectWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectWriter.h?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectWriter.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectWriter.h Fri Dec 24 15:22:02 2010
@@ -21,6 +21,7 @@
class MCFixup;
class MCFragment;
class MCSymbol;
+class MCSymbolData;
class MCSymbolRefExpr;
class MCValue;
class raw_ostream;
@@ -84,21 +85,19 @@
///
/// Clients are not required to answer precisely and may conservatively return
/// false, even when a difference is fully resolved.
- virtual bool
+ bool
IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolRefExpr *A,
const MCSymbolRefExpr *B,
bool InSet) const;
- /// Check if a fixup is fully resolved.
- ///
- /// This routine is used by the assembler to let the file format decide
- /// if a fixup is not fully resolved. For example, one that crosses
- /// two sections on ELF.
- virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const = 0;
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const = 0;
+
/// Write the object file.
///
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri Dec 24 15:22:02 2010
@@ -344,10 +344,12 @@
MCDataFragment *F,
const MCSectionData *SD);
- virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const;
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
virtual void WriteSection(MCAssembler &Asm,
@@ -1154,50 +1156,22 @@
}
}
-bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const {
- // If this is a PCrel relocation, find the section this fixup value is
- // relative to.
- const MCSection *BaseSection = 0;
- if (IsPCRel) {
- BaseSection = &DF->getParent()->getSection();
- assert(BaseSection);
- }
-
- const MCSection *SectionA = 0;
- const MCSymbol *SymbolA = 0;
- if (const MCSymbolRefExpr *A = Target.getSymA()) {
- SymbolA = &A->getSymbol();
- SectionA = &SymbolA->AliasedSymbol().getSection();
- }
-
- const MCSection *SectionB = 0;
- const MCSymbol *SymbolB = 0;
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- SymbolB = &B->getSymbol();
- SectionB = &SymbolB->AliasedSymbol().getSection();
- }
-
- if (!BaseSection)
- return SectionA == SectionB;
-
- if (SymbolB)
- return false;
-
- // Absolute address but PCrel instruction, so we need a relocation.
- if (!SymbolA)
- return false;
-
+bool
+ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const {
// FIXME: This is in here just to match gnu as output. If the two ends
// are in the same section, there is nothing that the linker can do to
// break it.
- const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA);
if (DataA.isExternal())
return false;
- return BaseSection == SectionA;
+ const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
+ const MCSection &SecB = FB.getParent()->getSection();
+ // On ELF A - B is absolute if A and B are in the same section.
+ return &SecA == &SecB;
}
void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Dec 24 15:22:02 2010
@@ -11,6 +11,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
@@ -218,22 +219,37 @@
if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout))
report_fatal_error("expected relocatable expression");
- // FIXME: How do non-scattered symbols work in ELF? I presume the linker
- // doesn't support small relocations, but then under what criteria does the
- // assembler allow symbol differences?
+ bool IsPCRel = Backend.getFixupKindInfo(
+ Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
+
+ bool IsResolved;
+ if (IsPCRel) {
+ if (Target.getSymB()) {
+ IsResolved = false;
+ } else if (!Target.getSymA()) {
+ IsResolved = false;
+ } else {
+ const MCSymbol &SA = Target.getSymA()->getSymbol();
+ if (SA.AliasedSymbol().isUndefined()) {
+ IsResolved = false;
+ } else {
+ const MCSymbolData &DataA = getSymbolData(SA);
+ IsResolved =
+ getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA,
+ *DF, false, true);
+ }
+ }
+ } else {
+ IsResolved = Target.isAbsolute();
+ }
Value = Target.getConstant();
- bool IsPCRel = Backend.getFixupKindInfo(
- Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
- bool IsResolved = true;
bool IsThumb = false;
if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
if (Sym.isDefined())
Value += Layout.getSymbolOffset(&getSymbolData(Sym));
- else
- IsResolved = false;
if (isThumbFunc(&Sym))
IsThumb = true;
}
@@ -241,12 +257,8 @@
const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
if (Sym.isDefined())
Value -= Layout.getSymbolOffset(&getSymbolData(Sym));
- else
- IsResolved = false;
}
- if (IsResolved)
- IsResolved = getWriter().IsFixupFullyResolved(*this, Target, IsPCRel, DF);
bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
Modified: llvm/trunk/lib/MC/MCObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectWriter.cpp Fri Dec 24 15:22:02 2010
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
@@ -54,9 +55,14 @@
const MCSymbol &SA = A->getSymbol();
const MCSymbol &SB = B->getSymbol();
- if (SA.isUndefined() || SB.isUndefined())
+ if (SA.AliasedSymbol().isUndefined() || SB.AliasedSymbol().isUndefined())
return false;
- // On ELF and COFF A - B is absolute if A and B are in the same section.
- return &SA.getSection() == &SB.getSection();
+ const MCSymbolData &DataA = Asm.getSymbolData(SA);
+ const MCSymbolData &DataB = Asm.getSymbolData(SB);
+
+ return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA,
+ *DataB.getFragment(),
+ InSet,
+ false);
}
Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/MachObjectWriter.cpp Fri Dec 24 15:22:02 2010
@@ -64,86 +64,6 @@
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 @@
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 @@
// 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 @@
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();
Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=122549&r1=122548&r2=122549&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Fri Dec 24 15:22:02 2010
@@ -179,10 +179,12 @@
MCValue Target,
uint64_t &FixedValue);
- virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const;
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
@@ -717,34 +719,17 @@
coff_section->Relocations.push_back(Reloc);
}
-bool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const {
- // If this is a PCrel relocation, find the section this fixup value is
- // relative to.
- const MCSection *BaseSection = 0;
- if (IsPCRel) {
- BaseSection = &DF->getParent()->getSection();
- assert(BaseSection);
- }
-
- const MCSection *SectionA = 0;
- const MCSymbol *SymbolA = 0;
- if (const MCSymbolRefExpr *A = Target.getSymA()) {
- SymbolA = &A->getSymbol();
- SectionA = &SymbolA->getSection();
- }
-
- const MCSection *SectionB = 0;
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- SectionB = &B->getSymbol().getSection();
- }
-
- if (!BaseSection)
- return SectionA == SectionB;
-
- return !SectionB && BaseSection == SectionA;
+bool
+WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const {
+ const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
+ const MCSection &SecB = FB.getParent()->getSection();
+ // On COFF A - B is absolute if A and B are in the same section.
+ return &SecA == &SecB;
}
void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
More information about the llvm-commits
mailing list