From: Lang Hames Date: Tue, 29 Jul 2014 23:43:13 +0000 (+0000) Subject: [MCJIT] Add options to llvm-rtdyld to describe a phony target address space for X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=41364b7d5420aecf266cda68552fe05b61ebb847 [MCJIT] Add options to llvm-rtdyld to describe a phony target address space for use in -verify mode. This patch adds three hidden command line options to llvm-rtdyld: -target-addr-start : Specify the start of the virtual address space on the phony target. -target-addr-end : Specify the end of the virtual address space on the phony target. -target-section-sep : Specify the separation (in bytes) between the end of one section and the start of the next. These options automatically default to sane values for the target platform. In particular, they allow narrow (e.g. 32-bit, 16-bit) targets to be tested from wider (e.g. 64-bit, 32-bit) hosts without overflowing pointers. The section separation option defaults to zero, but can be set to a large number (e.g. 1 << 32) to force large separations between sections in order to stress-test large-code-model code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214255 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 9873897f691..d244f45b080 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -749,12 +749,12 @@ std::pair RuntimeDyldCheckerImpl::getStubAddrFor( uint64_t Addr; if (IsInsideLoad) { - uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress; - Addr = SectionBase + StubOffset; - } else { uintptr_t SectionBase = reinterpret_cast(getRTDyld().Sections[SectionID].Address); Addr = static_cast(SectionBase) + StubOffset; + } else { + uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress; + Addr = SectionBase + StubOffset; } return std::make_pair(Addr, std::string("")); diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 0bed9df9800..5cea4658363 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -78,6 +78,26 @@ CheckFiles("check", cl::desc("File containing RuntimeDyld verifier checks."), cl::ZeroOrMore); +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 +TargetAddrEnd("target-addr-end", + cl::desc("For -verify only: end of phony target address range."), + cl::init(~0ULL), + cl::Hidden); + +static cl::opt +TargetSectionSep("target-section-sep", + cl::desc("For -verify only: Separation between sections in " + "phony target address space."), + cl::init(0), + cl::Hidden); + /* *** */ // A trivial memory manager that doesn't do anything fancy, just uses the @@ -300,6 +320,50 @@ static int checkAllExpressions(RuntimeDyldChecker &Checker) { return 0; } +// Scatter sections in all directions! +// Remaps section addresses for -verify mode. The following command line options +// can be used to customize the layout of the memory within the phony target's +// address space: +// -target-addr-start -- Specify where the phony target addres range starts. +// -target-addr-end -- Specify where the phony target address range ends. +// -target-section-sep -- Specify how big a gap should be left between the +// end of one section and the start of the next. +// Defaults to zero. Set to something big +// (e.g. 1 << 32) to stress-test stubs, GOTs, etc. +// +void remapSections(const llvm::Triple &TargetTriple, + const TrivialMemoryManager &MemMgr, + RuntimeDyld &RTDyld) { + + // If the -target-addr-end option wasn't explicitly passed, then set it to a + // sensible default based on the target triple. + if (TargetAddrEnd.getNumOccurrences() == 0) { + if (TargetTriple.isArch16Bit()) + TargetAddrEnd = (1ULL << 16) - 1; + else if (TargetTriple.isArch32Bit()) + TargetAddrEnd = (1ULL << 32) - 1; + // TargetAddrEnd already has a sensible default for 64-bit systems, so + // there's nothing to do in the 64-bit case. + } + + uint64_t NextSectionAddress = TargetAddrStart; + + // Remap code sections. + for (const auto& CodeSection : MemMgr.FunctionMemory) { + RTDyld.mapSectionAddress(CodeSection.base(), NextSectionAddress); + NextSectionAddress += CodeSection.size() + TargetSectionSep; + } + + // Remap data sections. + for (const auto& DataSection : MemMgr.DataMemory) { + RTDyld.mapSectionAddress(DataSection.base(), NextSectionAddress); + NextSectionAddress += DataSection.size() + TargetSectionSep; + } +} + +// Load and link the objects specified on the command line, but do not execute +// anything. Instead, attach a RuntimeDyldChecker instance and call it to +// verify the correctness of the linked memory. static int linkAndVerify() { // Check for missing triple.