The variable "Value" is carefully set to Layout.getSymbolAddress,
[oota-llvm.git] / lib / MC / MachObjectWriter.cpp
index 7be7af21b3f0181217839544bead5fa6cafd4748..fbe068b58ec85dabd7f7a15a0e016c3af3be1c35 100644 (file)
@@ -747,7 +747,6 @@ public:
            !Is64Bit &&
            "Should only be called with a 32-bit TLVP relocation!");
 
-    // If this is a subtraction then we're pcrel.
     unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
     uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
     unsigned IsPCRel = 0;
@@ -756,8 +755,22 @@ public:
     MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol());
     unsigned Index = SD_A->getIndex();
 
-    if (Target.getSymB())
+    // We're only going to have a second symbol in pic mode and it'll be a
+    // subtraction from the picbase. For 32-bit pic the addend is the difference
+    // between the picbase and the next address.  For 32-bit static the addend
+    // is zero.
+    if (Target.getSymB()) {
+      // If this is a subtraction then we're pcrel.
+      uint32_t FixupAddress =
+      Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
+      MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol());
       IsPCRel = 1;
+      FixedValue = (FixupAddress - Layout.getSymbolAddress(SD_B) +
+                    Target.getConstant());
+      FixedValue += 1 << Log2Size;
+    } else {
+      FixedValue = 0;
+    }
     
     // struct relocation_info (8 bytes)
     MachRelocationEntry MRE;
@@ -810,7 +823,6 @@ public:
 
     // See <reloc.h>.
     uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
-    uint32_t Value = 0;
     unsigned Index = 0;
     unsigned IsExtern = 0;
     unsigned Type = 0;
@@ -821,7 +833,6 @@ public:
       // FIXME: Currently, these are never generated (see code below). I cannot
       // find a case where they are actually emitted.
       Type = RIT_Vanilla;
-      Value = 0;
     } else {
       // Check whether we need an external or internal relocation.
       if (doesSymbolRequireExternRelocation(SD)) {
@@ -832,11 +843,9 @@ public:
         // undefined. This occurs with weak definitions, for example.
         if (!SD->Symbol->isUndefined())
           FixedValue -= Layout.getSymbolAddress(SD);
-        Value = 0;
       } else {
         // The index is the section ordinal (1-based).
         Index = SD->getFragment()->getParent()->getOrdinal() + 1;
-        Value = Layout.getSymbolAddress(SD);
       }
 
       Type = RIT_Vanilla;