From: Reid Kleckner Date: Thu, 16 Jun 2016 16:21:41 +0000 (+0000) Subject: [PATCH] Fix RuntimeDyldCOFFI386 to handle relocations with a non-zero addend X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71b1fedfef220802a262c6909abc94006ad55c3a;p=llvm [PATCH] Fix RuntimeDyldCOFFI386 to handle relocations with a non-zero addend 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272911 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h index 468ce111486..92fbb7c67d0 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -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; } diff --git a/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s b/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s index 0a96f702501..c2273da63dd 100644 --- a/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s +++ b/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s @@ -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