X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FExecutionEngine%2FRuntimeDyld%2FRuntimeDyldChecker.cpp;h=1e146338ee46bc4f5de1e340af190c2ff2df8e39;hp=308d80ef95e8620a1cc8b169462da2f27d8fe4f5;hb=51bd393f52d833d7c3542417f849217c125a539d;hpb=f072ab78ee3845725668c0ef8b4da598e1af9788 diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 308d80ef95e..1e146338ee4 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -12,7 +12,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" -#include "llvm/Support/StringRefMemoryObject.h" +#include "llvm/Support/Path.h" #include "RuntimeDyldCheckerImpl.h" #include "RuntimeDyldImpl.h" #include @@ -61,8 +61,8 @@ public: if (LHSResult.getValue() != RHSResult.getValue()) { Checker.ErrStream << "Expression '" << Expr << "' is false: " - << format("0x%lx", LHSResult.getValue()) - << " != " << format("0x%lx", RHSResult.getValue()) + << format("0x%" PRIx64, LHSResult.getValue()) + << " != " << format("0x%" PRIx64, RHSResult.getValue()) << "\n"; return false; } @@ -206,7 +206,7 @@ private: size_t FirstNonSymbol = Expr.find_first_not_of("0123456789" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - ":_."); + ":_.$"); return std::make_pair(Expr.substr(0, FirstNonSymbol), Expr.substr(FirstNonSymbol).ltrim()); } @@ -371,6 +371,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. @@ -387,6 +424,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 '"); @@ -523,6 +562,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); @@ -624,7 +667,9 @@ private: bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const { MCDisassembler *Dis = Checker.Disassembler; StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol); - StringRefMemoryObject SectionBytes(SectionMem, 0); + ArrayRef SectionBytes( + reinterpret_cast(SectionMem.data()), + SectionMem.size()); MCDisassembler::DecodeStatus S = Dis->getInstruction(Inst, Size, SectionBytes, 0, nulls(), nulls()); @@ -695,25 +740,26 @@ uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const { } uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const { - return getRTDyld().getAnySymbolRemoteAddress(Symbol); + if (uint64_t InternalSymbolAddr = getRTDyld().getSymbolLoadAddress(Symbol)) + return InternalSymbolAddr; + return getRTDyld().MemMgr->getSymbolAddress(Symbol); } uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr, unsigned Size) const { uintptr_t PtrSizedAddr = static_cast(SrcAddr); assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range."); - uint8_t *Src = reinterpret_cast(PtrSizedAddr); - uint64_t Result = 0; - memcpy(&Result, Src, Size); - return Result; + uint8_t *Src = reinterpret_cast(PtrSizedAddr); + 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. "; @@ -728,32 +774,75 @@ 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()); + ("Stub for symbol '" + SymbolName + "' not found. " + "If '" + SymbolName + "' is an internal symbol this " + "may indicate that the stub target offset is being " + "computed incorrectly.\n").str()); - unsigned SectionID = SI3->second.first; - uint64_t StubOffset = SI3->second.second; + uint64_t StubOffset = StubOffsetItr->second; uint64_t Addr; if (IsInsideLoad) { - uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress; - Addr = SectionBase + StubOffset; - } else { uintptr_t SectionBase = reinterpret_cast(getRTDyld().Sections[SectionID].Address); Addr = static_cast(SectionBase) + StubOffset; + } else { + uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress; + Addr = SectionBase + StubOffset; } return std::make_pair(Addr, std::string("")); @@ -771,11 +860,24 @@ 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; + + Stubs[FileName][SectionName].SectionID = SectionID; +} + void RuntimeDyldCheckerImpl::registerStubMap( - StringRef FileName, unsigned SectionID, + 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 = ""; @@ -787,7 +889,7 @@ void RuntimeDyldCheckerImpl::registerStubMap( for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) { if (GSTEntry.second.first == StubMapEntry.first.SectionID && GSTEntry.second.second == - static_cast(StubMapEntry.first.Addend)) { + static_cast(StubMapEntry.first.Offset)) { SymbolName = GSTEntry.first(); break; } @@ -795,8 +897,8 @@ void RuntimeDyldCheckerImpl::registerStubMap( } if (SymbolName != "") - Stubs[FileName][SectionName][SymbolName] = - StubLoc(SectionID, StubMapEntry.second); + Stubs[FileName][SectionName].StubOffsets[SymbolName] = + StubMapEntry.second; } } @@ -809,6 +911,14 @@ RuntimeDyldChecker::RuntimeDyldChecker(RuntimeDyld &RTDyld, 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); } @@ -817,3 +927,9 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const { return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf); } + +std::pair +RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName, + bool LinkerAddress) { + return Impl->getSectionAddr(FileName, SectionName, LinkerAddress); +}