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);
372 uint64_t NextPC = SymbolAddr + InstSize;
374 return std::make_pair(EvalResult(NextPC), RemainingExpr);
382 std::pair<EvalResult, StringRef>
383 evalStubOrGOTAddr(
StringRef Expr, ParseContext PCtx,
bool IsStubAddr)
const {
385 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
391 size_t ComaIdx = RemainingExpr.
find(
',');
392 StubContainerName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
393 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
396 return std::make_pair(
397 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
401 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
404 return std::make_pair(
405 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
409 std::string ErrorMsg;
410 std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor(
411 StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr);
414 return std::make_pair(EvalResult(ErrorMsg),
"");
416 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
419 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
420 ParseContext PCtx)
const {
422 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
428 size_t ComaIdx = RemainingExpr.
find(
',');
429 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
430 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
433 return std::make_pair(
434 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
438 size_t CloseParensIdx = RemainingExpr.
find(
')');
440 RemainingExpr = RemainingExpr.
substr(CloseParensIdx).
ltrim();
443 return std::make_pair(
444 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
448 std::string ErrorMsg;
449 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
453 return std::make_pair(EvalResult(ErrorMsg),
"");
455 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
461 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
462 ParseContext PCtx)
const {
465 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
468 if (Symbol ==
"decode_operand")
469 return evalDecodeOperand(RemainingExpr);
470 else if (Symbol ==
"next_pc")
471 return evalNextPC(RemainingExpr, PCtx);
472 else if (Symbol ==
"stub_addr")
473 return evalStubOrGOTAddr(RemainingExpr, PCtx,
true);
474 else if (Symbol ==
"got_addr")
475 return evalStubOrGOTAddr(RemainingExpr, PCtx,
false);
476 else if (Symbol ==
"section_addr")
477 return evalSectionAddr(RemainingExpr, PCtx);
479 if (!Checker.isSymbolValid(Symbol)) {
480 std::string ErrMsg(
"No known address for symbol '");
483 if (
Symbol.startswith(
"L"))
484 ErrMsg +=
" (this appears to be an assembler local label - "
485 " perhaps drop the 'L'?)";
487 return std::make_pair(EvalResult(ErrMsg),
"");
493 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
494 : Checker.getSymbolRemoteAddr(Symbol);
497 return std::make_pair(EvalResult(
Value), RemainingExpr);
502 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
507 FirstNonDigit = Expr.
size();
511 FirstNonDigit = Expr.
size();
513 return std::make_pair(Expr.
substr(0, FirstNonDigit),
514 Expr.
substr(FirstNonDigit));
520 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
523 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
525 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
526 return std::make_pair(
527 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
530 return std::make_pair(EvalResult(
Value), RemainingExpr);
536 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
537 ParseContext PCtx)
const {
539 EvalResult SubExprResult;
541 std::tie(SubExprResult, RemainingExpr) =
542 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
543 if (SubExprResult.hasError())
544 return std::make_pair(SubExprResult,
"");
546 return std::make_pair(
547 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
549 return std::make_pair(SubExprResult, RemainingExpr);
556 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
562 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
564 EvalResult ReadSizeExpr;
565 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
566 if (ReadSizeExpr.hasError())
567 return std::make_pair(ReadSizeExpr, RemainingExpr);
568 uint64_t ReadSize = ReadSizeExpr.getValue();
569 if (ReadSize < 1 || ReadSize > 8)
570 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
572 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
576 ParseContext LoadCtx(
true);
577 EvalResult LoadAddrExprResult;
578 std::tie(LoadAddrExprResult, RemainingExpr) =
579 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
581 if (LoadAddrExprResult.hasError())
582 return std::make_pair(LoadAddrExprResult,
"");
584 uint64_t LoadAddr = LoadAddrExprResult.getValue();
589 return std::make_pair(0, RemainingExpr);
591 return std::make_pair(
592 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
603 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
604 ParseContext PCtx)
const {
605 EvalResult SubExprResult;
609 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
612 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
613 else if (Expr[0] ==
'*')
614 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
615 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
616 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
617 else if (isdigit(Expr[0]))
618 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
620 return std::make_pair(
621 unexpectedToken(Expr, Expr,
622 "expected '(', '*', identifier, or number"),
"");
624 if (SubExprResult.hasError())
625 return std::make_pair(SubExprResult, RemainingExpr);
629 std::tie(SubExprResult, RemainingExpr) =
630 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
632 return std::make_pair(SubExprResult, RemainingExpr);
642 std::pair<EvalResult, StringRef>
643 evalSliceExpr(
const std::pair<EvalResult, StringRef> &Ctx)
const {
644 EvalResult SubExprResult;
646 std::tie(SubExprResult, RemainingExpr) = Ctx;
651 EvalResult HighBitExpr;
652 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
654 if (HighBitExpr.hasError())
655 return std::make_pair(HighBitExpr, RemainingExpr);
658 return std::make_pair(
659 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
662 EvalResult LowBitExpr;
663 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
665 if (LowBitExpr.hasError())
666 return std::make_pair(LowBitExpr, RemainingExpr);
669 return std::make_pair(
670 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
673 unsigned HighBit = HighBitExpr.getValue();
674 unsigned LowBit = LowBitExpr.getValue();
676 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
677 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
686 std::pair<EvalResult, StringRef>
687 evalComplexExpr(
const std::pair<EvalResult, StringRef> &LHSAndRemaining,
688 ParseContext PCtx)
const {
689 EvalResult LHSResult;
691 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
695 if (LHSResult.hasError() || RemainingExpr ==
"")
696 return std::make_pair(LHSResult, RemainingExpr);
700 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
703 if (BinOp == BinOpToken::Invalid)
704 return std::make_pair(LHSResult, RemainingExpr);
707 EvalResult RHSResult;
708 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
711 if (RHSResult.hasError())
712 return std::make_pair(RHSResult, RemainingExpr);
716 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
718 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
723 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
724 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());
726 if (
auto E = TI.takeError()) {
727 errs() <<
"Error obtaining disassembler: " <<
toString(std::move(
E))
732 StringRef SymbolMem = Checker.getSymbolContent(Symbol);
737 TI->Disassembler->getInstruction(Inst,
Size, SymbolBytes, 0,
nulls());
745 auto TripleName =
TT.str();
746 std::string ErrorStr;
750 return make_error<StringError>(
"Error accessing target '" + TripleName +
754 std::unique_ptr<MCSubtargetInfo> STI(
757 return make_error<StringError>(
"Unable to create subtarget for " +
763 return make_error<StringError>(
"Unable to create target register info "
769 std::unique_ptr<MCAsmInfo> MAI(
772 return make_error<StringError>(
"Unable to create target asm info " +
776 auto Ctx = std::make_unique<MCContext>(
Triple(TripleName), MAI.get(),
777 MRI.get(), STI.get());
779 std::unique_ptr<MCDisassembler> Disassembler(
782 return make_error<StringError>(
"Unable to create disassembler for " +
788 return make_error<StringError>(
"Unable to create instruction info for" +
793 Triple(TripleName), 0, *MAI, *MII, *
MRI));
795 return make_error<StringError>(
796 "Unable to create instruction printer for" + TripleName,
799 return TargetInfo({TheTarget, std::move(STI), std::move(
MRI),
800 std::move(MAI), std::move(Ctx), std::move(Disassembler),
801 std::move(MII), std::move(InstPrinter)});
807 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
808 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
811 : IsSymbolValid(
std::
move(IsSymbolValid)),
812 GetSymbolInfo(
std::
move(GetSymbolInfo)),
813 GetSectionInfo(
std::
move(GetSectionInfo)),
814 GetStubInfo(
std::
move(GetStubInfo)), GetGOTInfo(
std::
move(GetGOTInfo)),
816 TF(
std::
move(TF)), ErrStream(ErrStream) {}
819 CheckExpr = CheckExpr.
trim();
820 LLVM_DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr
823 bool Result =
P.evaluate(CheckExpr);
826 << (Result ?
"passed" :
"FAILED") <<
".\n");
832 bool DidAllTestsPass =
true;
833 unsigned NumRules = 0;
835 std::string CheckExpr;
839 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
842 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
843 const char *LineEnd = LineStart;
844 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
848 StringRef Line(LineStart, LineEnd - LineStart);
849 if (Line.startswith(RulePrefix))
850 CheckExpr += Line.substr(RulePrefix.
size()).str();
853 if (!CheckExpr.empty()) {
855 if (CheckExpr.back() !=
'\\') {
856 DidAllTestsPass &=
check(CheckExpr);
860 CheckExpr.pop_back();
865 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
868 return DidAllTestsPass && (NumRules != 0);
871bool RuntimeDyldCheckerImpl::isSymbolValid(
StringRef Symbol)
const {
872 return IsSymbolValid(Symbol);
876 auto SymInfo = GetSymbolInfo(Symbol);
886 reinterpret_cast<uintptr_t
>(
SymInfo->getContent().data()));
890 auto SymInfo = GetSymbolInfo(Symbol);
896 return SymInfo->getTargetAddress();
900 unsigned Size)
const {
901 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
902 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
903 void *
Ptr =
reinterpret_cast<void*
>(PtrSizedAddr);
907 return support::endian::read<uint8_t>(
Ptr, Endianness);
909 return support::endian::read<uint16_t>(
Ptr, Endianness);
911 return support::endian::read<uint32_t>(
Ptr, Endianness);
913 return support::endian::read<uint64_t>(
Ptr, Endianness);
919 auto SymInfo = GetSymbolInfo(Symbol);
924 return {
SymInfo->getContent().data(),
SymInfo->getContent().size()};
928 auto SymInfo = GetSymbolInfo(Symbol);
933 return SymInfo->getTargetFlags();
937RuntimeDyldCheckerImpl::getTripleForSymbol(
TargetFlagsType Flag)
const {
940 switch (
TT.getArch()) {
957std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
960 auto SecInfo = GetSectionInfo(FileName,
SectionName);
968 return std::make_pair(0, std::move(ErrMsg));
977 if (SecInfo->isZeroFill())
982 Addr = SecInfo->getTargetAddress();
984 return std::make_pair(
Addr,
"");
987std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
989 bool IsStubAddr)
const {
991 auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName)
1001 return std::make_pair((
uint64_t)0, std::move(ErrMsg));
1007 if (StubInfo->isZeroFill())
1008 return std::make_pair((
uint64_t)0,
"Detected zero-filled stub/GOT entry");
1011 Addr = StubInfo->getTargetAddress();
1013 return std::make_pair(
Addr,
"");
1030 return Impl->check(CheckExpr);
1035 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
1038std::pair<uint64_t, std::string>
1040 bool LocalAddress) {
1041 return Impl->getSectionAddr(FileName,
SectionName, LocalAddress);
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
std::function< Expected< MemoryRegionInfo >(StringRef StubContainer, StringRef TargetName)> GetStubInfoFunction
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 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).
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.
bool startswith(StringRef Prefix) const
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.
@ Invalid
Invalid file type.
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.