MCAssembler: Switch MCAsmFixup to storing MCFixupKind instead of just a size.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96094 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 268a3fc..4527f3c 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/MC/MCFixup.h"
 #include "llvm/System/DataTypes.h"
 #include <vector> // FIXME: Shouldn't be needed.
 
@@ -37,8 +38,8 @@
   /// Value - The expression to eventually write into the fragment.
   const MCExpr *Value;
 
-  /// Size - The fixup size.
-  unsigned Size;
+  /// Kind - The fixup kind.
+  MCFixupKind Kind;
 
   /// FixedValue - The value to replace the fix up by.
   //
@@ -46,8 +47,8 @@
   uint64_t FixedValue;
 
 public:
-  MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, unsigned _Size)
-    : Offset(_Offset), Value(&_Value), Size(_Size), FixedValue(0) {}
+  MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
+    : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
 };
 
 class MCFragment : public ilist_node<MCFragment> {
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index f325d65..cd0dd19 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -89,6 +89,18 @@
   unsigned getOffset() const { return Offset; }
 
   const MCExpr *getValue() const { return Value; }
+
+  /// getKindForSize - Return the generic fixup kind for a value with the given
+  /// size. It is an error to pass an unsupported size.
+  static MCFixupKind getKindForSize(unsigned Size) {
+    switch (Size) {
+    default: assert(0 && "Invalid generic fixup size!");
+    case 1: return FK_Data_1;
+    case 2: return FK_Data_2;
+    case 4: return FK_Data_4;
+    case 8: return FK_Data_8;
+    }
+  }
 };
 
 } // End llvm namespace
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 2875730..b2c4112 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -47,6 +47,16 @@
   return (Type == MCSectionMachO::S_ZEROFILL);
 }
 
+static unsigned getFixupKindLog2Size(MCFixupKind Kind) {
+  switch (Kind) {
+  default: llvm_unreachable("invalid fixup kind!");
+  case FK_Data_1: return 0;
+  case FK_Data_2: return 1;
+  case FK_Data_4: return 2;
+  case FK_Data_8: return 3;
+  }
+}
+
 class MachObjectWriter {
   // See <mach-o/loader.h>.
   enum {
@@ -426,8 +436,7 @@
       Value2 = SD->getFragment()->getAddress() + SD->getOffset();
     }
 
-    unsigned Log2Size = Log2_32(Fixup.Size);
-    assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
+    unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
 
     // The value which goes in the fixup is current value of the expression.
     Fixup.FixedValue = Value - Value2 + Target.getConstant();
@@ -512,8 +521,7 @@
     // The value which goes in the fixup is current value of the expression.
     Fixup.FixedValue = Value + Target.getConstant();
 
-    unsigned Log2Size = Log2_32(Fixup.Size);
-    assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
+    unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
 
     // struct relocation_info (8 bytes)
     MachRelocationEntry MRE;
@@ -880,8 +888,12 @@
   }
 
   void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) {
+    unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind);
+
     // FIXME: Endianness assumption.
-    for (unsigned i = 0; i != Fixup.Size; ++i)
+    assert(Fixup.Offset + Size <= DF.getContents().size() &&
+           "Invalid fixup offset!");
+    for (unsigned i = 0; i != Size; ++i)
       DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8));
   }
 };
@@ -1186,8 +1198,8 @@
 namespace llvm {
 
 raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
-  OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << AF.Value
-     << " Size:" << AF.Size << ">";
+  OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
+     << " Kind:" << AF.Kind << ">";
   return OS;
 }
 
@@ -1224,7 +1236,7 @@
     if (i) OS << ",";
     OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
   }
-  OS << "]";
+  OS << "] (" << getContents().size() << " bytes)";
 
   if (!getFixups().empty()) {
     OS << ",\n       ";
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 770105d..1801170 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -347,7 +347,8 @@
       DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
   } else {
     DF->getFixups().push_back(MCAsmFixup(DF->getContents().size(),
-                                         *AddValueSymbols(Value), Size));
+                                         *AddValueSymbols(Value),
+                                         MCFixup::getKindForSize(Size)));
     DF->getContents().resize(DF->getContents().size() + Size, 0);
   }
 }