31#define DEBUG_TYPE "rtdyld"
38 std::unique_ptr<MCSubtargetInfo> STI;
39 std::unique_ptr<MCRegisterInfo>
MRI;
40 std::unique_ptr<MCAsmInfo> MAI;
41 std::unique_ptr<MCContext> Ctx;
42 std::unique_ptr<MCDisassembler> Disassembler;
43 std::unique_ptr<MCInstrInfo> MII;
44 std::unique_ptr<MCInstPrinter> InstPrinter;
60 size_t EQIdx = Expr.
find(
'=');
62 ParseContext OutsideLoad(
false);
68 std::tie(LHSResult, RemainingExpr) =
69 evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);
70 if (LHSResult.hasError())
71 return handleError(Expr, LHSResult);
72 if (RemainingExpr !=
"")
73 return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr,
""));
78 std::tie(RHSResult, RemainingExpr) =
79 evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);
80 if (RHSResult.hasError())
81 return handleError(Expr, RHSResult);
82 if (RemainingExpr !=
"")
83 return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr,
""));
85 if (LHSResult.getValue() != RHSResult.getValue()) {
86 Checker.ErrStream <<
"Expression '" << Expr <<
"' is false: "
87 <<
format(
"0x%" PRIx64, LHSResult.getValue())
88 <<
" != " <<
format(
"0x%" PRIx64, RHSResult.getValue())
102 struct ParseContext {
104 ParseContext(
bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
109 enum class BinOpToken :
unsigned {
121 EvalResult() :
Value(0) {}
123 EvalResult(std::string ErrorMsg)
126 bool hasError()
const {
return ErrorMsg !=
""; }
127 const std::string &getErrorMsg()
const {
return ErrorMsg; }
131 std::string ErrorMsg;
139 if (isalpha(Expr[0]))
140 std::tie(
Token, Remaining) = parseSymbol(Expr);
141 else if (isdigit(Expr[0]))
142 std::tie(
Token, Remaining) = parseNumberString(Expr);
154 std::string ErrorMsg(
"Encountered unexpected token '");
155 ErrorMsg += getTokenForError(TokenStart);
157 ErrorMsg +=
"' while parsing subexpression '";
165 return EvalResult(std::move(ErrorMsg));
168 bool handleError(
StringRef Expr,
const EvalResult &R)
const {
169 assert(
R.hasError() &&
"Not an error result.");
170 Checker.ErrStream <<
"Error evaluating expression '" << Expr
171 <<
"': " <<
R.getErrorMsg() <<
"\n";
175 std::pair<BinOpToken, StringRef> parseBinOpToken(
StringRef Expr)
const {
177 return std::make_pair(BinOpToken::Invalid,
"");
181 return std::make_pair(BinOpToken::ShiftLeft, Expr.
substr(2).
ltrim());
183 return std::make_pair(BinOpToken::ShiftRight, Expr.
substr(2).
ltrim());
189 return std::make_pair(BinOpToken::Invalid, Expr);
191 Op = BinOpToken::Add;
194 Op = BinOpToken::Sub;
197 Op = BinOpToken::BitwiseAnd;
200 Op = BinOpToken::BitwiseOr;
207 EvalResult computeBinOpResult(BinOpToken
Op,
const EvalResult &LHSResult,
208 const EvalResult &RHSResult)
const {
212 case BinOpToken::Add:
213 return EvalResult(LHSResult.getValue() + RHSResult.getValue());
214 case BinOpToken::Sub:
215 return EvalResult(LHSResult.getValue() - RHSResult.getValue());
216 case BinOpToken::BitwiseAnd:
217 return EvalResult(LHSResult.getValue() & RHSResult.getValue());
218 case BinOpToken::BitwiseOr:
219 return EvalResult(LHSResult.getValue() | RHSResult.getValue());
220 case BinOpToken::ShiftLeft:
221 return EvalResult(LHSResult.getValue() << RHSResult.getValue());
222 case BinOpToken::ShiftRight:
223 return EvalResult(LHSResult.getValue() >> RHSResult.getValue());
229 std::pair<StringRef, StringRef> parseSymbol(
StringRef Expr)
const {
231 "abcdefghijklmnopqrstuvwxyz"
232 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
234 return std::make_pair(Expr.
substr(0, FirstNonSymbol),
244 std::pair<EvalResult, StringRef> evalDecodeOperand(
StringRef Expr)
const {
246 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
249 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
251 if (!Checker.isSymbolValid(Symbol))
252 return std::make_pair(
253 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
259 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
261 case BinOpToken::Add: {
263 std::tie(
Number, RemainingExpr) = evalNumberExpr(RemainingExpr);
267 case BinOpToken::Invalid:
270 return std::make_pair(
271 unexpectedToken(RemainingExpr, RemainingExpr,
272 "expected '+' for offset or ',' if no offset"),
277 return std::make_pair(
278 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ','"),
"");
281 EvalResult OpIdxExpr;
282 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
283 if (OpIdxExpr.hasError())
284 return std::make_pair(OpIdxExpr,
"");
287 return std::make_pair(
288 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
294 return std::make_pair(
295 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
298 unsigned OpIdx = OpIdxExpr.getValue();
302 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
303 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());
304 if (
auto E = TI.takeError()) {
305 errs() <<
"Error obtaining instruction printer: "
307 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
309 Inst.dump_pretty(ErrMsgStream, TI->InstPrinter.get());
310 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
313 if (OpIdx >= Inst.getNumOperands()) {
316 ErrMsgStream <<
"Invalid operand index '" <<
format(
"%i", OpIdx)
317 <<
"' for instruction '" <<
Symbol
318 <<
"'. Instruction has only "
319 <<
format(
"%i", Inst.getNumOperands())
320 <<
" operands.\nInstruction is:\n ";
322 return printInst(Symbol, Inst, ErrMsgStream);
329 ErrMsgStream <<
"Operand '" <<
format(
"%i", OpIdx) <<
"' of instruction '"
330 <<
Symbol <<
"' is not an immediate.\nInstruction is:\n ";
332 return printInst(Symbol, Inst, ErrMsgStream);
335 return std::make_pair(EvalResult(
Op.getImm()), RemainingExpr);
344 std::pair<EvalResult, StringRef> evalNextPC(
StringRef Expr,
345 ParseContext PCtx)
const {
347 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
350 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
352 if (!Checker.isSymbolValid(Symbol))
353 return std::make_pair(
354 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
358 return std::make_pair(
359 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
364 if (!decodeInst(Symbol, Inst, InstSize, 0))
365 return std::make_pair(
366 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
369 uint64_t SymbolAddr = PCtx.IsInsideLoad
370 ? Checker.getSymbolLocalAddr(Symbol)
371 : Checker.getSymbolRemoteAddr(Symbol);
375 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
378 uint64_t NextPC = SymbolAddr + InstSize + PCOffset;
380 return std::make_pair(EvalResult(NextPC), RemainingExpr);
388 std::pair<EvalResult, StringRef>
389 evalStubOrGOTAddr(
StringRef Expr, ParseContext PCtx,
bool IsStubAddr)
const {
391 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
397 size_t ComaIdx = RemainingExpr.
find(
',');
398 StubContainerName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
399 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
402 return std::make_pair(
403 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
407 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
413 size_t ClosingBracket = RemainingExpr.
find(
")");
414 KindNameFilter = RemainingExpr.
substr(0, ClosingBracket);
415 RemainingExpr = RemainingExpr.
substr(ClosingBracket);
419 return std::make_pair(
420 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
424 std::string ErrorMsg;
425 std::tie(StubAddr, ErrorMsg) =
426 Checker.getStubOrGOTAddrFor(StubContainerName, Symbol, KindNameFilter,
427 PCtx.IsInsideLoad, IsStubAddr);
430 return std::make_pair(EvalResult(ErrorMsg),
"");
432 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
435 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
436 ParseContext PCtx)
const {
438 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
444 size_t ComaIdx = RemainingExpr.
find(
',');
445 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
446 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
449 return std::make_pair(
450 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
454 size_t CloseParensIdx = RemainingExpr.
find(
')');
456 RemainingExpr = RemainingExpr.
substr(CloseParensIdx).
ltrim();
459 return std::make_pair(
460 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
464 std::string ErrorMsg;
465 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
469 return std::make_pair(EvalResult(ErrorMsg),
"");
471 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
477 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
478 ParseContext PCtx)
const {
481 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
484 if (Symbol ==
"decode_operand")
485 return evalDecodeOperand(RemainingExpr);
486 else if (Symbol ==
"next_pc")
487 return evalNextPC(RemainingExpr, PCtx);
488 else if (Symbol ==
"stub_addr")
489 return evalStubOrGOTAddr(RemainingExpr, PCtx,
true);
490 else if (Symbol ==
"got_addr")
491 return evalStubOrGOTAddr(RemainingExpr, PCtx,
false);
492 else if (Symbol ==
"section_addr")
493 return evalSectionAddr(RemainingExpr, PCtx);
495 if (!Checker.isSymbolValid(Symbol)) {
496 std::string ErrMsg(
"No known address for symbol '");
499 if (
Symbol.starts_with(
"L"))
500 ErrMsg +=
" (this appears to be an assembler local label - "
501 " perhaps drop the 'L'?)";
503 return std::make_pair(EvalResult(ErrMsg),
"");
509 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
510 : Checker.getSymbolRemoteAddr(Symbol);
513 return std::make_pair(EvalResult(
Value), RemainingExpr);
518 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
523 FirstNonDigit = Expr.
size();
527 FirstNonDigit = Expr.
size();
529 return std::make_pair(Expr.
substr(0, FirstNonDigit),
530 Expr.
substr(FirstNonDigit));
536 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
539 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
541 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
542 return std::make_pair(
543 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
546 return std::make_pair(EvalResult(
Value), RemainingExpr);
552 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
553 ParseContext PCtx)
const {
555 EvalResult SubExprResult;
557 std::tie(SubExprResult, RemainingExpr) =
558 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
559 if (SubExprResult.hasError())
560 return std::make_pair(SubExprResult,
"");
562 return std::make_pair(
563 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
565 return std::make_pair(SubExprResult, RemainingExpr);
572 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
578 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
580 EvalResult ReadSizeExpr;
581 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
582 if (ReadSizeExpr.hasError())
583 return std::make_pair(ReadSizeExpr, RemainingExpr);
584 uint64_t ReadSize = ReadSizeExpr.getValue();
585 if (ReadSize < 1 || ReadSize > 8)
586 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
588 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
592 ParseContext LoadCtx(
true);
593 EvalResult LoadAddrExprResult;
594 std::tie(LoadAddrExprResult, RemainingExpr) =
595 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
597 if (LoadAddrExprResult.hasError())
598 return std::make_pair(LoadAddrExprResult,
"");
600 uint64_t LoadAddr = LoadAddrExprResult.getValue();
605 return std::make_pair(0, RemainingExpr);
607 return std::make_pair(
608 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
619 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
620 ParseContext PCtx)
const {
621 EvalResult SubExprResult;
625 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
628 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
629 else if (Expr[0] ==
'*')
630 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
631 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
632 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
633 else if (isdigit(Expr[0]))
634 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
636 return std::make_pair(
637 unexpectedToken(Expr, Expr,
638 "expected '(', '*', identifier, or number"),
"");
640 if (SubExprResult.hasError())
641 return std::make_pair(SubExprResult, RemainingExpr);
645 std::tie(SubExprResult, RemainingExpr) =
646 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
648 return std::make_pair(SubExprResult, RemainingExpr);
658 std::pair<EvalResult, StringRef>
659 evalSliceExpr(
const std::pair<EvalResult, StringRef> &Ctx)
const {
660 EvalResult SubExprResult;
662 std::tie(SubExprResult, RemainingExpr) = Ctx;
667 EvalResult HighBitExpr;
668 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
670 if (HighBitExpr.hasError())
671 return std::make_pair(HighBitExpr, RemainingExpr);
674 return std::make_pair(
675 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
678 EvalResult LowBitExpr;
679 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
681 if (LowBitExpr.hasError())
682 return std::make_pair(LowBitExpr, RemainingExpr);
685 return std::make_pair(
686 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
689 unsigned HighBit = HighBitExpr.getValue();
690 unsigned LowBit = LowBitExpr.getValue();
692 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
693 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
702 std::pair<EvalResult, StringRef>
703 evalComplexExpr(
const std::pair<EvalResult, StringRef> &LHSAndRemaining,
704 ParseContext PCtx)
const {
705 EvalResult LHSResult;
707 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
711 if (LHSResult.hasError() || RemainingExpr ==
"")
712 return std::make_pair(LHSResult, RemainingExpr);
716 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
719 if (BinOp == BinOpToken::Invalid)
720 return std::make_pair(LHSResult, RemainingExpr);
723 EvalResult RHSResult;
724 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
727 if (RHSResult.hasError())
728 return std::make_pair(RHSResult, RemainingExpr);
732 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
734 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
739 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
740 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());
742 if (
auto E = TI.takeError()) {
743 errs() <<
"Error obtaining disassembler: " <<
toString(std::move(E))
748 StringRef SymbolMem = Checker.getSymbolContent(Symbol);
753 TI->Disassembler->getInstruction(Inst,
Size, SymbolBytes, 0,
nulls());
761 auto TripleName =
TT.str();
762 std::string ErrorStr;
766 return make_error<StringError>(
"Error accessing target '" + TripleName +
770 std::unique_ptr<MCSubtargetInfo> STI(
773 return make_error<StringError>(
"Unable to create subtarget for " +
779 return make_error<StringError>(
"Unable to create target register info "
785 std::unique_ptr<MCAsmInfo> MAI(
788 return make_error<StringError>(
"Unable to create target asm info " +
792 auto Ctx = std::make_unique<MCContext>(
Triple(TripleName), MAI.get(),
793 MRI.get(), STI.get());
795 std::unique_ptr<MCDisassembler> Disassembler(
798 return make_error<StringError>(
"Unable to create disassembler for " +
804 return make_error<StringError>(
"Unable to create instruction info for" +
809 Triple(TripleName), 0, *MAI, *MII, *
MRI));
811 return make_error<StringError>(
812 "Unable to create instruction printer for" + TripleName,
815 return TargetInfo({TheTarget, std::move(STI), std::move(
MRI),
816 std::move(MAI), std::move(Ctx), std::move(Disassembler),
817 std::move(MII), std::move(InstPrinter)});
823 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
824 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
827 : IsSymbolValid(
std::
move(IsSymbolValid)),
828 GetSymbolInfo(
std::
move(GetSymbolInfo)),
829 GetSectionInfo(
std::
move(GetSectionInfo)),
830 GetStubInfo(
std::
move(GetStubInfo)), GetGOTInfo(
std::
move(GetGOTInfo)),
832 TF(
std::
move(TF)), ErrStream(ErrStream) {}
835 CheckExpr = CheckExpr.
trim();
836 LLVM_DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr
839 bool Result =
P.evaluate(CheckExpr);
842 << (Result ?
"passed" :
"FAILED") <<
".\n");
848 bool DidAllTestsPass =
true;
849 unsigned NumRules = 0;
851 std::string CheckExpr;
855 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
858 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
859 const char *LineEnd = LineStart;
860 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
864 StringRef Line(LineStart, LineEnd - LineStart);
865 if (Line.starts_with(RulePrefix))
866 CheckExpr += Line.substr(RulePrefix.
size()).str();
869 if (!CheckExpr.empty()) {
871 if (CheckExpr.back() !=
'\\') {
872 DidAllTestsPass &=
check(CheckExpr);
876 CheckExpr.pop_back();
881 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
884 return DidAllTestsPass && (NumRules != 0);
887bool RuntimeDyldCheckerImpl::isSymbolValid(
StringRef Symbol)
const {
888 return IsSymbolValid(Symbol);
892 auto SymInfo = GetSymbolInfo(Symbol);
902 reinterpret_cast<uintptr_t
>(
SymInfo->getContent().data()));
906 auto SymInfo = GetSymbolInfo(Symbol);
912 return SymInfo->getTargetAddress();
916 unsigned Size)
const {
917 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
918 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
919 void *
Ptr =
reinterpret_cast<void*
>(PtrSizedAddr);
923 return support::endian::read<uint8_t>(
Ptr, Endianness);
925 return support::endian::read<uint16_t>(
Ptr, Endianness);
927 return support::endian::read<uint32_t>(
Ptr, Endianness);
929 return support::endian::read<uint64_t>(
Ptr, Endianness);
935 auto SymInfo = GetSymbolInfo(Symbol);
940 return {
SymInfo->getContent().data(),
SymInfo->getContent().size()};
944 auto SymInfo = GetSymbolInfo(Symbol);
949 return SymInfo->getTargetFlags();
953RuntimeDyldCheckerImpl::getTripleForSymbol(
TargetFlagsType Flag)
const {
956 switch (
TT.getArch()) {
973std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
976 auto SecInfo = GetSectionInfo(FileName,
SectionName);
984 return std::make_pair(0, std::move(ErrMsg));
993 if (SecInfo->isZeroFill())
998 Addr = SecInfo->getTargetAddress();
1000 return std::make_pair(
Addr,
"");
1003std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
1005 bool IsInsideLoad,
bool IsStubAddr)
const {
1008 "Kind name filter only supported for stubs");
1010 IsStubAddr ? GetStubInfo(StubContainerName, SymbolName, StubKindFilter)
1020 return std::make_pair((
uint64_t)0, std::move(ErrMsg));
1026 if (StubInfo->isZeroFill())
1027 return std::make_pair((
uint64_t)0,
"Detected zero-filled stub/GOT entry");
1030 Addr = StubInfo->getTargetAddress();
1032 return std::make_pair(
Addr,
"");
1049 return Impl->check(CheckExpr);
1054 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
1057std::pair<uint64_t, std::string>
1059 bool LocalAddress) {
1060 return Impl->getSectionAddr(FileName,
SectionName, LocalAddress);
unsigned const MachineRegisterInfo * MRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class represents an Operation in the Expression.
Tagged union holding either a T or a Error.
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
Instances of this class represent operands of the MCInst class.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
const char * getBufferEnd() const
const char * getBufferStart() const
bool evaluate(StringRef Expr) const
RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker, raw_ostream &ErrStream)
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
bool check(StringRef CheckExpr) const
RuntimeDyldCheckerImpl(IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, GetGOTInfoFunction GetGOTInfo, llvm::endianness Endianness, Triple TT, StringRef CPU, SubtargetFeatures TF, llvm::raw_ostream &ErrStream)
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...
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
Scan the given memory buffer for lines beginning with the string in RulePrefix.
bool check(StringRef CheckExpr) const
Check a single expression against the attached RuntimeDyld instance.
std::function< bool(StringRef Symbol)> IsSymbolValidFunction
RuntimeDyldChecker(IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, GetGOTInfoFunction GetGOTInfo, llvm::endianness Endianness, Triple TT, StringRef CPU, SubtargetFeatures TF, raw_ostream &ErrStream)
std::function< Expected< MemoryRegionInfo >(StringRef StubContainer, StringRef TargetName, StringRef StubKindFilter)> GetStubInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef FileName, StringRef SectionName)> GetSectionInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef GOTContainer, StringRef TargetName)> GetGOTInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef SymbolName)> GetSymbolInfoFunction
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static constexpr size_t npos
const unsigned char * bytes_begin() 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.
Manages the enabling and disabling of subtarget specific features.
std::string getString() const
Returns features as a string.
Target - Wrapper for Target specific information.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
MCDisassembler * createMCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) const
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
MCInstPrinter * createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) const
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Triple - Helper class for working with autoconf configuration names.
void setArchName(StringRef Str)
Set the architecture (first) component of the triple by name.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint8_t TargetFlagsType
Holds target-specific properties for a symbol.
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Implement std::hash so that hash_code can be used in STL containers.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.