]> granicus.if.org Git - llvm/commitdiff
Make llvm-rtdlyd -check preserve automatic address mappings made by RuntimeDyld.
authorLang Hames <lhames@gmail.com>
Sun, 7 May 2017 17:19:53 +0000 (17:19 +0000)
committerLang Hames <lhames@gmail.com>
Sun, 7 May 2017 17:19:53 +0000 (17:19 +0000)
Currently llvm-rtdyld in -check mode will map sections to back-to-back 4k
aligned slabs starting at 0x1000. Automatically remapping sections by default is
helpful because it quickly exposes relocation bugs due to use of local addresses
rather than load addresses (these would silently pass if the load address was
not remapped). These mappings can be explicitly overridden on a per-section
basis using llvm-rtdlyd's -map-section option. This patch extends this scheme to
also preserve any mappings made by RuntimeDyld itself. Preserving RuntimeDyld's
automatic mappings allows us to write test cases to verify that these automatic
mappings have been applied.

This will allow the fix in https://reviews.llvm.org/D32899 to be tested with
llvm-rtdyld -check.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302372 91177308-0d34-0410-b5e6-96231b3b80d8

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

index f5f52b5d2f9226e9aa96208d43bc44090f92b1c7..de89f405af4c4b15d7e29525c6445861ff7385f2 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
 
+#include "llvm/ADT/Optional.h"
+
 #include <cstdint>
 #include <memory>
 #include <string>
@@ -97,6 +99,10 @@ public:
                                                   StringRef SectionName,
                                                   bool LocalAddress);
 
+  /// \brief If there is a section at the given local address, return its load
+  ///        address, otherwise return none.
+  Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
+
 private:
   std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
 };
index 7bfa79445584902bd2eaee6491c2f7c9e732f6a4..e45fdc7aee18ad69b46c6bdf285554663bf5233c 100644 (file)
@@ -861,6 +861,15 @@ RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
                        SymInfo.getOffset());
 }
 
+Optional<uint64_t>
+RuntimeDyldCheckerImpl::getSectionLoadAddress(void *LocalAddress) const {
+  for (auto &S : getRTDyld().Sections) {
+    if (S.getAddress() == LocalAddress)
+      return S.getLoadAddress();
+  }
+  return Optional<uint64_t>();
+}
+
 void RuntimeDyldCheckerImpl::registerSection(
     StringRef FilePath, unsigned SectionID) {
   StringRef FileName = sys::path::filename(FilePath);
@@ -935,3 +944,8 @@ RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
                                    bool LocalAddress) {
   return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
 }
+
+Optional<uint64_t>
+RuntimeDyldChecker::getSectionLoadAddress(void *LocalAddress) const {
+  return Impl->getSectionLoadAddress(LocalAddress);
+}
index b7263be09934aaa6f5115d52d0aa15f3fb5bf7d9..b462ef2c00cee6762a93bdec602640528115735e 100644 (file)
@@ -60,6 +60,8 @@ private:
                                                   bool IsInsideLoad) const;
   StringRef getSubsectionStartingAt(StringRef Name) const;
 
+  Optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const;
+
   void registerSection(StringRef FilePath, unsigned SectionID);
   void registerStubMap(StringRef FilePath, unsigned SectionID,
                        const RuntimeDyldImpl::StubMap &RTDyldStubs);
index 4e1caa0400f1e024ae357b97ca23d407e2ffd82e..75345de5028039e43515ff9053778c4949550388 100644 (file)
@@ -486,10 +486,7 @@ static int checkAllExpressions(RuntimeDyldChecker &Checker) {
   return 0;
 }
 
-static std::map<void *, uint64_t>
-applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
-
-  std::map<void*, uint64_t> SpecificMappings;
+void applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
 
   for (StringRef Mapping : SpecificSectionMappings) {
 
@@ -522,10 +519,7 @@ applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
                          "'.");
 
     Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
-    SpecificMappings[OldAddr] = NewAddr;
   }
-
-  return SpecificMappings;
 }
 
 // Scatter sections in all directions!
@@ -554,8 +548,7 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
 
   // Apply any section-specific mappings that were requested on the command
   // line.
-  typedef std::map<void*, uint64_t> AppliedMappingsT;
-  AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);
+  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
@@ -563,15 +556,19 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
   // minimum separation.
   std::map<uint64_t, uint64_t> AlreadyAllocated;
 
-  // Move the previously applied mappings into the already-allocated map.
+  // Move the previously applied mappings (whether explicitly specified on the
+  // command line, or implicitly set by RuntimeDyld) 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);
+    auto LoadAddr = Checker.getSectionLoadAddress(Tmp->first);
 
-    if (AI != AppliedMappings.end()) {
-      AlreadyAllocated[AI->second] = Tmp->second;
+    if (LoadAddr &&
+        *LoadAddr != static_cast<uint64_t>(
+                       reinterpret_cast<uintptr_t>(Tmp->first))) {
+      AlreadyAllocated[*LoadAddr] = Tmp->second;
       Worklist.erase(Tmp);
     }
   }