21 #define DEBUG_TYPE "rtdyld"
37 size_t EQIdx = Expr.
find(
'=');
39 ParseContext OutsideLoad(
false);
45 std::tie(LHSResult, RemainingExpr) =
46 evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);
47 if (LHSResult.hasError())
48 return handleError(Expr, LHSResult);
49 if (RemainingExpr !=
"")
50 return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr,
""));
55 std::tie(RHSResult, RemainingExpr) =
56 evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);
57 if (RHSResult.hasError())
58 return handleError(Expr, RHSResult);
59 if (RemainingExpr !=
"")
60 return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr,
""));
62 if (LHSResult.getValue() != RHSResult.getValue()) {
63 Checker.ErrStream <<
"Expression '" << Expr <<
"' is false: "
64 <<
format(
"0x%" PRIx64, LHSResult.getValue())
65 <<
" != " <<
format(
"0x%" PRIx64, RHSResult.getValue())
81 ParseContext(
bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
98 EvalResult() :
Value(0), ErrorMsg(
"") {}
99 EvalResult(uint64_t
Value) : Value(Value), ErrorMsg(
"") {}
100 EvalResult(std::string ErrorMsg) :
Value(0), ErrorMsg(ErrorMsg) {}
101 uint64_t getValue()
const {
return Value; }
102 bool hasError()
const {
return ErrorMsg !=
""; }
103 const std::string &getErrorMsg()
const {
return ErrorMsg; }
107 std::string ErrorMsg;
115 if (isalpha(Expr[0]))
116 std::tie(Token, Remaining) = parseSymbol(Expr);
117 else if (isdigit(Expr[0]))
118 std::tie(Token, Remaining) = parseNumberString(Expr);
123 Token = Expr.
substr(0, TokLen);
130 std::string ErrorMsg(
"Encountered unexpected token '");
131 ErrorMsg += getTokenForError(TokenStart);
133 ErrorMsg +=
"' while parsing subexpression '";
141 return EvalResult(std::move(ErrorMsg));
144 bool handleError(
StringRef Expr,
const EvalResult &R)
const {
145 assert(R.hasError() &&
"Not an error result.");
146 Checker.ErrStream <<
"Error evaluating expression '" << Expr
147 <<
"': " << R.getErrorMsg() <<
"\n";
151 std::pair<BinOpToken, StringRef> parseBinOpToken(
StringRef Expr)
const {
183 EvalResult computeBinOpResult(BinOpToken Op,
const EvalResult &LHSResult,
184 const EvalResult &RHSResult)
const {
189 return EvalResult(LHSResult.getValue() + RHSResult.getValue());
191 return EvalResult(LHSResult.getValue() - RHSResult.getValue());
193 return EvalResult(LHSResult.getValue() & RHSResult.getValue());
195 return EvalResult(LHSResult.getValue() | RHSResult.getValue());
197 return EvalResult(LHSResult.getValue() << RHSResult.getValue());
199 return EvalResult(LHSResult.getValue() >> RHSResult.getValue());
205 std::pair<StringRef, StringRef> parseSymbol(
StringRef Expr)
const {
207 "abcdefghijklmnopqrstuvwxyz"
208 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
210 return std::make_pair(Expr.
substr(0, FirstNonSymbol),
220 std::pair<EvalResult, StringRef> evalDecodeOperand(
StringRef Expr)
const {
222 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
225 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
227 if (!Checker.isSymbolValid(Symbol))
228 return std::make_pair(
229 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
233 return std::make_pair(
234 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ','"),
"");
237 EvalResult OpIdxExpr;
238 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
239 if (OpIdxExpr.hasError())
240 return std::make_pair(OpIdxExpr,
"");
243 return std::make_pair(
244 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
249 if (!decodeInst(Symbol, Inst, Size))
250 return std::make_pair(
251 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
254 unsigned OpIdx = OpIdxExpr.getValue();
258 ErrMsgStream <<
"Invalid operand index '" <<
format(
"%i", OpIdx)
259 <<
"' for instruction '" << Symbol
260 <<
"'. Instruction has only "
262 <<
" operands.\nInstruction is:\n ";
263 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
264 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
271 ErrMsgStream <<
"Operand '" <<
format(
"%i", OpIdx) <<
"' of instruction '"
272 << Symbol <<
"' is not an immediate.\nInstruction is:\n ";
273 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
275 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
278 return std::make_pair(EvalResult(Op.
getImm()), RemainingExpr);
287 std::pair<EvalResult, StringRef> evalNextPC(
StringRef Expr,
288 ParseContext PCtx)
const {
290 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
293 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
295 if (!Checker.isSymbolValid(Symbol))
296 return std::make_pair(
297 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
301 return std::make_pair(
302 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
307 if (!decodeInst(Symbol, Inst, InstSize))
308 return std::make_pair(
309 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
312 uint64_t SymbolAddr = PCtx.IsInsideLoad
313 ? Checker.getSymbolLocalAddr(Symbol)
314 : Checker.getSymbolRemoteAddr(Symbol);
315 uint64_t NextPC = SymbolAddr + InstSize;
317 return std::make_pair(EvalResult(NextPC), RemainingExpr);
325 std::pair<EvalResult, StringRef> evalStubAddr(
StringRef Expr,
326 ParseContext PCtx)
const {
328 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
334 size_t ComaIdx = RemainingExpr.
find(
',');
335 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
336 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
339 return std::make_pair(
340 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
344 std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
347 return std::make_pair(
348 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
352 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
355 return std::make_pair(
356 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
360 std::string ErrorMsg =
"";
361 std::tie(StubAddr, ErrorMsg) = Checker.getStubAddrFor(
362 FileName, SectionName, Symbol, PCtx.IsInsideLoad);
365 return std::make_pair(EvalResult(ErrorMsg),
"");
367 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
370 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
371 ParseContext PCtx)
const {
373 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
379 size_t ComaIdx = RemainingExpr.
find(
',');
380 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
381 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
384 return std::make_pair(
385 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
389 std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
392 return std::make_pair(
393 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
397 std::string ErrorMsg =
"";
398 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
399 FileName, SectionName, PCtx.IsInsideLoad);
402 return std::make_pair(EvalResult(ErrorMsg),
"");
404 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
410 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
411 ParseContext PCtx)
const {
414 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
417 if (Symbol ==
"decode_operand")
418 return evalDecodeOperand(RemainingExpr);
419 else if (Symbol ==
"next_pc")
420 return evalNextPC(RemainingExpr, PCtx);
421 else if (Symbol ==
"stub_addr")
422 return evalStubAddr(RemainingExpr, PCtx);
423 else if (Symbol ==
"section_addr")
424 return evalSectionAddr(RemainingExpr, PCtx);
426 if (!Checker.isSymbolValid(Symbol)) {
427 std::string ErrMsg(
"No known address for symbol '");
431 ErrMsg +=
" (this appears to be an assembler local label - "
432 " perhaps drop the 'L'?)";
434 return std::make_pair(EvalResult(ErrMsg),
"");
440 uint64_t
Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
441 : Checker.getSymbolRemoteAddr(Symbol);
444 return std::make_pair(EvalResult(Value), RemainingExpr);
449 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
454 FirstNonDigit = Expr.
size();
458 FirstNonDigit = Expr.
size();
460 return std::make_pair(Expr.
substr(0, FirstNonDigit),
461 Expr.
substr(FirstNonDigit));
467 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
470 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
472 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
473 return std::make_pair(
474 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
477 return std::make_pair(EvalResult(Value), RemainingExpr);
483 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
484 ParseContext PCtx)
const {
485 assert(Expr.
startswith(
"(") &&
"Not a parenthesized expression");
486 EvalResult SubExprResult;
488 std::tie(SubExprResult, RemainingExpr) =
489 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
490 if (SubExprResult.hasError())
491 return std::make_pair(SubExprResult,
"");
493 return std::make_pair(
494 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
496 return std::make_pair(SubExprResult, RemainingExpr);
503 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
504 assert(Expr.
startswith(
"*") &&
"Not a load expression");
508 if (!RemainingExpr.startswith(
"{"))
509 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
511 EvalResult ReadSizeExpr;
512 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
513 if (ReadSizeExpr.hasError())
514 return std::make_pair(ReadSizeExpr, RemainingExpr);
515 uint64_t ReadSize = ReadSizeExpr.getValue();
516 if (ReadSize < 1 || ReadSize > 8)
517 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
518 if (!RemainingExpr.startswith(
"}"))
519 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
520 RemainingExpr = RemainingExpr.substr(1).ltrim();
523 ParseContext LoadCtx(
true);
524 EvalResult LoadAddrExprResult;
525 std::tie(LoadAddrExprResult, RemainingExpr) =
526 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
528 if (LoadAddrExprResult.hasError())
529 return std::make_pair(LoadAddrExprResult,
"");
531 uint64_t LoadAddr = LoadAddrExprResult.getValue();
533 return std::make_pair(
534 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
545 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
546 ParseContext PCtx)
const {
547 EvalResult SubExprResult;
551 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
554 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
555 else if (Expr[0] ==
'*')
556 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
557 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
558 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
559 else if (isdigit(Expr[0]))
560 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
562 return std::make_pair(
563 unexpectedToken(Expr, Expr,
564 "expected '(', '*', identifier, or number"),
"");
566 if (SubExprResult.hasError())
567 return std::make_pair(SubExprResult, RemainingExpr);
571 std::tie(SubExprResult, RemainingExpr) =
572 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
574 return std::make_pair(SubExprResult, RemainingExpr);
584 std::pair<EvalResult, StringRef>
585 evalSliceExpr(std::pair<EvalResult, StringRef> Ctx)
const {
586 EvalResult SubExprResult;
588 std::tie(SubExprResult, RemainingExpr) = Ctx;
590 assert(RemainingExpr.
startswith(
"[") &&
"Not a slice expr.");
593 EvalResult HighBitExpr;
594 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
596 if (HighBitExpr.hasError())
597 return std::make_pair(HighBitExpr, RemainingExpr);
599 if (!RemainingExpr.startswith(
":"))
600 return std::make_pair(
601 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
602 RemainingExpr = RemainingExpr.substr(1).ltrim();
604 EvalResult LowBitExpr;
605 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
607 if (LowBitExpr.hasError())
608 return std::make_pair(LowBitExpr, RemainingExpr);
610 if (!RemainingExpr.startswith(
"]"))
611 return std::make_pair(
612 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
613 RemainingExpr = RemainingExpr.substr(1).ltrim();
615 unsigned HighBit = HighBitExpr.getValue();
616 unsigned LowBit = LowBitExpr.getValue();
617 uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;
618 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
619 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
628 std::pair<EvalResult, StringRef>
629 evalComplexExpr(std::pair<EvalResult, StringRef> LHSAndRemaining,
630 ParseContext PCtx)
const {
631 EvalResult LHSResult;
633 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
637 if (LHSResult.hasError() || RemainingExpr ==
"")
638 return std::make_pair(LHSResult, RemainingExpr);
642 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
646 return std::make_pair(LHSResult, RemainingExpr);
649 EvalResult RHSResult;
650 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
653 if (RHSResult.hasError())
654 return std::make_pair(RHSResult, RemainingExpr);
658 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
660 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
663 bool decodeInst(
StringRef Symbol,
MCInst &Inst, uint64_t &Size)
const {
665 StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol);
667 reinterpret_cast<const uint8_t *>(SectionMem.
data()),
682 : RTDyld(RTDyld), Disassembler(Disassembler), InstPrinter(InstPrinter),
683 ErrStream(ErrStream) {
684 RTDyld.Checker =
this;
688 CheckExpr = CheckExpr.
trim();
689 DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr <<
"'...\n");
691 bool Result = P.
evaluate(CheckExpr);
693 DEBUG(
dbgs() <<
"RuntimeDyldChecker: '" << CheckExpr <<
"' "
694 << (Result ?
"passed" :
"FAILED") <<
".\n");
700 bool DidAllTestsPass =
true;
701 unsigned NumRules = 0;
706 while (LineStart != MemBuf->
getBufferEnd() && std::isspace(*LineStart))
709 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
710 const char *LineEnd = LineStart;
711 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
715 StringRef Line(LineStart, LineEnd - LineStart);
723 while (LineStart != MemBuf->
getBufferEnd() && std::isspace(*LineStart))
726 return DidAllTestsPass && (NumRules != 0);
729 bool RuntimeDyldCheckerImpl::isSymbolValid(
StringRef Symbol)
const {
730 if (getRTDyld().getSymbolLocalAddress(Symbol))
735 uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(
StringRef Symbol)
const {
736 return static_cast<uint64_t
>(
740 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(
StringRef Symbol)
const {
741 if (
auto InternalSymbol = getRTDyld().getSymbol(Symbol))
746 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
747 unsigned Size)
const {
748 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
749 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
750 uint8_t *Src =
reinterpret_cast<uint8_t*
>(PtrSizedAddr);
755 std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
756 RuntimeDyldCheckerImpl::findSectionAddrInfo(
StringRef FileName,
759 auto SectionMapItr = Stubs.find(FileName);
760 if (SectionMapItr == Stubs.end()) {
761 std::string ErrorMsg =
"File '";
762 ErrorMsg += FileName;
763 ErrorMsg +=
"' not found. ";
765 ErrorMsg +=
"No stubs registered.";
767 ErrorMsg +=
"Available files are:";
768 for (
const auto& StubEntry : Stubs) {
770 ErrorMsg += StubEntry.first;
775 return std::make_pair(
nullptr, ErrorMsg);
778 auto SectionInfoItr = SectionMapItr->second.find(SectionName);
779 if (SectionInfoItr == SectionMapItr->second.end())
780 return std::make_pair(
nullptr,
781 (
"Section '" + SectionName +
"' not found in file '" +
782 FileName +
"'\n").str());
784 return std::make_pair(&SectionInfoItr->second, std::string(
""));
787 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
790 const SectionAddressInfo *SectionInfo =
nullptr;
792 std::string ErrorMsg;
793 std::tie(SectionInfo, ErrorMsg) =
794 findSectionAddrInfo(FileName, SectionName);
796 return std::make_pair(0, ErrorMsg);
799 unsigned SectionID = SectionInfo->SectionID;
803 static_cast<uint64_t
>(
804 reinterpret_cast<uintptr_t
>(getRTDyld().
Sections[SectionID].Address));
806 Addr = getRTDyld().
Sections[SectionID].LoadAddress;
808 return std::make_pair(Addr, std::string(
""));
811 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
813 bool IsInsideLoad)
const {
815 const SectionAddressInfo *SectionInfo =
nullptr;
817 std::string ErrorMsg;
818 std::tie(SectionInfo, ErrorMsg) =
819 findSectionAddrInfo(FileName, SectionName);
821 return std::make_pair(0, ErrorMsg);
824 unsigned SectionID = SectionInfo->SectionID;
825 const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
826 auto StubOffsetItr = SymbolStubs.find(SymbolName);
827 if (StubOffsetItr == SymbolStubs.end())
828 return std::make_pair(0,
829 (
"Stub for symbol '" + SymbolName +
"' not found. "
830 "If '" + SymbolName +
"' is an internal symbol this "
831 "may indicate that the stub target offset is being "
832 "computed incorrectly.\n").str());
834 uint64_t StubOffset = StubOffsetItr->second;
838 uintptr_t SectionBase =
839 reinterpret_cast<uintptr_t
>(getRTDyld().
Sections[SectionID].Address);
840 Addr =
static_cast<uint64_t
>(SectionBase) + StubOffset;
842 uint64_t SectionBase = getRTDyld().
Sections[SectionID].LoadAddress;
843 Addr = SectionBase + StubOffset;
846 return std::make_pair(Addr, std::string(
""));
850 RuntimeDyldCheckerImpl::getSubsectionStartingAt(
StringRef Name)
const {
853 if (pos == getRTDyld().GlobalSymbolTable.end())
855 const auto &SymInfo = pos->
second;
857 return StringRef(reinterpret_cast<const char *>(SectionAddr) +
859 getRTDyld().
Sections[SymInfo.getSectionID()].Size -
860 SymInfo.getOffset());
863 void RuntimeDyldCheckerImpl::registerSection(
864 StringRef FilePath,
unsigned SectionID) {
869 Stubs[FileName][SectionName].SectionID = SectionID;
872 void RuntimeDyldCheckerImpl::registerStubMap(
879 Stubs[FileName][SectionName].SectionID = SectionID;
881 for (
auto &StubMapEntry : RTDyldStubs) {
882 std::string SymbolName =
"";
884 if (StubMapEntry.first.SymbolName)
885 SymbolName = StubMapEntry.first.SymbolName;
889 for (
auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
890 const auto &SymInfo = GSTEntry.second;
891 if (SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
892 SymInfo.getOffset() ==
893 static_cast<uint64_t
>(StubMapEntry.first.Offset)) {
894 SymbolName = GSTEntry.first();
900 if (SymbolName !=
"")
901 Stubs[FileName][SectionName].StubOffsets[SymbolName] =
911 InstPrinter, ErrStream)) {}
924 return Impl->check(CheckExpr);
929 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
932 std::pair<uint64_t, std::string>
935 return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
size_t size() const
size - Get the string size.
const char * getBufferStart() const
RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, llvm::raw_ostream &ErrStream)
DecodeStatus
Ternary decode status.
std::string Name
Name - section name.
Superclass for all disassemblers.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
uint64_t getAddress() const
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
iterator find(StringRef Key)
RuntimeDyld & getRTDyld()
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker, raw_ostream &ErrStream)
StringRef rtrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the right removed.
bool evaluate(StringRef Expr) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::map< RelocationValueRef, uintptr_t > StubMap
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
Scan the given memory buffer for lines beginning with the string in RulePrefix.
Instances of this class represent a single low-level machine instruction.
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
StringRef filename(StringRef path)
Get filename.
std::pair< uint64_t, std::string > getSectionAddr(StringRef FileName, StringRef SectionName, bool LocalAddress)
Returns the address of the requested section (or an error message in the second element of the pair i...
StringRef trim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left and right removed...
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
RuntimeDyld::SymbolResolver & Resolver
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
virtual SymbolInfo findSymbol(const std::string &Name)=0
This method returns the address of the specified function or variable.
uint8_t * getSectionAddress(unsigned SectionID) const
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool check(StringRef CheckExpr) const
Check a single expression against the attached RuntimeDyld instance.
bool check(StringRef CheckExpr) const
This interface provides simple read-only access to a block of memory, and provides simple methods for...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
unsigned getNumOperands() const
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
const char * getBufferEnd() const
SectionEntry - represents a section emitted into memory by the dynamic linker.
A raw_ostream that writes to an std::string.
LLVM Value Representation.
RuntimeDyldChecker(RuntimeDyld &RTDyld, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, raw_ostream &ErrStream)
RTDyldSymbolTable GlobalSymbolTable
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
This class implements an extremely fast bulk output stream that can only output to a stream...
uint8_t * getSymbolLocalAddress(StringRef Name) const
StringRef - Represent a constant reference to a string, i.e.
virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const =0
Returns the disassembly of a single instruction.
Instances of this class represent operands of the MCInst class.
const MCOperand & getOperand(unsigned i) const
StringRef ltrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left removed.
bool empty() const
empty - Check if the string is empty.