Skip to content

Commit 776f1d5

Browse files
committed
[RuntimeDyld][COFF] Skip non-loaded sections when calculating ImageBase.
Non-loaded sections (whose unused load-address defaults to zero) should not be taken into account when calculating ImageBase, or ImageBase will be incorrectly set to 0. Patch by Andrew Scheidecker. Thanks Andrew! https://reviews.llvm.org/D51343 + // The Sections list may contain sections that weren't loaded for + // whatever reason: they may be debug sections, and ProcessAllSections + // is false, or they may be sections that contain 0 bytes. If the + // section isn't loaded, the load address will be 0, and it should not + // be included in the ImageBase calculation. llvm-svn: 344995
1 parent 3d16af6 commit 776f1d5

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ class RuntimeDyldCOFFX86_64 : public RuntimeDyldCOFF {
3737
if (!ImageBase) {
3838
ImageBase = std::numeric_limits<uint64_t>::max();
3939
for (const SectionEntry &Section : Sections)
40-
ImageBase = std::min(ImageBase, Section.getLoadAddress());
40+
// The Sections list may contain sections that weren't loaded for
41+
// whatever reason: they may be debug sections, and ProcessAllSections
42+
// is false, or they may be sections that contain 0 bytes. If the
43+
// section isn't loaded, the load address will be 0, and it should not
44+
// be included in the ImageBase calculation.
45+
if (Section.getLoadAddress() != 0)
46+
ImageBase = std::min(ImageBase, Section.getLoadAddress());
4147
}
4248
return ImageBase;
4349
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RUN: rm -rf %t && mkdir -p %t
22
# RUN: llvm-mc -triple=x86_64-pc-win32 -filetype=obj -o %t/COFF_x86_64_IMGREL.o %s
3-
# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -check=%s %t/COFF_x86_64_IMGREL.o
3+
# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -target-addr-start=40960000000000 -check=%s %t/COFF_x86_64_IMGREL.o
44
.text
55
.def F;
66
.scl 2;
@@ -18,9 +18,9 @@
1818
.align 16, 0x90
1919

2020
F: # @F
21-
# rtdyld-check: decode_operand(inst1, 3) = section_addr(COFF_x86_64_IMGREL.o, .text)+0
21+
# rtdyld-check: decode_operand(inst1, 3) = section_addr(COFF_x86_64_IMGREL.o, .text)+0-40960000000000
2222
inst1:
2323
mov %ebx, F@IMGREL
24-
# rtdyld-check: decode_operand(inst2, 3) = section_addr(COFF_x86_64_IMGREL.o, .rdata)+5
24+
# rtdyld-check: decode_operand(inst2, 3) = section_addr(COFF_x86_64_IMGREL.o, .rdata)+5-40960000000000
2525
inst2:
2626
mov %ebx, (__constdata@imgrel+5)

llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,25 +88,30 @@ CheckFiles("check",
8888
cl::desc("File containing RuntimeDyld verifier checks."),
8989
cl::ZeroOrMore);
9090

91-
static cl::opt<uint64_t>
91+
// Tracking BUG: 19665
92+
// http://llvm.org/bugs/show_bug.cgi?id=19665
93+
//
94+
// Do not change these options to cl::opt<uint64_t> since this silently breaks
95+
// argument parsing.
96+
static cl::opt<unsigned long long>
9297
PreallocMemory("preallocate",
9398
cl::desc("Allocate memory upfront rather than on-demand"),
9499
cl::init(0));
95100

96-
static cl::opt<uint64_t>
101+
static cl::opt<unsigned long long>
97102
TargetAddrStart("target-addr-start",
98103
cl::desc("For -verify only: start of phony target address "
99104
"range."),
100105
cl::init(4096), // Start at "page 1" - no allocating at "null".
101106
cl::Hidden);
102107

103-
static cl::opt<uint64_t>
108+
static cl::opt<unsigned long long>
104109
TargetAddrEnd("target-addr-end",
105110
cl::desc("For -verify only: end of phony target address range."),
106111
cl::init(~0ULL),
107112
cl::Hidden);
108113

109-
static cl::opt<uint64_t>
114+
static cl::opt<unsigned long long>
110115
TargetSectionSep("target-section-sep",
111116
cl::desc("For -verify only: Separation between sections in "
112117
"phony target address space."),
@@ -577,7 +582,11 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
577582
if (LoadAddr &&
578583
*LoadAddr != static_cast<uint64_t>(
579584
reinterpret_cast<uintptr_t>(Tmp->first))) {
580-
AlreadyAllocated[*LoadAddr] = Tmp->second;
585+
// A section will have a LoadAddr of 0 if it wasn't loaded for whatever
586+
// reason (e.g. zero byte COFF sections). Don't include those sections in
587+
// the allocation map.
588+
if (*LoadAddr != 0)
589+
AlreadyAllocated[*LoadAddr] = Tmp->second;
581590
Worklist.erase(Tmp);
582591
}
583592
}

0 commit comments

Comments
 (0)