MC/Mach-O: Split out RecordARMRelocation for now, it is weird enough it isn't
[oota-llvm.git] / lib / MC / MachObjectWriter.cpp
index 17615eef6974be696f628901b08aec43a5a96130..a4c612d0d696c02f9fb6b14c2b3bbec97e8b2ddc 100644 (file)
@@ -235,6 +235,10 @@ public:
   /// @{
 
   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+  bool isARM() const {
+    uint32_t CPUType = TargetObjectWriter->getCPUType() & mach::CTFM_ArchMask;
+    return CPUType == mach::CTM_ARM;
+  }
 
   /// @}
 
@@ -765,14 +769,15 @@ public:
       // Note that there is no longer any semantic difference between these two
       // relocation types from the linkers point of view, this is done solely
       // for pedantic compatibility with 'as'.
-      Type = A_SD->isExternal() ? macho::RIT_Difference :
-        macho::RIT_LocalDifference;
+      Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference :
+        (unsigned)macho::RIT_Generic_LocalDifference;
       Value2 = getSymbolAddress(B_SD, Layout);
       FixedValue -= getSectionAddress(B_SD->getFragment()->getParent());
     }
 
     // Relocations are written out in reverse order, so the PAIR comes first.
-    if (Type == macho::RIT_Difference || Type == macho::RIT_LocalDifference) {
+    if (Type == macho::RIT_Difference ||
+        Type == macho::RIT_Generic_LocalDifference) {
       macho::RelocationEntry MRE;
       MRE.Word0 = ((0         <<  0) |
                    (macho::RIT_Pair  << 24) |
@@ -830,17 +835,28 @@ public:
     // struct relocation_info (8 bytes)
     macho::RelocationEntry MRE;
     MRE.Word0 = Value;
-    MRE.Word1 = ((Index     <<  0) |
-                 (IsPCRel   << 24) |
-                 (Log2Size  << 25) |
-                 (1         << 27) | // Extern
-                 (macho::RIT_TLV   << 28)); // Type
+    MRE.Word1 = ((Index                  <<  0) |
+                 (IsPCRel                << 24) |
+                 (Log2Size               << 25) |
+                 (1                      << 27) | // Extern
+                 (macho::RIT_Generic_TLV << 28)); // Type
     Relocations[Fragment->getParent()].push_back(MRE);
   }
 
+  void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+                           const MCFragment *Fragment, const MCFixup &Fixup,
+                           MCValue Target, uint64_t &FixedValue) {
+    // FIXME!
+  }
+
   void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
                         const MCFragment *Fragment, const MCFixup &Fixup,
                         MCValue Target, uint64_t &FixedValue) {
+    // FIXME: These needs to be factored into the target Mach-O writer.
+    if (isARM()) {
+      RecordARMRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
+      return;
+    }
     if (is64Bit()) {
       RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
       return;
@@ -1125,7 +1141,14 @@ public:
 
   bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
                                           const MCSymbolRefExpr *A,
-                                          const MCSymbolRefExpr *B) const {
+                                          const MCSymbolRefExpr *B,
+                                          bool InSet) const {
+    if (InSet)
+      return true;
+
+    if (!TargetObjectWriter->useAggressiveSymbolFolding())
+      return false;
+
     // The effective address is
     //     addr(atom(A)) + offset(A)
     //   - addr(atom(B)) - offset(B)