Index: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -37,7 +37,13 @@ if (!ImageBase) { ImageBase = std::numeric_limits::max(); for (const SectionEntry &Section : Sections) - ImageBase = std::min(ImageBase, Section.getLoadAddress()); + // 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. + if (Section.getLoadAddress() != 0) + ImageBase = std::min(ImageBase, Section.getLoadAddress()); } return ImageBase; } Index: test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64_IMGREL.s =================================================================== --- test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64_IMGREL.s +++ test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64_IMGREL.s @@ -1,6 +1,6 @@ # RUN: rm -rf %t && mkdir -p %t # RUN: llvm-mc -triple=x86_64-pc-win32 -filetype=obj -o %t/COFF_x86_64_IMGREL.o %s -# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -check=%s %t/COFF_x86_64_IMGREL.o +# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -target-addr-start=40960000000000 -check=%s %t/COFF_x86_64_IMGREL.o .text .def F; .scl 2; @@ -18,9 +18,9 @@ .align 16, 0x90 F: # @F -# rtdyld-check: decode_operand(inst1, 3) = section_addr(COFF_x86_64_IMGREL.o, .text)+0 +# rtdyld-check: decode_operand(inst1, 3) = section_addr(COFF_x86_64_IMGREL.o, .text)+0-40960000000000 inst1: mov %ebx, F@IMGREL -# rtdyld-check: decode_operand(inst2, 3) = section_addr(COFF_x86_64_IMGREL.o, .rdata)+5 +# rtdyld-check: decode_operand(inst2, 3) = section_addr(COFF_x86_64_IMGREL.o, .rdata)+5-40960000000000 inst2: mov %ebx, (__constdata@imgrel+5) Index: tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- tools/llvm-rtdyld/llvm-rtdyld.cpp +++ tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -88,25 +88,30 @@ cl::desc("File containing RuntimeDyld verifier checks."), cl::ZeroOrMore); -static cl::opt +// Tracking BUG: 19665 +// http://llvm.org/bugs/show_bug.cgi?id=19665 +// +// Do not change these options to cl::opt since this silently breaks +// argument parsing. +static cl::opt PreallocMemory("preallocate", cl::desc("Allocate memory upfront rather than on-demand"), cl::init(0)); -static cl::opt +static cl::opt TargetAddrStart("target-addr-start", cl::desc("For -verify only: start of phony target address " "range."), cl::init(4096), // Start at "page 1" - no allocating at "null". cl::Hidden); -static cl::opt +static cl::opt TargetAddrEnd("target-addr-end", cl::desc("For -verify only: end of phony target address range."), cl::init(~0ULL), cl::Hidden); -static cl::opt +static cl::opt TargetSectionSep("target-section-sep", cl::desc("For -verify only: Separation between sections in " "phony target address space."), @@ -577,7 +582,11 @@ if (LoadAddr && *LoadAddr != static_cast( reinterpret_cast(Tmp->first))) { - AlreadyAllocated[*LoadAddr] = Tmp->second; + // A section will have a LoadAddr of 0 if it wasn't loaded for whatever + // reason (e.g. zero byte COFF sections). Don't include those sections in + // the allocation map. + if (*LoadAddr != 0) + AlreadyAllocated[*LoadAddr] = Tmp->second; Worklist.erase(Tmp); } }