[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