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) {}
89 enum class BinOpToken :
unsigned {
101 EvalResult() :
Value(0) {}
103 EvalResult(std::string ErrorMsg)
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);
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()),
239 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
241 case BinOpToken::Add: {
243 std::tie(
Number, RemainingExpr) = evalNumberExpr(RemainingExpr);
247 case BinOpToken::Invalid:
250 return std::make_pair(
251 unexpectedToken(RemainingExpr, RemainingExpr,
252 "expected '+' for offset or ',' if no offset"),
257 return std::make_pair(
258 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ','"),
"");
261 EvalResult OpIdxExpr;
262 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
263 if (OpIdxExpr.hasError())
264 return std::make_pair(OpIdxExpr,
"");
267 return std::make_pair(
268 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
274 return std::make_pair(
275 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
278 unsigned OpIdx = OpIdxExpr.getValue();
282 ErrMsgStream <<
"Invalid operand index '" <<
format(
"%i", OpIdx)
283 <<
"' for instruction '" <<
Symbol
284 <<
"'. Instruction has only "
286 <<
" operands.\nInstruction is:\n ";
287 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
288 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
295 ErrMsgStream <<
"Operand '" <<
format(
"%i", OpIdx) <<
"' of instruction '"
296 <<
Symbol <<
"' is not an immediate.\nInstruction is:\n ";
297 Inst.
dump_pretty(ErrMsgStream, Checker.InstPrinter);
299 return std::make_pair(EvalResult(ErrMsgStream.str()),
"");
302 return std::make_pair(EvalResult(
Op.getImm()), RemainingExpr);
311 std::pair<EvalResult, StringRef> evalNextPC(
StringRef Expr,
312 ParseContext PCtx)
const {
314 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
317 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
319 if (!Checker.isSymbolValid(Symbol))
320 return std::make_pair(
321 EvalResult((
"Cannot decode unknown symbol '" + Symbol +
"'").str()),
325 return std::make_pair(
326 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ')'"),
"");
331 if (!decodeInst(Symbol, Inst, InstSize, 0))
332 return std::make_pair(
333 EvalResult((
"Couldn't decode instruction at '" + Symbol +
"'").str()),
336 uint64_t SymbolAddr = PCtx.IsInsideLoad
337 ? Checker.getSymbolLocalAddr(Symbol)
338 : Checker.getSymbolRemoteAddr(Symbol);
339 uint64_t NextPC = SymbolAddr + InstSize;
341 return std::make_pair(EvalResult(NextPC), RemainingExpr);
349 std::pair<EvalResult, StringRef>
350 evalStubOrGOTAddr(
StringRef Expr, ParseContext PCtx,
bool IsStubAddr)
const {
352 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
358 size_t ComaIdx = RemainingExpr.
find(
',');
359 StubContainerName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
360 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
363 return std::make_pair(
364 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
368 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
371 return std::make_pair(
372 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
376 std::string ErrorMsg;
377 std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor(
378 StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr);
381 return std::make_pair(EvalResult(ErrorMsg),
"");
383 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
386 std::pair<EvalResult, StringRef> evalSectionAddr(
StringRef Expr,
387 ParseContext PCtx)
const {
389 return std::make_pair(unexpectedToken(Expr, Expr,
"expected '('"),
"");
395 size_t ComaIdx = RemainingExpr.
find(
',');
396 FileName = RemainingExpr.
substr(0, ComaIdx).
rtrim();
397 RemainingExpr = RemainingExpr.
substr(ComaIdx).
ltrim();
400 return std::make_pair(
401 unexpectedToken(RemainingExpr, Expr,
"expected ','"),
"");
405 size_t CloseParensIdx = RemainingExpr.
find(
')');
407 RemainingExpr = RemainingExpr.
substr(CloseParensIdx).
ltrim();
410 return std::make_pair(
411 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
415 std::string ErrorMsg;
416 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
420 return std::make_pair(EvalResult(ErrorMsg),
"");
422 return std::make_pair(EvalResult(StubAddr), RemainingExpr);
428 std::pair<EvalResult, StringRef> evalIdentifierExpr(
StringRef Expr,
429 ParseContext PCtx)
const {
432 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
435 if (Symbol ==
"decode_operand")
436 return evalDecodeOperand(RemainingExpr);
437 else if (Symbol ==
"next_pc")
438 return evalNextPC(RemainingExpr, PCtx);
439 else if (Symbol ==
"stub_addr")
440 return evalStubOrGOTAddr(RemainingExpr, PCtx,
true);
441 else if (Symbol ==
"got_addr")
442 return evalStubOrGOTAddr(RemainingExpr, PCtx,
false);
443 else if (Symbol ==
"section_addr")
444 return evalSectionAddr(RemainingExpr, PCtx);
446 if (!Checker.isSymbolValid(Symbol)) {
447 std::string ErrMsg(
"No known address for symbol '");
450 if (
Symbol.startswith(
"L"))
451 ErrMsg +=
" (this appears to be an assembler local label - "
452 " perhaps drop the 'L'?)";
454 return std::make_pair(EvalResult(ErrMsg),
"");
460 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
461 : Checker.getSymbolRemoteAddr(Symbol);
464 return std::make_pair(EvalResult(
Value), RemainingExpr);
469 std::pair<StringRef, StringRef> parseNumberString(
StringRef Expr)
const {
474 FirstNonDigit = Expr.
size();
478 FirstNonDigit = Expr.
size();
480 return std::make_pair(Expr.
substr(0, FirstNonDigit),
481 Expr.
substr(FirstNonDigit));
487 std::pair<EvalResult, StringRef> evalNumberExpr(
StringRef Expr)
const {
490 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
492 if (ValueStr.
empty() || !isdigit(ValueStr[0]))
493 return std::make_pair(
494 unexpectedToken(RemainingExpr, RemainingExpr,
"expected number"),
"");
497 return std::make_pair(EvalResult(
Value), RemainingExpr);
503 std::pair<EvalResult, StringRef> evalParensExpr(
StringRef Expr,
504 ParseContext PCtx)
const {
506 EvalResult SubExprResult;
508 std::tie(SubExprResult, RemainingExpr) =
509 evalComplexExpr(evalSimpleExpr(Expr.
substr(1).
ltrim(), PCtx), PCtx);
510 if (SubExprResult.hasError())
511 return std::make_pair(SubExprResult,
"");
513 return std::make_pair(
514 unexpectedToken(RemainingExpr, Expr,
"expected ')'"),
"");
516 return std::make_pair(SubExprResult, RemainingExpr);
523 std::pair<EvalResult, StringRef> evalLoadExpr(
StringRef Expr)
const {
529 return std::make_pair(EvalResult(
"Expected '{' following '*'."),
"");
531 EvalResult ReadSizeExpr;
532 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
533 if (ReadSizeExpr.hasError())
534 return std::make_pair(ReadSizeExpr, RemainingExpr);
535 uint64_t ReadSize = ReadSizeExpr.getValue();
536 if (ReadSize < 1 || ReadSize > 8)
537 return std::make_pair(EvalResult(
"Invalid size for dereference."),
"");
539 return std::make_pair(EvalResult(
"Missing '}' for dereference."),
"");
543 ParseContext LoadCtx(
true);
544 EvalResult LoadAddrExprResult;
545 std::tie(LoadAddrExprResult, RemainingExpr) =
546 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
548 if (LoadAddrExprResult.hasError())
549 return std::make_pair(LoadAddrExprResult,
"");
551 uint64_t LoadAddr = LoadAddrExprResult.getValue();
556 return std::make_pair(0, RemainingExpr);
558 return std::make_pair(
559 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
570 std::pair<EvalResult, StringRef> evalSimpleExpr(
StringRef Expr,
571 ParseContext PCtx)
const {
572 EvalResult SubExprResult;
576 return std::make_pair(EvalResult(
"Unexpected end of expression"),
"");
579 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
580 else if (Expr[0] ==
'*')
581 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
582 else if (isalpha(Expr[0]) || Expr[0] ==
'_')
583 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
584 else if (isdigit(Expr[0]))
585 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
587 return std::make_pair(
588 unexpectedToken(Expr, Expr,
589 "expected '(', '*', identifier, or number"),
"");
591 if (SubExprResult.hasError())
592 return std::make_pair(SubExprResult, RemainingExpr);
596 std::tie(SubExprResult, RemainingExpr) =
597 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
599 return std::make_pair(SubExprResult, RemainingExpr);
609 std::pair<EvalResult, StringRef>
610 evalSliceExpr(
const std::pair<EvalResult, StringRef> &Ctx)
const {
611 EvalResult SubExprResult;
613 std::tie(SubExprResult, RemainingExpr) = Ctx;
618 EvalResult HighBitExpr;
619 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
621 if (HighBitExpr.hasError())
622 return std::make_pair(HighBitExpr, RemainingExpr);
625 return std::make_pair(
626 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ':'"),
"");
629 EvalResult LowBitExpr;
630 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
632 if (LowBitExpr.hasError())
633 return std::make_pair(LowBitExpr, RemainingExpr);
636 return std::make_pair(
637 unexpectedToken(RemainingExpr, RemainingExpr,
"expected ']'"),
"");
640 unsigned HighBit = HighBitExpr.getValue();
641 unsigned LowBit = LowBitExpr.getValue();
643 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
644 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
653 std::pair<EvalResult, StringRef>
654 evalComplexExpr(
const std::pair<EvalResult, StringRef> &LHSAndRemaining,
655 ParseContext PCtx)
const {
656 EvalResult LHSResult;
658 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
662 if (LHSResult.hasError() || RemainingExpr ==
"")
663 return std::make_pair(LHSResult, RemainingExpr);
667 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
670 if (BinOp == BinOpToken::Invalid)
671 return std::make_pair(LHSResult, RemainingExpr);
674 EvalResult RHSResult;
675 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
678 if (RHSResult.hasError())
679 return std::make_pair(RHSResult, RemainingExpr);
683 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
685 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
691 StringRef SymbolMem = Checker.getSymbolContent(Symbol);
704 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
705 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
709 : IsSymbolValid(
std::
move(IsSymbolValid)),
710 GetSymbolInfo(
std::
move(GetSymbolInfo)),
711 GetSectionInfo(
std::
move(GetSectionInfo)),
712 GetStubInfo(
std::
move(GetStubInfo)), GetGOTInfo(
std::
move(GetGOTInfo)),
713 Endianness(Endianness), Disassembler(Disassembler),
714 InstPrinter(InstPrinter), ErrStream(ErrStream) {}
717 CheckExpr = CheckExpr.
trim();
718 LLVM_DEBUG(
dbgs() <<
"RuntimeDyldChecker: Checking '" << CheckExpr
721 bool Result =
P.evaluate(CheckExpr);
724 << (Result ?
"passed" :
"FAILED") <<
".\n");
730 bool DidAllTestsPass =
true;
731 unsigned NumRules = 0;
733 std::string CheckExpr;
737 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
740 while (LineStart != MemBuf->
getBufferEnd() && *LineStart !=
'\0') {
741 const char *LineEnd = LineStart;
742 while (LineEnd != MemBuf->
getBufferEnd() && *LineEnd !=
'\r' &&
746 StringRef Line(LineStart, LineEnd - LineStart);
747 if (Line.startswith(RulePrefix))
748 CheckExpr += Line.substr(RulePrefix.
size()).str();
751 if (!CheckExpr.empty()) {
753 if (CheckExpr.back() !=
'\\') {
754 DidAllTestsPass &=
check(CheckExpr);
758 CheckExpr.pop_back();
763 while (LineStart != MemBuf->
getBufferEnd() && isSpace(*LineStart))
766 return DidAllTestsPass && (NumRules != 0);
769bool RuntimeDyldCheckerImpl::isSymbolValid(
StringRef Symbol)
const {
770 return IsSymbolValid(Symbol);
774 auto SymInfo = GetSymbolInfo(Symbol);
784 reinterpret_cast<uintptr_t
>(
SymInfo->getContent().data()));
788 auto SymInfo = GetSymbolInfo(Symbol);
794 return SymInfo->getTargetAddress();
798 unsigned Size)
const {
799 uintptr_t PtrSizedAddr =
static_cast<uintptr_t
>(SrcAddr);
800 assert(PtrSizedAddr == SrcAddr &&
"Linker memory pointer out-of-range.");
801 void *
Ptr =
reinterpret_cast<void*
>(PtrSizedAddr);
805 return support::endian::read<uint8_t>(
Ptr, Endianness);
807 return support::endian::read<uint16_t>(
Ptr, Endianness);
809 return support::endian::read<uint32_t>(
Ptr, Endianness);
811 return support::endian::read<uint64_t>(
Ptr, Endianness);
817 auto SymInfo = GetSymbolInfo(Symbol);
822 return {
SymInfo->getContent().data(),
SymInfo->getContent().size()};
825std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
828 auto SecInfo = GetSectionInfo(FileName,
SectionName);
836 return std::make_pair(0, std::move(ErrMsg));
845 if (SecInfo->isZeroFill())
850 Addr = SecInfo->getTargetAddress();
852 return std::make_pair(
Addr,
"");
855std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
857 bool IsStubAddr)
const {
859 auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName)
869 return std::make_pair((
uint64_t)0, std::move(ErrMsg));
875 if (StubInfo->isZeroFill())
876 return std::make_pair((
uint64_t)0,
"Detected zero-filled stub/GOT entry");
879 Addr = StubInfo->getTargetAddress();
881 return std::make_pair(
Addr,
"");
893 std::
move(GetGOTInfo), Endianness, Disassembler, InstPrinter,
899 return Impl->check(CheckExpr);
904 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
907std::pair<uint64_t, std::string>
910 return Impl->getSectionAddr(FileName,
SectionName, LocalAddress);
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Superclass for all disassemblers.
DecodeStatus
Ternary decode status.
virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const =0
Returns the disassembly of a single instruction.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Instances of this class represent a single low-level machine instruction.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
unsigned getNumOperands() const
const MCOperand & getOperand(unsigned i) const
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, support::endianness Endianness, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, 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, support::endianness Endianness, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, 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.
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.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
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.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...