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.
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 '");
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);
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. ";
}
}
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<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(""));
+}
- const SymbolStubMap &SymbolStubs = SI2->second;
- auto SI3 = SymbolStubs.find(SymbolName);
- if (SI3 == SymbolStubs.end())
+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) {
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 = "";
}
if (SymbolName != "")
- Stubs[FileName][SectionName][SymbolName] =
- StubLoc(SectionID, StubMapEntry.second);
+ Stubs[FileName][SectionName].StubOffsets[SymbolName] =
+ StubMapEntry.second;
}
}
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;
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;
};
}