MC: Add TargetAsmBackend::MayNeedRelaxation, for checking whether a particular instru...
[oota-llvm.git] / lib / MC / MachObjectWriter.cpp
index 9ea79f070c6ca9d098e80aa88eef48782ff758f1..e6232acbf0de3f3d6785924aae672deb8cb1797e 100644 (file)
@@ -192,8 +192,6 @@ public:
     : Writer(_Writer), OS(Writer->getStream()), Is64Bit(_Is64Bit) {
   }
 
-  virtual ~MachObjectWriterImpl() {}
-
   void Write8(uint8_t Value) { Writer->Write8(Value); }
   void Write16(uint16_t Value) { Writer->Write16(Value); }
   void Write32(uint32_t Value) { Writer->Write32(Value); }
@@ -439,8 +437,22 @@ public:
       Write32(Address);
   }
 
+  // FIXME: We really need to improve the relocation validation. Basically, we
+  // want to implement a separate computation which evaluates the relocation
+  // entry as the linker would, and verifies that the resultant fixup value is
+  // exactly what the encoder wanted. This will catch several classes of
+  // problems:
+  //
+  //  - Relocation entry bugs, the two algorithms are unlikely to have the same
+  //    exact bug.
+  //
+  //  - Relaxation issues, where we forget to relax something.
+  //
+  //  - Input errors, where something cannot be correctly encoded. 'as' allows
+  //    these through in many cases.
+
   void RecordX86_64Relocation(const MCAssembler &Asm,
-                              const MCDataFragment &Fragment,
+                              const MCFragment *Fragment,
                               const MCAsmFixup &Fixup, MCValue Target,
                               uint64_t &FixedValue) {
     unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
@@ -448,7 +460,7 @@ public:
     unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
 
     // See <reloc.h>.
-    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
+    uint32_t Address = Fragment->getOffset() + Fixup.Offset;
     int64_t Value = 0;
     unsigned Index = 0;
     unsigned IsExtern = 0;
@@ -523,7 +535,7 @@ public:
                    (Log2Size  << 25) |
                    (IsExtern  << 27) |
                    (Type      << 28));
-      Relocations[Fragment.getParent()].push_back(MRE);
+      Relocations[Fragment->getParent()].push_back(MRE);
 
       Index = B_Base->getIndex();
       IsExtern = 1;
@@ -624,14 +636,14 @@ public:
                  (Log2Size  << 25) |
                  (IsExtern  << 27) |
                  (Type      << 28));
-    Relocations[Fragment.getParent()].push_back(MRE);
+    Relocations[Fragment->getParent()].push_back(MRE);
   }
 
   void RecordScatteredRelocation(const MCAssembler &Asm,
-                                 const MCFragment &Fragment,
+                                 const MCFragment *Fragment,
                                  const MCAsmFixup &Fixup, MCValue Target,
                                  uint64_t &FixedValue) {
-    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
+    uint32_t Address = Fragment->getOffset() + Fixup.Offset;
     unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
     unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
     unsigned Type = RIT_Vanilla;
@@ -672,7 +684,7 @@ public:
                    (IsPCRel   << 30) |
                    RF_Scattered);
       MRE.Word1 = Value2;
-      Relocations[Fragment.getParent()].push_back(MRE);
+      Relocations[Fragment->getParent()].push_back(MRE);
     }
 
     MachRelocationEntry MRE;
@@ -682,13 +694,12 @@ public:
                  (IsPCRel   << 30) |
                  RF_Scattered);
     MRE.Word1 = Value;
-    Relocations[Fragment.getParent()].push_back(MRE);
+    Relocations[Fragment->getParent()].push_back(MRE);
   }
 
-  virtual void RecordRelocation(const MCAssembler &Asm,
-                                const MCDataFragment &Fragment,
-                                const MCAsmFixup &Fixup, MCValue Target,
-                                uint64_t &FixedValue) {
+  void RecordRelocation(const MCAssembler &Asm, const MCFragment *Fragment,
+                        const MCAsmFixup &Fixup, MCValue Target,
+                        uint64_t &FixedValue) {
     if (Is64Bit) {
       RecordX86_64Relocation(Asm, Fragment, Fixup, Target, FixedValue);
       return;
@@ -710,7 +721,7 @@ public:
     }
 
     // See <reloc.h>.
-    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
+    uint32_t Address = Fragment->getOffset() + Fixup.Offset;
     uint32_t Value = 0;
     unsigned Index = 0;
     unsigned IsExtern = 0;
@@ -755,7 +766,7 @@ public:
                  (Log2Size  << 25) |
                  (IsExtern  << 27) |
                  (Type      << 28));
-    Relocations[Fragment.getParent()].push_back(MRE);
+    Relocations[Fragment->getParent()].push_back(MRE);
   }
 
   void BindIndirectSymbols(MCAssembler &Asm) {
@@ -914,7 +925,7 @@ public:
       StringTable += '\x00';
   }
 
-  virtual void ExecutePostLayoutBinding(MCAssembler &Asm) {
+  void ExecutePostLayoutBinding(MCAssembler &Asm) {
     // Create symbol data for any indirect symbols.
     BindIndirectSymbols(Asm);
 
@@ -923,7 +934,7 @@ public:
                        UndefinedSymbolData);
   }
 
-  virtual void WriteObject(const MCAssembler &Asm) {
+  void WriteObject(const MCAssembler &Asm) {
     unsigned NumSections = Asm.size();
 
     // The section data starts after the header, the segment load command (and
@@ -1100,7 +1111,7 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
 }
 
 void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
-                                        const MCDataFragment &Fragment,
+                                        const MCFragment *Fragment,
                                         const MCAsmFixup &Fixup, MCValue Target,
                                         uint64_t &FixedValue) {
   ((MachObjectWriterImpl*) Impl)->RecordRelocation(Asm, Fragment, Fixup,