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);
407 size_t ClosingBracket = RemainingExpr.
find(
")");
408 KindNameFilter = RemainingExpr.
substr(0, ClosingBracket);
409 RemainingExpr = RemainingExpr.
substr(ClosingBracket);
413 return std::make_pair(
414 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
418 std::string ErrorMsg;
419 std::tie(StubAddr, ErrorMsg) =
420 Checker.getStubOrGOTAddrFor(StubContainerName, Symbol, KindNameFilter,
421 PCtx.IsInsideLoad, IsStubAddr);
424 return std::make_pair(EvalResult(ErrorMsg),
"");
426 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
429 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
430 ParseContext PCtx)
const {
432 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
438 size_t ComaIdx = RemainingExpr.
find(
',');
439 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
440 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
443 return std::make_pair(
444 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
448 size_t CloseParensIdx = RemainingExpr.
find(
')');
450 RemainingExpr = RemainingExpr.
substr(CloseParensIdx).
ltrim();
453 return std::make_pair(
454 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
458 std::string ErrorMsg;
459 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
463 return std::make_pair(EvalResult(ErrorMsg),
"");
465 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
471 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
472 ParseContext PCtx)
const {
475 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
478 if (Symbol ==
"decode_operand")
479 return evalDecodeOperand(RemainingExpr);
480 else if (Symbol ==
"next_pc")
481 return evalNextPC(RemainingExpr, PCtx);
482 else if (Symbol ==
"stub_addr")
483 return evalStubOrGOTAddr(RemainingExpr, PCtx,
true);
484 else if (Symbol ==
"got_addr")
485 return evalStubOrGOTAddr(RemainingExpr, PCtx,
false);
486 else if (Symbol ==
"section_addr")
487 return evalSectionAddr(RemainingExpr, PCtx);
489 if (!Checker.isSymbolValid(Symbol)) {
490 std::string ErrMsg(
"No known address for symbol '");
493 if (
Symbol.starts_with(
"L"))
494 ErrMsg +=
" (this appears to be an assembler local label - "
495 " perhaps drop the 'L'?)";
497 return std::make_pair(EvalResult(ErrMsg),
"");
503 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
504 : Checker.getSymbolRemoteAddr(Symbol);
507 return std::make_pair(EvalResult(
Value), RemainingExpr);
512 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
517 FirstNonDigit = Expr.
size();
521 FirstNonDigit = Expr.
size();
523 return std::make_pair(Expr.
substr(0, FirstNonDigit),
524 Expr.
substr(FirstNonDigit));
530 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
533 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
535 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
536 return std::make_pair(
537 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
540 return std::make_pair(EvalResult(
Value), RemainingExpr);
546 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
547 ParseContext PCtx)
const {
549 EvalResult SubExprResult;
551 std::tie(SubExprResult, RemainingExpr) =
552 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
553 if (SubExprResult.hasError())
554 return std::make_pair(SubExprResult,
"");
556 return std::make_pair(
557 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
559 return std::make_pair(SubExprResult, RemainingExpr);
566 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
572 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
574 EvalResult ReadSizeExpr;
575 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
576 if (ReadSizeExpr.hasError())
577 return std::make_pair(ReadSizeExpr, RemainingExpr);
578 uint64_t ReadSize = ReadSizeExpr.getValue();
579 if (ReadSize < 1 || ReadSize > 8)
580 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
582 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
586 ParseContext LoadCtx(
true);
587 EvalResult LoadAddrExprResult;
588 std::tie(LoadAddrExprResult, RemainingExpr) =
589 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
591 if (LoadAddrExprResult.hasError())
592 return std::make_pair(LoadAddrExprResult,
"");
594 uint64_t LoadAddr = LoadAddrExprResult.getValue();
599 return std::make_pair(0, RemainingExpr);
601 return std::make_pair(
602 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
613 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
614 ParseContext PCtx)
const {
615 EvalResult SubExprResult;
619 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
622 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
623 else if (Expr[0] ==
'*')
624 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
625 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
626 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
627 else if (isdigit(Expr[0]))
628 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
630 return std::make_pair(
631 unexpectedToken(Expr, Expr,
632 "expected '(', '*', identifier, or number"),
"");
634 if (SubExprResult.hasError())
635 return std::make_pair(SubExprResult, RemainingExpr);
639 std::tie(SubExprResult, RemainingExpr) =
640 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
642 return std::make_pair(SubExprResult, RemainingExpr);
652 std::pair<EvalResult, StringRef>
653 evalSliceExpr(
const std::pair<EvalResult, StringRef> &Ctx)
const {
654 EvalResult SubExprResult;
656 std::tie(SubExprResult, RemainingExpr) = Ctx;
661 EvalResult HighBitExpr;
662 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
664 if (HighBitExpr.hasError())
665 return std::make_pair(HighBitExpr, RemainingExpr);
668 return std::make_pair(
669 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
672 EvalResult LowBitExpr;
673 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
675 if (LowBitExpr.hasError())
676 return std::make_pair(LowBitExpr, RemainingExpr);
679 return std::make_pair(
680 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
683 unsigned HighBit = HighBitExpr.getValue();
684 unsigned LowBit = LowBitExpr.getValue();
686 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
687 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
696 std::pair<EvalResult, StringRef>
697 evalComplexExpr(
const std::pair<EvalResult, StringRef> &LHSAndRemaining,
698 ParseContext PCtx)
const {
699 EvalResult LHSResult;
701 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
705 if (LHSResult.hasError() || RemainingExpr ==
"")
706 return std::make_pair(LHSResult, RemainingExpr);
710 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
713 if (BinOp == BinOpToken::Invalid)
714 return std::make_pair(LHSResult, RemainingExpr);
717 EvalResult RHSResult;
718 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
721 if (RHSResult.hasError())
722 return std::make_pair(RHSResult, RemainingExpr);
726 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
728 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
733 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
734 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());
736 if (
auto E = TI.takeError()) {
737 errs() <<
"Error obtaining disassembler: " <<
toString(std::move(E))
742 StringRef SymbolMem = Checker.getSymbolContent(Symbol);
747 TI->Disassembler->getInstruction(Inst,
Size, SymbolBytes, 0,
nulls());
755 auto TripleName =
TT.str();
756 std::string ErrorStr;
760 return make_error<StringError>(
"Error accessing target '" + TripleName +
764 std::unique_ptr<MCSubtargetInfo> STI(
767 return make_error<StringError>(
"Unable to create subtarget for " +
773 return make_error<StringError>(
"Unable to create target register info "
779 std::unique_ptr<MCAsmInfo> MAI(
782 return make_error<StringError>(
"Unable to create target asm info " +
786 auto Ctx = std::make_unique<MCContext>(
Triple(TripleName), MAI.get(),
787 MRI.get(), STI.get());
789 std::unique_ptr<MCDisassembler> Disassembler(
792 return make_error<StringError>(
"Unable to create disassembler for " +
798 return make_error<StringError>(
"Unable to create instruction info for" +
803 Triple(TripleName), 0, *MAI, *MII, *
MRI));
805 return make_error<StringError>(
806 "Unable to create instruction printer for" + TripleName,
809 return TargetInfo({TheTarget, std::move(STI), std::move(
MRI),
810 std::move(MAI), std::move(Ctx), std::move(Disassembler),
811 std::move(MII), std::move(InstPrinter)});
817 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
818 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
821 : IsSymbolValid(
std::
move(IsSymbolValid)),
822 GetSymbolInfo(
std::
move(GetSymbolInfo)),
823 GetSectionInfo(
std::
move(GetSectionInfo)),
824 GetStubInfo(
std::
move(GetStubInfo)), GetGOTInfo(
std::
move(GetGOTInfo)),
826 TF(
std::
move(TF)), ErrStream(ErrStream) {}
829 CheckExpr = CheckExpr.
trim();
830 LLVM_DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr
833 bool Result =
P.evaluate(CheckExpr);
836 << (Result ?
"passed" :
"FAILED") <<
".\n");
842 bool DidAllTestsPass =
true;
843 unsigned NumRules = 0;
845 std::string CheckExpr;
849 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
852 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
853 const char *LineEnd = LineStart;
854 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
858 StringRef Line(LineStart, LineEnd - LineStart);
859 if (Line.starts_with(RulePrefix))
860 CheckExpr += Line.substr(RulePrefix.
size()).str();
863 if (!CheckExpr.empty()) {
865 if (CheckExpr.back() !=
'\\') {
866 DidAllTestsPass &=
check(CheckExpr);
870 CheckExpr.pop_back();
875 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
878 return DidAllTestsPass && (NumRules != 0);
881bool RuntimeDyldCheckerImpl::isSymbolValid(
StringRef Symbol)
const {
882 return IsSymbolValid(Symbol);
886 auto SymInfo = GetSymbolInfo(Symbol);
896 reinterpret_cast<uintptr_t
>(
SymInfo->getContent().data()));
900 auto SymInfo = GetSymbolInfo(Symbol);
906 return SymInfo->getTargetAddress();
910 unsigned Size)
const {
911 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
912 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
913 void *
Ptr =
reinterpret_cast<void*
>(PtrSizedAddr);
917 return support::endian::read<uint8_t>(
Ptr, Endianness);
919 return support::endian::read<uint16_t>(
Ptr, Endianness);
921 return support::endian::read<uint32_t>(
Ptr, Endianness);
923 return support::endian::read<uint64_t>(
Ptr, Endianness);
929 auto SymInfo = GetSymbolInfo(Symbol);
934 return {
SymInfo->getContent().data(),
SymInfo->getContent().size()};
938 auto SymInfo = GetSymbolInfo(Symbol);
943 return SymInfo->getTargetFlags();
947RuntimeDyldCheckerImpl::getTripleForSymbol(
TargetFlagsType Flag)
const {
950 switch (
TT.getArch()) {
967std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
970 auto SecInfo = GetSectionInfo(FileName,
SectionName);
978 return std::make_pair(0, std::move(ErrMsg));
987 if (SecInfo->isZeroFill())
992 Addr = SecInfo->getTargetAddress();
994 return std::make_pair(
Addr,
"");
997std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
999 bool IsInsideLoad,
bool IsStubAddr)
const {
1002 "Kind name filter only supported for stubs");
1004 IsStubAddr ? GetStubInfo(StubContainerName, SymbolName, StubKindFilter)
1014 return std::make_pair((
uint64_t)0, std::move(ErrMsg));
1020 if (StubInfo->isZeroFill())
1021 return std::make_pair((
uint64_t)0,
"Detected zero-filled stub/GOT entry");
1024 Addr = StubInfo->getTargetAddress();
1026 return std::make_pair(
Addr,
"");
1043 return Impl->check(CheckExpr);
1048 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
1051std::pair<uint64_t, std::string>
1053 bool LocalAddress) {
1054 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.
@ 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.