[llvm] r217010 - [MCJIT] Add a 'section_addr' builtin function to RuntimeDyldChecker.

Lang Hames lhames at gmail.com
Tue Sep 2 22:01:47 PDT 2014


Author: lhames
Date: Wed Sep  3 00:01:46 2014
New Revision: 217010

URL: http://llvm.org/viewvc/llvm-project?rev=217010&view=rev
Log:
[MCJIT] Add a 'section_addr' builtin function to RuntimeDyldChecker.

The syntax of the new builtin is 'section_addr(<filename>, <section-name>)'
(similar to the stub_addr builtin, but without a symbol name). It returns the
base address of the given section in the given object file. This builtin makes
it possible to refer to the contents of sections that cannot contain symbols,
e.g. sections added by the linker itself, like __eh_frame.


Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=217010&r1=217009&r2=217010&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Sep  3 00:01:46 2014
@@ -550,6 +550,10 @@ unsigned RuntimeDyldImpl::emitSection(Ob
   }
 
   Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
+
+  if (Checker)
+    Checker->registerSection(Obj.getImageName(), SectionID);
+
   return SectionID;
 }
 

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp?rev=217010&r1=217009&r2=217010&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp Wed Sep  3 00:01:46 2014
@@ -372,6 +372,43 @@ private:
     return std::make_pair(EvalResult(StubAddr), RemainingExpr);
   }
 
+  std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr,
+                                                   ParseContext PCtx) const {
+    if (!Expr.startswith("("))
+      return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
+    StringRef RemainingExpr = Expr.substr(1).ltrim();
+
+    // Handle file-name specially, as it may contain characters that aren't
+    // legal for symbols.
+    StringRef FileName;
+    size_t ComaIdx = RemainingExpr.find(',');
+    FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
+    RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
+
+    if (!RemainingExpr.startswith(","))
+      return std::make_pair(
+          unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
+    RemainingExpr = RemainingExpr.substr(1).ltrim();
+
+    StringRef SectionName;
+    std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
+
+    if (!RemainingExpr.startswith(")"))
+      return std::make_pair(
+          unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
+    RemainingExpr = RemainingExpr.substr(1).ltrim();
+
+    uint64_t StubAddr;
+    std::string ErrorMsg = "";
+    std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
+        FileName, SectionName, PCtx.IsInsideLoad);
+
+    if (ErrorMsg != "")
+      return std::make_pair(EvalResult(ErrorMsg), "");
+
+    return std::make_pair(EvalResult(StubAddr), RemainingExpr);
+  }
+
   // Evaluate an identiefer expr, which may be a symbol, or a call to
   // one of the builtin functions: get_insn_opcode or get_insn_length.
   // Return the result, plus the expression remaining to be parsed.
@@ -388,6 +425,8 @@ private:
       return evalNextPC(RemainingExpr, PCtx);
     else if (Symbol == "stub_addr")
       return evalStubAddr(RemainingExpr, PCtx);
+    else if (Symbol == "section_addr")
+      return evalSectionAddr(RemainingExpr, PCtx);
 
     if (!Checker.isSymbolValid(Symbol)) {
       std::string ErrMsg("No known address for symbol '");
@@ -524,6 +563,10 @@ private:
       std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
     else if (isdigit(Expr[0]))
       std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
+    else
+      return std::make_pair(
+          unexpectedToken(Expr, Expr,
+                          "expected '(', '*', identifier, or number"), "");
 
     if (SubExprResult.hasError())
       return std::make_pair(SubExprResult, RemainingExpr);
@@ -707,12 +750,13 @@ uint64_t RuntimeDyldCheckerImpl::readMem
   return getRTDyld().readBytesUnaligned(Src, Size);
 }
 
-std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
-    StringRef FileName, StringRef SectionName, StringRef SymbolName,
-    bool IsInsideLoad) const {
 
-  auto SI1 = Stubs.find(FileName);
-  if (SI1 == Stubs.end()) {
+std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
+RuntimeDyldCheckerImpl::findSectionAddrInfo(StringRef FileName,
+                                            StringRef SectionName) const {
+
+  auto SectionMapItr = Stubs.find(FileName);
+  if (SectionMapItr == Stubs.end()) {
     std::string ErrorMsg = "File '";
     ErrorMsg += FileName;
     ErrorMsg += "' not found. ";
@@ -727,23 +771,63 @@ std::pair<uint64_t, std::string> Runtime
       }
     }
     ErrorMsg += "\n";
-    return std::make_pair(0, ErrorMsg);
+    return std::make_pair(nullptr, ErrorMsg);
   }
 
-  const SectionStubMap &SectionStubs = SI1->second;
-  auto SI2 = SectionStubs.find(SectionName);
-  if (SI2 == SectionStubs.end())
-    return std::make_pair(0,
-                          ("Section '" + SectionName + "' not found.\n").str());
+  auto SectionInfoItr = SectionMapItr->second.find(SectionName);
+  if (SectionInfoItr == SectionMapItr->second.end())
+    return std::make_pair(nullptr,
+                          ("Section '" + SectionName + "' not found in file '" +
+                           FileName + "'\n").str());
 
-  const SymbolStubMap &SymbolStubs = SI2->second;
-  auto SI3 = SymbolStubs.find(SymbolName);
-  if (SI3 == SymbolStubs.end())
+  return std::make_pair(&SectionInfoItr->second, std::string(""));
+}
+
+std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
+    StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
+
+  const SectionAddressInfo *SectionInfo = nullptr;
+  {
+    std::string ErrorMsg;
+    std::tie(SectionInfo, ErrorMsg) =
+      findSectionAddrInfo(FileName, SectionName);
+    if (ErrorMsg != "")
+      return std::make_pair(0, ErrorMsg);
+  }
+
+  unsigned SectionID = SectionInfo->SectionID;
+  uint64_t Addr;
+  if (IsInsideLoad)
+    Addr =
+      static_cast<uint64_t>(
+        reinterpret_cast<uintptr_t>(getRTDyld().Sections[SectionID].Address));
+  else
+    Addr = getRTDyld().Sections[SectionID].LoadAddress;
+
+  return std::make_pair(Addr, std::string(""));
+}
+
+std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
+    StringRef FileName, StringRef SectionName, StringRef SymbolName,
+    bool IsInsideLoad) const {
+
+  const SectionAddressInfo *SectionInfo = nullptr;
+  {
+    std::string ErrorMsg;
+    std::tie(SectionInfo, ErrorMsg) =
+      findSectionAddrInfo(FileName, SectionName);
+    if (ErrorMsg != "")
+      return std::make_pair(0, ErrorMsg);
+  }
+
+  unsigned SectionID = SectionInfo->SectionID;
+  const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
+  auto StubOffsetItr = SymbolStubs.find(SymbolName);
+  if (StubOffsetItr == SymbolStubs.end())
     return std::make_pair(0,
                           ("Symbol '" + SymbolName + "' not found.\n").str());
 
-  unsigned SectionID = SI3->second.first;
-  uint64_t StubOffset = SI3->second.second;
+  uint64_t StubOffset = StubOffsetItr->second;
 
   uint64_t Addr;
   if (IsInsideLoad) {
@@ -770,12 +854,25 @@ RuntimeDyldCheckerImpl::getSubsectionSta
                    getRTDyld().Sections[Loc.first].Size - Loc.second);
 }
 
+void RuntimeDyldCheckerImpl::registerSection(
+    StringRef FilePath, unsigned SectionID) {
+  StringRef FileName = sys::path::filename(FilePath);
+  const SectionEntry &Section = getRTDyld().Sections[SectionID];
+  StringRef SectionName = Section.Name;
+
+  dbgs() << "Registering " << SectionName << "\n";
+  Stubs[FileName][SectionName].SectionID = SectionID;
+}
+
 void RuntimeDyldCheckerImpl::registerStubMap(
     StringRef FilePath, unsigned SectionID,
     const RuntimeDyldImpl::StubMap &RTDyldStubs) {
   StringRef FileName = sys::path::filename(FilePath);
   const SectionEntry &Section = getRTDyld().Sections[SectionID];
   StringRef SectionName = Section.Name;
+
+  Stubs[FileName][SectionName].SectionID = SectionID;
+
   for (auto &StubMapEntry : RTDyldStubs) {
     std::string SymbolName = "";
 
@@ -795,8 +892,8 @@ void RuntimeDyldCheckerImpl::registerStu
     }
 
     if (SymbolName != "")
-      Stubs[FileName][SectionName][SymbolName] =
-          StubLoc(SectionID, StubMapEntry.second);
+      Stubs[FileName][SectionName].StubOffsets[SymbolName] =
+        StubMapEntry.second;
   }
 }
 

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h?rev=217010&r1=217009&r2=217010&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h Wed Sep  3 00:01:46 2014
@@ -28,19 +28,39 @@ public:
   bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
 
 private:
+
+  // StubMap typedefs.
+  typedef std::map<std::string, uint64_t> StubOffsetsMap;
+  struct SectionAddressInfo {
+    uint64_t SectionID;
+    StubOffsetsMap StubOffsets;
+  };
+  typedef std::map<std::string, SectionAddressInfo> SectionMap;
+  typedef std::map<std::string, SectionMap> StubMap;
+
   RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
 
   bool isSymbolValid(StringRef Symbol) const;
   uint64_t getSymbolLinkerAddr(StringRef Symbol) const;
   uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
   uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
-  std::pair<uint64_t, std::string> getStubAddrFor(StringRef FilePath,
+
+  std::pair<const SectionAddressInfo*, std::string> findSectionAddrInfo(
+                                                   StringRef FileName,
+                                                   StringRef SectionName) const;
+
+  std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
+                                                  StringRef SectionName,
+                                                  bool IsInsideLoad) const;
+
+  std::pair<uint64_t, std::string> getStubAddrFor(StringRef FileName,
                                                   StringRef SectionName,
                                                   StringRef Symbol,
                                                   bool IsInsideLoad) const;
   StringRef getSubsectionStartingAt(StringRef Name) const;
 
-  void registerStubMap(StringRef FileName, unsigned SectionID,
+  void registerSection(StringRef FilePath, unsigned SectionID);
+  void registerStubMap(StringRef FilePath, unsigned SectionID,
                        const RuntimeDyldImpl::StubMap &RTDyldStubs);
 
   RuntimeDyld &RTDyld;
@@ -48,11 +68,6 @@ private:
   MCInstPrinter *InstPrinter;
   llvm::raw_ostream &ErrStream;
 
-  // StubMap typedefs.
-  typedef std::pair<unsigned, uint64_t> StubLoc;
-  typedef std::map<std::string, StubLoc> SymbolStubMap;
-  typedef std::map<std::string, SymbolStubMap> SectionStubMap;
-  typedef std::map<std::string, SectionStubMap> StubMap;
   StubMap Stubs;
 };
 }





More information about the llvm-commits mailing list