[llvm] r217122 - [MCJIT] Add command-line argument to llvm-rtdyld to specify target addresses for

Lang Hames lhames at gmail.com
Wed Sep 3 21:19:54 PDT 2014


Author: lhames
Date: Wed Sep  3 23:19:54 2014
New Revision: 217122

URL: http://llvm.org/viewvc/llvm-project?rev=217122&view=rev
Log:
[MCJIT] Add command-line argument to llvm-rtdyld to specify target addresses for
sections.

This allows fine-grained control of the memory layout of hypothetical target
processes for testing purposes.


Modified:
    llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
    llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp

Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h?rev=217122&r1=217121&r2=217122&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h Wed Sep  3 23:19:54 2014
@@ -67,6 +67,12 @@ public:
                      MCInstPrinter *InstPrinter, raw_ostream &ErrStream);
   ~RuntimeDyldChecker();
 
+  // \brief Get the associated RTDyld instance.
+  RuntimeDyld& getRTDyld();
+
+  // \brief Get the associated RTDyld instance.
+  const RuntimeDyld& getRTDyld() const;
+
   /// \brief Check a single expression against the attached RuntimeDyld
   ///        instance.
   bool check(StringRef CheckExpr) const;
@@ -76,6 +82,16 @@ public:
   ///        method to be evaluated as an expression.
   bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
 
+  /// \brief Returns the address of the requested section (or an error message
+  ///        in the second element of the pair if the address cannot be found).
+  ///
+  /// if 'LinkerAddress' is true, this returns the address of the section
+  /// within the linker's memory. If 'LinkerAddress' is false it returns the
+  /// address within the target process (i.e. the load address).
+  std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
+                                                  StringRef SectionName,
+                                                  bool LinkerAddress);
+
 private:
   std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
 };

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=217122&r1=217121&r2=217122&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Sep  3 23:19:54 2014
@@ -695,6 +695,10 @@ void RuntimeDyldImpl::reassignSectionAdd
   // Addr is a uint64_t because we can't assume the pointer width
   // of the target is the same as that of the host. Just use a generic
   // "big enough" type.
+  DEBUG(dbgs() << "Reassigning address for section "
+               << SectionID << " (" << Sections[SectionID].Name << "): "
+               << format("0x%016x", Sections[SectionID].LoadAddress) << " -> "
+               << format("0x%016x", Addr) << "\n");
   Sections[SectionID].LoadAddress = Addr;
 }
 

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp?rev=217122&r1=217121&r2=217122&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp Wed Sep  3 23:19:54 2014
@@ -905,6 +905,14 @@ RuntimeDyldChecker::RuntimeDyldChecker(R
 
 RuntimeDyldChecker::~RuntimeDyldChecker() {}
 
+RuntimeDyld& RuntimeDyldChecker::getRTDyld() {
+  return Impl->RTDyld;
+}
+
+const RuntimeDyld& RuntimeDyldChecker::getRTDyld() const {
+  return Impl->RTDyld;
+}
+
 bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
   return Impl->check(CheckExpr);
 }
@@ -913,3 +921,9 @@ bool RuntimeDyldChecker::checkAllRulesIn
                                                MemoryBuffer *MemBuf) const {
   return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
 }
+
+std::pair<uint64_t, std::string>
+RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
+                                   bool LinkerAddress) {
+  return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
+}

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h?rev=217122&r1=217121&r2=217122&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h Wed Sep  3 23:19:54 2014
@@ -16,6 +16,7 @@
 namespace llvm {
 
 class RuntimeDyldCheckerImpl {
+  friend class RuntimeDyldChecker;
   friend class RuntimeDyldImpl;
   friend class RuntimeDyldCheckerExprEval;
 

Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=217122&r1=217121&r2=217122&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Wed Sep  3 23:19:54 2014
@@ -34,6 +34,7 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
+#include <list>
 #include <system_error>
 
 using namespace llvm;
@@ -98,6 +99,11 @@ TargetSectionSep("target-section-sep",
                  cl::init(0),
                  cl::Hidden);
 
+static cl::list<std::string>
+SpecificSectionMappings("map-section",
+                        cl::desc("Map a section to a specific address."),
+                        cl::ZeroOrMore);
+
 /* *** */
 
 // A trivial memory manager that doesn't do anything fancy, just uses the
@@ -320,6 +326,53 @@ static int checkAllExpressions(RuntimeDy
   return 0;
 }
 
+std::map<void*, uint64_t>
+applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
+
+  std::map<void*, uint64_t> SpecificMappings;
+
+  for (StringRef Mapping : SpecificSectionMappings) {
+
+    size_t EqualsIdx = Mapping.find_first_of("=");
+    StringRef SectionIDStr = Mapping.substr(0, EqualsIdx);
+    size_t ComaIdx = Mapping.find_first_of(",");
+
+    if (ComaIdx == StringRef::npos) {
+      errs() << "Invalid section specification '" << Mapping
+             << "'. Should be '<file name>,<section name>=<addr>'\n";
+      exit(1);
+    }
+
+    StringRef FileName = SectionIDStr.substr(0, ComaIdx);
+    StringRef SectionName = SectionIDStr.substr(ComaIdx + 1);
+
+    uint64_t OldAddrInt;
+    std::string ErrorMsg;
+    std::tie(OldAddrInt, ErrorMsg) =
+      Checker.getSectionAddr(FileName, SectionName, true);
+
+    if (ErrorMsg != "") {
+      errs() << ErrorMsg;
+      exit(1);
+    }
+
+    void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt));
+
+    StringRef NewAddrStr = Mapping.substr(EqualsIdx + 1);
+    uint64_t NewAddr;
+
+    if (NewAddrStr.getAsInteger(0, NewAddr)) {
+      errs() << "Invalid section address in mapping: " << Mapping << "\n";
+      exit(1);
+    }
+
+    Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
+    SpecificMappings[OldAddr] = NewAddr;
+  }
+
+  return SpecificMappings;
+}
+
 // 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
@@ -333,7 +386,40 @@ static int checkAllExpressions(RuntimeDy
 //
 void remapSections(const llvm::Triple &TargetTriple,
                    const TrivialMemoryManager &MemMgr,
-                   RuntimeDyld &RTDyld) {
+                   RuntimeDyldChecker &Checker) {
+
+  // Set up a work list (section addr/size pairs).
+  typedef std::list<std::pair<void*, uint64_t>> WorklistT;
+  WorklistT Worklist;
+
+  for (const auto& CodeSection : MemMgr.FunctionMemory)
+    Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size()));
+  for (const auto& DataSection : MemMgr.DataMemory)
+    Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size()));
+
+  // Apply any section-specific mappings that were requested on the command
+  // line.
+  typedef std::map<void*, uint64_t> AppliedMappingsT;
+  AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);
+
+  // Keep an "already allocated" mapping of section target addresses to sizes.
+  // Sections whose address mappings aren't specified on the command line will
+  // allocated around the explicitly mapped sections while maintaining the
+  // minimum separation.
+  std::map<uint64_t, uint64_t> AlreadyAllocated;
+
+  // Move the previously applied mappings into the already-allocated map.
+  for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
+       I != E;) {
+    WorklistT::iterator Tmp = I;
+    ++I;
+    AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first);
+
+    if (AI != AppliedMappings.end()) {
+      AlreadyAllocated[AI->second] = Tmp->second;
+      Worklist.erase(Tmp);
+    }
+  }
 
   // If the -target-addr-end option wasn't explicitly passed, then set it to a
   // sensible default based on the target triple.
@@ -346,19 +432,23 @@ void remapSections(const llvm::Triple &T
     // there's nothing to do in the 64-bit case.
   }
 
-  uint64_t NextSectionAddress = TargetAddrStart;
+  // Process any elements remaining in the worklist.
+  while (!Worklist.empty()) {
+    std::pair<void*, uint64_t> CurEntry = Worklist.front();
+    Worklist.pop_front();
+
+    uint64_t NextSectionAddr = TargetAddrStart;
+
+    for (const auto &Alloc : AlreadyAllocated)
+      if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first)
+        break;
+      else
+        NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;
 
-  // Remap code sections.
-  for (const auto& CodeSection : MemMgr.FunctionMemory) {
-    RTDyld.mapSectionAddress(CodeSection.base(), NextSectionAddress);
-    NextSectionAddress += CodeSection.size() + TargetSectionSep;
+    AlreadyAllocated[NextSectionAddr] = CurEntry.second;
+    Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr);
   }
 
-  // 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
@@ -435,7 +525,7 @@ static int linkAndVerify() {
   }
 
   // Re-map the section addresses into the phony target address space.
-  remapSections(TheTriple, MemMgr, Dyld);
+  remapSections(TheTriple, MemMgr, Checker);
 
   // Resolve all the relocations we can.
   Dyld.resolveRelocations();





More information about the llvm-commits mailing list