MCAssembler: Switch MCAsmFixup to storing MCFixupKind instead of just a size.
authorDaniel Dunbar <daniel@zuster.org>
Sat, 13 Feb 2010 09:28:54 +0000 (09:28 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 13 Feb 2010 09:28:54 +0000 (09:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96094 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAssembler.h
include/llvm/MC/MCFixup.h
lib/MC/MCAssembler.cpp
lib/MC/MCMachOStreamer.cpp

index 268a3fc3b8d74d38ba67c8ea69e93a1617004f89..4527f3c28d36269a02713c10a8256db71d9b328e 100644 (file)
@@ -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 @@ struct MCAsmFixup {
   /// 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 @@ struct MCAsmFixup {
   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> {
index f325d65500107fc541b61b9d0ff2f9e8ebe056e4..cd0dd1962aefe0869204d2d46093b8b65babdd7a 100644 (file)
@@ -89,6 +89,18 @@ public:
   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
index 2875730dd32c988943227be8104508ed0f17c9e6..b2c4112f484cc0a174dddf5827739572d1c1d23b 100644 (file)
@@ -47,6 +47,16 @@ static bool isVirtualSection(const MCSection &Section) {
   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 @@ public:
       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 @@ public:
     // 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 @@ public:
   }
 
   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 @@ void MCAssembler::Finish() {
 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 @@ void MCDataFragment::dump() {
     if (i) OS << ",";
     OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
   }
-  OS << "]";
+  OS << "] (" << getContents().size() << " bytes)";
 
   if (!getFixups().empty()) {
     OS << ",\n       ";
index 770105d0e51f6d732af28e33ccabf6a1e1fb81f5..1801170ea03942179a81ab824157a66c2ea3ed41 100644 (file)
@@ -347,7 +347,8 @@ void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
       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);
   }
 }