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()); - const SymbolStubMap &SymbolStubs = SI2->second; - auto SI3 = SymbolStubs.find(SymbolName); - if (SI3 == SymbolStubs.end()) + 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("")); +} + +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; }; }