forked from OSchip/llvm-project
[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. llvm-svn: 217010
This commit is contained in:
parent
33a2a2ed1a
commit
587ee6ab4f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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::readMemoryAtAddr(uint64_t SrcAddr,
|
|||
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> 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<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::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue