]> granicus.if.org Git - llvm/commitdiff
[MCJIT] Add options to llvm-rtdyld to describe a phony target address space for
authorLang Hames <lhames@gmail.com>
Tue, 29 Jul 2014 23:43:13 +0000 (23:43 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 29 Jul 2014 23:43:13 +0000 (23:43 +0000)
use in -verify mode.

This patch adds three hidden command line options to llvm-rtdyld:

 -target-addr-start <start-addr> : Specify the start of the virtual address
                                   space on the phony target.

 -target-addr-end   <end-addr>   : Specify the end of the virtual address space
                                   on the phony target.

 -target-section-sep <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

lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
tools/llvm-rtdyld/llvm-rtdyld.cpp

index 9873897f69182c240dd07cdba1fe1e82392b3dd7..d244f45b0803b767481b5d703acfca9aaa865ca0 100644 (file)
@@ -749,12 +749,12 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
 
   uint64_t Addr;
   if (IsInsideLoad) {
-    uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress;
-    Addr = SectionBase + StubOffset;
-  } else {
     uintptr_t SectionBase =
         reinterpret_cast<uintptr_t>(getRTDyld().Sections[SectionID].Address);
     Addr = static_cast<uint64_t>(SectionBase) + StubOffset;
+  } else {
+    uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress;
+    Addr = SectionBase + StubOffset;
   }
 
   return std::make_pair(Addr, std::string(""));
index 0bed9df980027b218a3ff677ac5c1021d8d6f964..5cea4658363fa3ab561b8d109e3a88d670c17b91 100644 (file)
@@ -78,6 +78,26 @@ CheckFiles("check",
            cl::desc("File containing RuntimeDyld verifier checks."),
            cl::ZeroOrMore);
 
+static cl::opt<uint64_t>
+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<uint64_t>
+TargetAddrEnd("target-addr-end",
+              cl::desc("For -verify only: end of phony target address range."),
+              cl::init(~0ULL),
+              cl::Hidden);
+
+static cl::opt<uint64_t>
+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 <s> -- Specify where the phony target addres range starts.
+// -target-addr-end   <e> -- Specify where the phony target address range ends.
+// -target-section-sep <d> -- 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.