Fix an issue in some Thumb fixups, where the effective PC address needs to be 4-byte...
[oota-llvm.git] / lib / MC / MachObjectWriter.cpp
index de96d64c2790c80dccde55639e6dd39c0084e149..1eb7c1ceead92349015da3b66c3a88f18321d21b 100644 (file)
@@ -564,14 +564,10 @@ public:
       if (A_Base == B_Base && A_Base)
         report_fatal_error("unsupported relocation with identical base");
 
-      assert((A_Base == NULL) == (B_Base == NULL));
-      assert(A_SD.getFragment()->getParent() ==
-             B_SD.getFragment()->getParent());
-
-      Value += Layout.getSymbolOffset(&A_SD) -
-               (A_Base == NULL ? 0 : Layout.getSymbolOffset(A_Base));
-      Value -= Layout.getSymbolOffset(&B_SD) -
-               (B_Base == NULL ? 0 : Layout.getSymbolOffset(B_Base));
+      Value += getSymbolAddress(&A_SD, Layout) -
+        (A_Base == NULL ? 0 : getSymbolAddress(A_Base, Layout));
+      Value -= getSymbolAddress(&B_SD, Layout) -
+        (B_Base == NULL ? 0 : getSymbolAddress(B_Base, Layout));
 
       if (A_Base) {
         Index = A_Base->getIndex();
@@ -888,6 +884,17 @@ public:
       // FIXME: Currently, these are never generated (see code below). I cannot
       // find a case where they are actually emitted.
       Type = macho::RIT_Vanilla;
+    } else if (SD->getSymbol().isVariable()) {
+      const MCExpr *Value = SD->getSymbol().getVariableValue();
+      int64_t Res;
+      bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress);
+      if (isAbs) {
+        FixedValue = Res;
+        return;
+      } else {
+        report_fatal_error("unsupported relocation of variable '" +
+                           SD->getSymbol().getName() + "'");
+      }
     } else {
       // Check whether we need an external or internal relocation.
       if (doesSymbolRequireExternRelocation(SD)) {
@@ -897,14 +904,14 @@ public:
         // compensate for the addend of the symbol address, if it was
         // undefined. This occurs with weak definitions, for example.
         if (!SD->Symbol->isUndefined())
-          FixedValue -= getSymbolAddress(SD, Layout);
+          FixedValue -= Layout.getSymbolOffset(SD);
       } else {
         // The index is the section ordinal (1-based).
         Index = SD->getFragment()->getParent()->getOrdinal() + 1;
         FixedValue += getSectionAddress(SD->getFragment()->getParent());
-        if (IsPCRel)
-          FixedValue -= getSectionAddress(Fragment->getParent());
       }
+      if (IsPCRel)
+        FixedValue -= getSectionAddress(Fragment->getParent());
 
       Type = macho::RIT_Vanilla;
     }