From: Lang Hames Date: Wed, 3 Sep 2014 05:01:46 +0000 (+0000) Subject: [MCJIT] Add a 'section_addr' builtin function to RuntimeDyldChecker. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=5ae26474052439a8ca557a7196a313fee773aa9c [MCJIT] Add a 'section_addr' builtin function to RuntimeDyldChecker. The syntax of the new builtin is 'section_addr(, )' (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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217010 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 537a683cd5f..d1b17ce94d8 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -550,6 +550,10 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, } Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); + + if (Checker) + Checker->registerSection(Obj.getImageName(), SectionID); + return SectionID; } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index aa4480226ac..c42287a480b 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -372,6 +372,43 @@ private: return std::make_pair(EvalResult(StubAddr), RemainingExpr); } + std::pair 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::readMemoryAtAddr(uint64_t SrcAddr, return getRTDyld().readBytesUnaligned(Src, Size); } -std::pair RuntimeDyldCheckerImpl::getStubAddrFor( - StringRef FileName, StringRef SectionName, StringRef SymbolName, - bool IsInsideLoad) const { - auto SI1 = Stubs.find(FileName); - if (SI1 == Stubs.end()) { +std::pair +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 RuntimeDyldCheckerImpl::getStubAddrFor( } } 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()); + + return std::make_pair(&SectionInfoItr->second, std::string("")); +} + +std::pair 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( + reinterpret_cast(getRTDyld().Sections[SectionID].Address)); + else + Addr = getRTDyld().Sections[SectionID].LoadAddress; + + return std::make_pair(Addr, std::string("")); +} - const SymbolStubMap &SymbolStubs = SI2->second; - auto SI3 = SymbolStubs.find(SymbolName); - if (SI3 == SymbolStubs.end()) +std::pair 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::getSubsectionStartingAt(StringRef Name) const { 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::registerStubMap( } if (SymbolName != "") - Stubs[FileName][SectionName][SymbolName] = - StubLoc(SectionID, StubMapEntry.second); + Stubs[FileName][SectionName].StubOffsets[SymbolName] = + StubMapEntry.second; } } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h index fd618651777..2c8d9a51318 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h @@ -28,19 +28,39 @@ public: bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const; private: + + // StubMap typedefs. + typedef std::map StubOffsetsMap; + struct SectionAddressInfo { + uint64_t SectionID; + StubOffsetsMap StubOffsets; + }; + typedef std::map SectionMap; + typedef std::map 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 getStubAddrFor(StringRef FilePath, + + std::pair findSectionAddrInfo( + StringRef FileName, + StringRef SectionName) const; + + std::pair getSectionAddr(StringRef FileName, + StringRef SectionName, + bool IsInsideLoad) const; + + std::pair 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 StubLoc; - typedef std::map SymbolStubMap; - typedef std::map SectionStubMap; - typedef std::map StubMap; StubMap Stubs; }; }