OSDN Git Service

MC: Calculate intra-section symbol differences correctly for COFF
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 9 Feb 2015 06:31:31 +0000 (06:31 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 9 Feb 2015 06:31:31 +0000 (06:31 +0000)
This fixes PR22060.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228565 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/WinCOFFObjectWriter.cpp
test/MC/COFF/diff.s

index bd750af..e398581 100644 (file)
@@ -706,17 +706,22 @@ void WinCOFFObjectWriter::RecordRelocation(
     CrossSection = &Symbol.getSection() != &B->getSection();
 
     // Offset of the symbol in the section
-    int64_t a = Layout.getSymbolOffset(&B_SD);
+    int64_t OffsetOfB = Layout.getSymbolOffset(&B_SD);
 
-    // Offset of the relocation in the section
-    int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
-
-    FixedValue = b - a;
     // In the case where we have SymbA and SymB, we just need to store the delta
     // between the two symbols.  Update FixedValue to account for the delta, and
     // skip recording the relocation.
-    if (!CrossSection)
+    if (!CrossSection) {
+      int64_t OffsetOfA = Layout.getSymbolOffset(&A_SD);
+      FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant();
       return;
+    }
+
+    // Offset of the relocation in the section
+    int64_t OffsetOfRelocation =
+        Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+
+    FixedValue = OffsetOfRelocation - OffsetOfB;
   } else {
     FixedValue = Target.getConstant();
   }
index 820272a..5111600 100644 (file)
@@ -1,5 +1,23 @@
 // RUN: llvm-mc -filetype=obj -triple i686-pc-mingw32 %s | llvm-readobj -s -sr -sd | FileCheck %s
 
+.section baz, "xr"
+       .def    X
+       .scl    2;
+       .type   32;
+       .endef
+       .globl  X
+X:
+       mov     Y-X+42, %eax
+       retl
+
+       .def    Y
+       .scl    2;
+       .type   32;
+       .endef
+       .globl  Y
+Y:
+       retl
+
        .def     _foobar;
        .scl    2;
        .type   32;
@@ -30,3 +48,10 @@ _rust_crate:
 // CHECK:        SectionData (
 // CHECK-NEXT:     0000: 00000000 00000000 1C000000 20000000
 // CHECK-NEXT:   )
+
+// CHECK:        Name: baz
+// CHECK:        Relocations [
+// CHECK-NEXT:   ]
+// CHECK:        SectionData (
+// CHECK-NEXT:     0000: A1300000 00C3C3
+// CHECK-NEXT:   )