Skip to content

Commit 0166a71

Browse files
committed
[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 <[email protected]> llvm-svn: 272911
1 parent c9fee5f commit 0166a71

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,31 @@ class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
5858
uint64_t RelType = RelI->getType();
5959
uint64_t Offset = RelI->getOffset();
6060

61+
// Determine the Addend used to adjust the relocation value.
62+
uint64_t Addend = 0;
63+
SectionEntry &AddendSection = Sections[SectionID];
64+
uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
65+
uint8_t *Displacement = (uint8_t *)ObjTarget;
66+
67+
switch (RelType) {
68+
case COFF::IMAGE_REL_I386_DIR32:
69+
case COFF::IMAGE_REL_I386_DIR32NB:
70+
case COFF::IMAGE_REL_I386_SECREL:
71+
case COFF::IMAGE_REL_I386_REL32: {
72+
Addend = readBytesUnaligned(Displacement, 4);
73+
break;
74+
}
75+
default:
76+
break;
77+
}
78+
6179
#if !defined(NDEBUG)
6280
SmallString<32> RelTypeName;
6381
RelI->getTypeName(RelTypeName);
6482
#endif
6583
DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
6684
<< " RelType: " << RelTypeName << " TargetName: " << TargetName
67-
<< "\n");
85+
<< " Addend " << Addend << "\n");
6886

6987
unsigned TargetSectionID = -1;
7088
if (Section == Obj.section_end()) {
@@ -85,7 +103,7 @@ class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
85103
case COFF::IMAGE_REL_I386_DIR32NB:
86104
case COFF::IMAGE_REL_I386_REL32: {
87105
RelocationEntry RE =
88-
RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID,
106+
RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,
89107
getSymbolOffset(*Symbol), 0, 0, false, 0);
90108
addRelocationForSection(RE, TargetSectionID);
91109
break;
@@ -98,7 +116,7 @@ class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
98116
}
99117
case COFF::IMAGE_REL_I386_SECREL: {
100118
RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
101-
getSymbolOffset(*Symbol));
119+
getSymbolOffset(*Symbol) + Addend);
102120
addRelocationForSection(RE, TargetSectionID);
103121
break;
104122
}

llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,16 @@ rel7:
6464
# rtdyld-check: *{4}rel7 = relocations - section_addr(COFF_i386.s.tmp.obj, .data)
6565
.secrel32 relocations // IMAGE_REL_I386_SECREL
6666

67+
# Test that addends work.
68+
rel8:
69+
# rtdyld-check: *{4}rel8 = string
70+
.long string // IMAGE_REL_I386_DIR32
71+
rel9:
72+
# rtdyld-check: *{4}rel9 = string+1
73+
.long string+1 // IMAGE_REL_I386_DIR32
74+
rel10:
75+
# rtdyld-check: *{4}rel10 = string - section_addr(COFF_i386.s.tmp.obj, .text) + 1
76+
.long string@imgrel+1 // IMAGE_REL_I386_DIR32NB
77+
rel11:
78+
# rtdyld-check: *{4}rel11 = string - section_addr(COFF_i386.s.tmp.obj, .data) + 1
79+
.long string@SECREL32+1 // IMAGE_REL_I386_SECREL

0 commit comments

Comments
 (0)