24 #define DEBUG_TYPE "rtdyld" 40 size_t EQIdx = Expr.
find(
'=');
42 ParseContext OutsideLoad(
false);
48 std::tie(LHSResult, RemainingExpr) =
49 evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);
50 if (LHSResult.hasError())
51 return handleError(Expr, LHSResult);
52 if (RemainingExpr !=
"")
53 return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr,
""));
58 std::tie(RHSResult, RemainingExpr) =
59 evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);
60 if (RHSResult.hasError())
61 return handleError(Expr, RHSResult);
62 if (RemainingExpr !=
"")
63 return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr,
""));
65 if (LHSResult.getValue() != RHSResult.getValue()) {
66 Checker.ErrStream <<
"Expression '" << Expr <<
"' is false: " 67 <<
format(
"0x%" PRIx64, LHSResult.getValue())
68 <<
" != " <<
format(
"0x%" PRIx64, RHSResult.getValue())
84 ParseContext(
bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
101 EvalResult() :
Value(0), ErrorMsg(
"") {}
102 EvalResult(uint64_t
Value) : Value(Value), ErrorMsg(
"") {}
103 EvalResult(std::string ErrorMsg)
104 : Value(0), ErrorMsg(std::move(ErrorMsg)) {}
105 uint64_t getValue()
const {
return Value; }
106 bool hasError()
const {
return ErrorMsg !=
""; }
107 const std::string &getErrorMsg()
const {
return ErrorMsg; }
111 std::string ErrorMsg;
119 if (isalpha(Expr[0]))
120 std::tie(Token, Remaining) = parseSymbol(Expr);
121 else if (isdigit(Expr[0]))
122 std::tie(Token, Remaining) = parseNumberString(Expr);
127 Token = Expr.
substr(0, TokLen);
134 std::string ErrorMsg(
"Encountered unexpected token '");
135 ErrorMsg += getTokenForError(TokenStart);
137 ErrorMsg +=
"' while parsing subexpression '";
145 return EvalResult(std::move(ErrorMsg));
148 bool handleError(
StringRef Expr,
const EvalResult &R)
const {
149 assert(R.hasError() &&
"Not an error result.");
150 Checker.ErrStream <<
"Error evaluating expression '" << Expr
151 <<
"': " << R.getErrorMsg() <<
"\n";
155 std::pair<BinOpToken, StringRef> parseBinOpToken(
StringRef Expr)
const {
157 return std::make_pair(BinOpToken::Invalid,
"");
161 return std::make_pair(BinOpToken::ShiftLeft, Expr.
substr(2).
ltrim());
163 return std::make_pair(BinOpToken::ShiftRight, Expr.
substr(2).
ltrim());
169 return std::make_pair(BinOpToken::Invalid, Expr);
171 Op = BinOpToken::Add;
174 Op = BinOpToken::Sub;
177 Op = BinOpToken::BitwiseAnd;
180 Op = BinOpToken::BitwiseOr;
187 EvalResult computeBinOpResult(BinOpToken
Op,
const EvalResult &LHSResult,
188 const EvalResult &RHSResult)
const {
192 case BinOpToken::Add:
193 return EvalResult(LHSResult.getValue() + RHSResult.getValue());
194 case BinOpToken::Sub:
195 return EvalResult(LHSResult.getValue() - RHSResult.getValue());
196 case BinOpToken::BitwiseAnd:
197 return EvalResult(LHSResult.getValue() & RHSResult.getValue());
198 case BinOpToken::BitwiseOr:
199 return EvalResult(LHSResult.getValue() | RHSResult.getValue());
200 case BinOpToken::ShiftLeft:
201 return EvalResult(LHSResult.getValue() << RHSResult.getValue());
202 case BinOpToken::ShiftRight:
203 return EvalResult(LHSResult.getValue() >> RHSResult.getValue());
209 std::pair<StringRef, StringRef> parseSymbol(
StringRef Expr)
const {
211 "abcdefghijklmnopqrstuvwxyz" 212 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 214 return std::make_pair(Expr.
substr(0, FirstNonSymbol),
224 std::pair<EvalResult, StringRef> evalDecodeOperand(
StringRef Expr)
const {
226 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
229 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
231 if (!Checker.isSymbolValid(Symbol))
232 return std::make_pair(
233 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
237 return std::make_pair(
238 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ','"),
"");
241 EvalResult OpIdxExpr;
242 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
243 if (OpIdxExpr.hasError())
244 return std::make_pair(OpIdxExpr,
"");
247 return std::make_pair(
248 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
253 if (!decodeInst(Symbol, Inst, Size))
254 return std::make_pair(
255 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
258 unsigned OpIdx = OpIdxExpr.getValue();
262 ErrMsgStream <<
"Invalid operand index '" <<
format(
"%i", OpIdx)
263 <<
"' for instruction '" << Symbol
264 <<
"'. Instruction has only " 266 <<
" operands.\nInstruction is:\n ";
267 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
268 return std::make_pair(EvalResult(ErrMsgStream.
str()),
"");
275 ErrMsgStream <<
"Operand '" <<
format(
"%i", OpIdx) <<
"' of instruction '" 276 << Symbol <<
"' is not an immediate.\nInstruction is:\n ";
277 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
279 return std::make_pair(EvalResult(ErrMsgStream.
str()),
"");
282 return std::make_pair(EvalResult(Op.
getImm()), RemainingExpr);
291 std::pair<EvalResult, StringRef> evalNextPC(
StringRef Expr,
292 ParseContext PCtx)
const {
294 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
297 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
299 if (!Checker.isSymbolValid(Symbol))
300 return std::make_pair(
301 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
305 return std::make_pair(
306 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
311 if (!decodeInst(Symbol, Inst, InstSize))
312 return std::make_pair(
313 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
316 uint64_t SymbolAddr = PCtx.IsInsideLoad
317 ? Checker.getSymbolLocalAddr(Symbol)
318 : Checker.getSymbolRemoteAddr(Symbol);
319 uint64_t NextPC = SymbolAddr + InstSize;
321 return std::make_pair(EvalResult(NextPC), RemainingExpr);
329 std::pair<EvalResult, StringRef> evalStubAddr(
StringRef Expr,
330 ParseContext PCtx)
const {
332 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
338 size_t ComaIdx = RemainingExpr.
find(
',');
339 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
340 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
343 return std::make_pair(
344 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
348 std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
351 return std::make_pair(
352 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
356 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
359 return std::make_pair(
360 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
364 std::string ErrorMsg =
"";
365 std::tie(StubAddr, ErrorMsg) = Checker.getStubAddrFor(
366 FileName, SectionName, Symbol, PCtx.IsInsideLoad);
369 return std::make_pair(EvalResult(ErrorMsg),
"");
371 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
374 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
375 ParseContext PCtx)
const {
377 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
383 size_t ComaIdx = RemainingExpr.
find(
',');
384 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
385 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
388 return std::make_pair(
389 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
393 std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
396 return std::make_pair(
397 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
401 std::string ErrorMsg =
"";
402 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
403 FileName, SectionName, PCtx.IsInsideLoad);
406 return std::make_pair(EvalResult(ErrorMsg),
"");
408 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
414 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
415 ParseContext PCtx)
const {
418 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
421 if (Symbol ==
"decode_operand")
422 return evalDecodeOperand(RemainingExpr);
423 else if (Symbol ==
"next_pc")
424 return evalNextPC(RemainingExpr, PCtx);
425 else if (Symbol ==
"stub_addr")
426 return evalStubAddr(RemainingExpr, PCtx);
427 else if (Symbol ==
"section_addr")
428 return evalSectionAddr(RemainingExpr, PCtx);
430 if (!Checker.isSymbolValid(Symbol)) {
431 std::string ErrMsg(
"No known address for symbol '");
435 ErrMsg +=
" (this appears to be an assembler local label - " 436 " perhaps drop the 'L'?)";
438 return std::make_pair(EvalResult(ErrMsg),
"");
444 uint64_t
Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
445 : Checker.getSymbolRemoteAddr(Symbol);
448 return std::make_pair(EvalResult(Value), RemainingExpr);
453 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
458 FirstNonDigit = Expr.
size();
462 FirstNonDigit = Expr.
size();
464 return std::make_pair(Expr.
substr(0, FirstNonDigit),
465 Expr.
substr(FirstNonDigit));
471 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
474 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
476 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
477 return std::make_pair(
478 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
481 return std::make_pair(EvalResult(Value), RemainingExpr);
487 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
488 ParseContext PCtx)
const {
490 EvalResult SubExprResult;
492 std::tie(SubExprResult, RemainingExpr) =
493 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
494 if (SubExprResult.hasError())
495 return std::make_pair(SubExprResult,
"");
497 return std::make_pair(
498 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
500 return std::make_pair(SubExprResult, RemainingExpr);
507 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
512 if (!RemainingExpr.startswith(
"{"))
513 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
515 EvalResult ReadSizeExpr;
516 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
517 if (ReadSizeExpr.hasError())
518 return std::make_pair(ReadSizeExpr, RemainingExpr);
519 uint64_t ReadSize = ReadSizeExpr.getValue();
520 if (ReadSize < 1 || ReadSize > 8)
521 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
522 if (!RemainingExpr.startswith(
"}"))
523 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
524 RemainingExpr = RemainingExpr.substr(1).ltrim();
527 ParseContext LoadCtx(
true);
528 EvalResult LoadAddrExprResult;
529 std::tie(LoadAddrExprResult, RemainingExpr) =
530 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
532 if (LoadAddrExprResult.hasError())
533 return std::make_pair(LoadAddrExprResult,
"");
535 uint64_t LoadAddr = LoadAddrExprResult.getValue();
537 return std::make_pair(
538 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
549 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
550 ParseContext PCtx)
const {
551 EvalResult SubExprResult;
555 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
558 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
559 else if (Expr[0] ==
'*')
560 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
561 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
562 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
563 else if (isdigit(Expr[0]))
564 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
566 return std::make_pair(
567 unexpectedToken(Expr, Expr,
568 "expected '(', '*', identifier, or number"),
"");
570 if (SubExprResult.hasError())
571 return std::make_pair(SubExprResult, RemainingExpr);
575 std::tie(SubExprResult, RemainingExpr) =
576 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
578 return std::make_pair(SubExprResult, RemainingExpr);
588 std::pair<EvalResult, StringRef>
589 evalSliceExpr(
const std::pair<EvalResult, StringRef> &Ctx)
const {
590 EvalResult SubExprResult;
592 std::tie(SubExprResult, RemainingExpr) = Ctx;
597 EvalResult HighBitExpr;
598 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
600 if (HighBitExpr.hasError())
601 return std::make_pair(HighBitExpr, RemainingExpr);
603 if (!RemainingExpr.startswith(
":"))
604 return std::make_pair(
605 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
606 RemainingExpr = RemainingExpr.substr(1).ltrim();
608 EvalResult LowBitExpr;
609 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
611 if (LowBitExpr.hasError())
612 return std::make_pair(LowBitExpr, RemainingExpr);
614 if (!RemainingExpr.startswith(
"]"))
615 return std::make_pair(
616 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
617 RemainingExpr = RemainingExpr.substr(1).ltrim();
619 unsigned HighBit = HighBitExpr.getValue();
620 unsigned LowBit = LowBitExpr.getValue();
621 uint64_t
Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;
622 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
623 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
632 std::pair<EvalResult, StringRef>
633 evalComplexExpr(
const std::pair<EvalResult, StringRef> &LHSAndRemaining,
634 ParseContext PCtx)
const {
635 EvalResult LHSResult;
637 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
641 if (LHSResult.hasError() || RemainingExpr ==
"")
642 return std::make_pair(LHSResult, RemainingExpr);
646 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
649 if (BinOp == BinOpToken::Invalid)
650 return std::make_pair(LHSResult, RemainingExpr);
653 EvalResult RHSResult;
654 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
657 if (RHSResult.hasError())
658 return std::make_pair(RHSResult, RemainingExpr);
662 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
664 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
669 StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol);
671 reinterpret_cast<const uint8_t *>(SectionMem.
data()),
686 : RTDyld(RTDyld), Disassembler(Disassembler), InstPrinter(InstPrinter),
687 ErrStream(ErrStream) {
688 RTDyld.Checker =
this;
692 CheckExpr = CheckExpr.
trim();
693 LLVM_DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr
696 bool Result = P.
evaluate(CheckExpr);
699 << (Result ?
"passed" :
"FAILED") <<
".\n");
705 bool DidAllTestsPass =
true;
706 unsigned NumRules = 0;
711 while (LineStart != MemBuf->
getBufferEnd() && std::isspace(*LineStart))
714 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
715 const char *LineEnd = LineStart;
716 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
720 StringRef Line(LineStart, LineEnd - LineStart);
728 while (LineStart != MemBuf->
getBufferEnd() && std::isspace(*LineStart))
731 return DidAllTestsPass && (NumRules != 0);
743 auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
744 auto ResultF = ResultP->get_future();
748 ResultP->set_value(std::move(Result));
750 return ResultF.get();
756 auto Result = lookup({Symbol});
763 assert(Result->count(Symbol) &&
"Missing symbol result");
767 uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(
StringRef Symbol)
const {
768 return static_cast<uint64_t
>(
772 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(
StringRef Symbol)
const {
773 if (
auto InternalSymbol = getRTDyld().
getSymbol(Symbol))
774 return InternalSymbol.getAddress();
776 auto Result = lookup({Symbol});
781 auto I = Result->find(Symbol);
782 assert(
I != Result->end() &&
"Missing symbol result");
783 return I->second.getAddress();
786 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
787 unsigned Size)
const {
788 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
789 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
790 uint8_t *Src =
reinterpret_cast<uint8_t*
>(PtrSizedAddr);
795 std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
796 RuntimeDyldCheckerImpl::findSectionAddrInfo(
StringRef FileName,
799 auto SectionMapItr = Stubs.find(FileName);
800 if (SectionMapItr == Stubs.end()) {
801 std::string ErrorMsg =
"File '";
802 ErrorMsg += FileName;
803 ErrorMsg +=
"' not found. ";
805 ErrorMsg +=
"No stubs registered.";
807 ErrorMsg +=
"Available files are:";
808 for (
const auto& StubEntry : Stubs) {
810 ErrorMsg += StubEntry.first;
815 return std::make_pair(
nullptr, ErrorMsg);
818 auto SectionInfoItr = SectionMapItr->second.find(SectionName);
819 if (SectionInfoItr == SectionMapItr->second.end())
820 return std::make_pair(
nullptr,
821 (
"Section '" + SectionName +
"' not found in file '" +
822 FileName +
"'\n").str());
824 return std::make_pair(&SectionInfoItr->second, std::string(
""));
827 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
830 const SectionAddressInfo *SectionInfo =
nullptr;
832 std::string ErrorMsg;
833 std::tie(SectionInfo, ErrorMsg) =
834 findSectionAddrInfo(FileName, SectionName);
836 return std::make_pair(0, ErrorMsg);
839 unsigned SectionID = SectionInfo->SectionID;
842 Addr =
static_cast<uint64_t
>(
reinterpret_cast<uintptr_t
>(
843 getRTDyld().
Sections[SectionID].getAddress()));
845 Addr = getRTDyld().
Sections[SectionID].getLoadAddress();
847 return std::make_pair(Addr, std::string(
""));
850 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
852 bool IsInsideLoad)
const {
854 const SectionAddressInfo *SectionInfo =
nullptr;
856 std::string ErrorMsg;
857 std::tie(SectionInfo, ErrorMsg) =
858 findSectionAddrInfo(FileName, SectionName);
860 return std::make_pair(0, ErrorMsg);
863 unsigned SectionID = SectionInfo->SectionID;
864 const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
865 auto StubOffsetItr = SymbolStubs.find(SymbolName);
866 if (StubOffsetItr == SymbolStubs.end())
867 return std::make_pair(0,
868 (
"Stub for symbol '" + SymbolName +
"' not found. " 869 "If '" + SymbolName +
"' is an internal symbol this " 870 "may indicate that the stub target offset is being " 871 "computed incorrectly.\n").str());
873 uint64_t StubOffset = StubOffsetItr->second;
877 uintptr_t SectionBase =
reinterpret_cast<uintptr_t
>(
878 getRTDyld().
Sections[SectionID].getAddress());
879 Addr =
static_cast<uint64_t
>(SectionBase) + StubOffset;
881 uint64_t SectionBase = getRTDyld().
Sections[SectionID].getLoadAddress();
882 Addr = SectionBase + StubOffset;
885 return std::make_pair(Addr, std::string(
""));
889 RuntimeDyldCheckerImpl::getSubsectionStartingAt(
StringRef Name)
const {
892 if (pos == getRTDyld().GlobalSymbolTable.end())
894 const auto &
SymInfo = pos->second;
896 return StringRef(reinterpret_cast<const char *>(SectionAddr) +
903 RuntimeDyldCheckerImpl::getSectionLoadAddress(
void *LocalAddress)
const {
904 for (
auto &S : getRTDyld().Sections) {
905 if (S.getAddress() == LocalAddress)
906 return S.getLoadAddress();
911 void RuntimeDyldCheckerImpl::registerSection(
912 StringRef FilePath,
unsigned SectionID) {
917 Stubs[FileName][
SectionName].SectionID = SectionID;
920 void RuntimeDyldCheckerImpl::registerStubMap(
927 Stubs[FileName][
SectionName].SectionID = SectionID;
929 for (
auto &StubMapEntry : RTDyldStubs) {
930 std::string SymbolName =
"";
932 if (StubMapEntry.first.SymbolName)
933 SymbolName = StubMapEntry.first.SymbolName;
937 for (
auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
938 const auto &
SymInfo = GSTEntry.second;
939 if (
SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
941 static_cast<uint64_t
>(StubMapEntry.first.Offset)) {
942 SymbolName = GSTEntry.first();
948 if (SymbolName !=
"")
959 InstPrinter, ErrStream)) {}
972 return Impl->check(CheckExpr);
977 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
980 std::pair<uint64_t, std::string>
983 return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
988 return Impl->getSectionLoadAddress(LocalAddress);
uint8_t * getSymbolLocalAddress(StringRef Name) const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
Scan the given memory buffer for lines beginning with the string in RulePrefix.
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
This class represents lattice values for constants.
RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, llvm::raw_ostream &ErrStream)
DecodeStatus
Ternary decode status.
Superclass for all disassemblers.
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
iterator find(StringRef Key)
RuntimeDyld & getRTDyld()
LLVM_NODISCARD StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left 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...
std::set< StringRef > LookupSet
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker, raw_ostream &ErrStream)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
std::map< RelocationValueRef, uintptr_t > StubMap
Tagged union holding either a T or a Error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Instances of this class represent a single low-level machine instruction.
Optional< uint64_t > getSectionLoadAddress(void *LocalAddress) const
If there is a section at the given local address, return its load address, otherwise return none...
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...
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
LLVM_NODISCARD 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 check(StringRef CheckExpr) const
Check a single expression against the attached RuntimeDyld instance.
unsigned getNumOperands() const
virtual void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved)=0
Returns the fully resolved address and flags for each of the given symbols.
uint8_t * getSectionAddress(unsigned SectionID) const
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
const MCOperand & getOperand(unsigned i) const
JITSymbolResolver & Resolver
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.
bool evaluate(StringRef Expr) const
const char * getBufferEnd() const
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
const char * getBufferStart() const
bool check(StringRef CheckExpr) const
StringRef getName() const
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
SectionEntry - represents a section emitted into memory by the dynamic linker.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
StringRef - Represent a constant reference to a string, i.e.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
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.