]> granicus.if.org Git - llvm/commitdiff
[PATCH] Fix RuntimeDyldCOFFI386 to handle relocations with a non-zero addend
authorReid Kleckner <rnk@google.com>
Thu, 16 Jun 2016 16:21:41 +0000 (16:21 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 16 Jun 2016 16:21:41 +0000 (16:21 +0000)
This fixes IMAGE_REL_I386_DIR32, IMAGE_REL_I386_DIR32NB,
IMAGE_REL_I386_SECREL, and IMAGE_REL_I386_REL32 relocations.

Based on patch by Jon Turney <jon.turney@dronecode.org.uk>

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

lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s

index 468ce11148672334e3038a3a055f59318a24d796..92fbb7c67d0bc54f77ad471a69161b0482d6df96 100644 (file)
@@ -58,13 +58,31 @@ public:
     uint64_t RelType = RelI->getType();
     uint64_t Offset = RelI->getOffset();
 
+    // Determine the Addend used to adjust the relocation value.
+    uint64_t Addend = 0;
+    SectionEntry &AddendSection = Sections[SectionID];
+    uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
+    uint8_t *Displacement = (uint8_t *)ObjTarget;
+
+    switch (RelType) {
+    case COFF::IMAGE_REL_I386_DIR32:
+    case COFF::IMAGE_REL_I386_DIR32NB:
+    case COFF::IMAGE_REL_I386_SECREL:
+    case COFF::IMAGE_REL_I386_REL32: {
+      Addend = readBytesUnaligned(Displacement, 4);
+      break;
+    }
+    default:
+      break;
+    }
+
 #if !defined(NDEBUG)
     SmallString<32> RelTypeName;
     RelI->getTypeName(RelTypeName);
 #endif
     DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
                  << " RelType: " << RelTypeName << " TargetName: " << TargetName
-                 << "\n");
+                 << " Addend " << Addend << "\n");
 
     unsigned TargetSectionID = -1;
     if (Section == Obj.section_end()) {
@@ -85,7 +103,7 @@ public:
       case COFF::IMAGE_REL_I386_DIR32NB:
       case COFF::IMAGE_REL_I386_REL32: {
         RelocationEntry RE =
-            RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID,
+            RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,
                             getSymbolOffset(*Symbol), 0, 0, false, 0);
         addRelocationForSection(RE, TargetSectionID);
         break;
@@ -98,7 +116,7 @@ public:
       }
       case COFF::IMAGE_REL_I386_SECREL: {
         RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
-                                             getSymbolOffset(*Symbol));
+                                             getSymbolOffset(*Symbol) + Addend);
         addRelocationForSection(RE, TargetSectionID);
         break;
       }
index 0a96f70250117affdc1fcc9ac9d9bd2cec604872..c2273da63dd03fd8bef1c22cbd5884e60459fad6 100644 (file)
@@ -64,3 +64,16 @@ rel7:
 # rtdyld-check: *{4}rel7 = relocations - section_addr(COFF_i386.s.tmp.obj, .data)
        .secrel32 relocations                   // IMAGE_REL_I386_SECREL
 
+# Test that addends work.
+rel8:
+# rtdyld-check: *{4}rel8 = string
+       .long string                            // IMAGE_REL_I386_DIR32
+rel9:
+# rtdyld-check: *{4}rel9 = string+1
+       .long string+1                          // IMAGE_REL_I386_DIR32
+rel10:
+# rtdyld-check: *{4}rel10 = string - section_addr(COFF_i386.s.tmp.obj, .text) + 1
+       .long string@imgrel+1                   // IMAGE_REL_I386_DIR32NB
+rel11:
+# rtdyld-check: *{4}rel11 = string - section_addr(COFF_i386.s.tmp.obj, .data) + 1
+       .long string@SECREL32+1                 // IMAGE_REL_I386_SECREL