[RuntimeDyld] Fix x86-64 MachO GOT relocation handling.
authorLang Hames <lhames@gmail.com>
Mon, 19 May 2014 19:21:25 +0000 (19:21 +0000)
committerLang Hames <lhames@gmail.com>
Mon, 19 May 2014 19:21:25 +0000 (19:21 +0000)
For GOT relocations the addend should modify the offset to the
GOT entry, not the value of the entry itself. Teach RuntimeDyldMachO
to do The Right Thing here.

Fixes <rdar://problem/16961886>.

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

lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
test/ExecutionEngine/RuntimeDyld/Inputs/x86_64_macho_pic_globals_GOT.o [new file with mode: 0644]
test/ExecutionEngine/RuntimeDyld/arm_secdiff_reloc.test [deleted file]
test/ExecutionEngine/RuntimeDyld/macho_relocations.test [new file with mode: 0644]

index 66456a990b7634c7e8d87f3d5ba8bbecc499d57a..30529808d0d5caec44d8550e96bfb0c3af4dee93 100644 (file)
@@ -573,6 +573,10 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
                                  RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
     assert(IsPCRel);
     assert(Size == 2);
+
+    // FIXME: Teach the generic code above not to prematurely conflate
+    //        relocation addends and symbol offsets.
+    Value.Addend -= Addend;
     StubMap::const_iterator i = Stubs.find(Value);
     uint8_t *Addr;
     if (i != Stubs.end()) {
@@ -581,7 +585,8 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
       Stubs[Value] = Section.StubOffset;
       uint8_t *GOTEntry = Section.Address + Section.StubOffset;
       RelocationEntry GOTRE(SectionID, Section.StubOffset,
-                            MachO::X86_64_RELOC_UNSIGNED, 0, false, 3);
+                            MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false,
+                            3);
       if (Value.SymbolName)
         addRelocationForSymbol(GOTRE, Value.SymbolName);
       else
@@ -590,7 +595,7 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
       Addr = GOTEntry;
     }
     RelocationEntry TargetRE(SectionID, Offset,
-                             MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true,
+                             MachO::X86_64_RELOC_UNSIGNED, Addend, true,
                              2);
     resolveRelocation(TargetRE, (uint64_t)Addr);
   } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
diff --git a/test/ExecutionEngine/RuntimeDyld/Inputs/x86_64_macho_pic_globals_GOT.o b/test/ExecutionEngine/RuntimeDyld/Inputs/x86_64_macho_pic_globals_GOT.o
new file mode 100644 (file)
index 0000000..2013a0e
Binary files /dev/null and b/test/ExecutionEngine/RuntimeDyld/Inputs/x86_64_macho_pic_globals_GOT.o differ
diff --git a/test/ExecutionEngine/RuntimeDyld/arm_secdiff_reloc.test b/test/ExecutionEngine/RuntimeDyld/arm_secdiff_reloc.test
deleted file mode 100644 (file)
index 92e4dd7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-RUN: llvm-rtdyld -printline %p/Inputs/arm_secdiff_reloc.o
diff --git a/test/ExecutionEngine/RuntimeDyld/macho_relocations.test b/test/ExecutionEngine/RuntimeDyld/macho_relocations.test
new file mode 100644 (file)
index 0000000..d340735
--- /dev/null
@@ -0,0 +1,2 @@
+RUN: llvm-rtdyld -printline %p/Inputs/arm_secdiff_reloc.o
+RUN: llvm-rtdyld %p/Inputs/x86_64_macho_pic_globals_GOT.o