LLVM  16.0.0git
RuntimeDyldChecker.cpp
Go to the documentation of this file.
1 //===--- RuntimeDyldChecker.cpp - RuntimeDyld tester framework --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "RuntimeDyldCheckerImpl.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Path.h"
20 #include <cctype>
21 #include <memory>
22 #include <utility>
23 
24 #define DEBUG_TYPE "rtdyld"
25 
26 using namespace llvm;
27 
28 namespace llvm {
29 
30 // Helper class that implements the language evaluated by RuntimeDyldChecker.
32 public:
34  raw_ostream &ErrStream)
35  : Checker(Checker) {}
36 
37  bool evaluate(StringRef Expr) const {
38  // Expect equality expression of the form 'LHS = RHS'.
39  Expr = Expr.trim();
40  size_t EQIdx = Expr.find('=');
41 
42  ParseContext OutsideLoad(false);
43 
44  // Evaluate LHS.
45  StringRef LHSExpr = Expr.substr(0, EQIdx).rtrim();
46  StringRef RemainingExpr;
47  EvalResult LHSResult;
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, ""));
54 
55  // Evaluate RHS.
56  StringRef RHSExpr = Expr.substr(EQIdx + 1).ltrim();
57  EvalResult RHSResult;
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, ""));
64 
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())
69  << "\n";
70  return false;
71  }
72  return true;
73  }
74 
75 private:
76  // RuntimeDyldCheckerExprEval requires some context when parsing exprs. In
77  // particular, it needs to know whether a symbol is being evaluated in the
78  // context of a load, in which case we want the linker's local address for
79  // the symbol, or outside of a load, in which case we want the symbol's
80  // address in the remote target.
81 
82  struct ParseContext {
83  bool IsInsideLoad;
84  ParseContext(bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
85  };
86 
87  const RuntimeDyldCheckerImpl &Checker;
88 
89  enum class BinOpToken : unsigned {
90  Invalid,
91  Add,
92  Sub,
93  BitwiseAnd,
94  BitwiseOr,
95  ShiftLeft,
96  ShiftRight
97  };
98 
99  class EvalResult {
100  public:
101  EvalResult() : Value(0) {}
102  EvalResult(uint64_t Value) : Value(Value) {}
103  EvalResult(std::string ErrorMsg)
104  : Value(0), ErrorMsg(std::move(ErrorMsg)) {}
105  uint64_t getValue() const { return Value; }
106  bool hasError() const { return ErrorMsg != ""; }
107  const std::string &getErrorMsg() const { return ErrorMsg; }
108 
109  private:
110  uint64_t Value;
111  std::string ErrorMsg;
112  };
113 
114  StringRef getTokenForError(StringRef Expr) const {
115  if (Expr.empty())
116  return "";
117 
118  StringRef Token, Remaining;
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);
123  else {
124  unsigned TokLen = 1;
125  if (Expr.startswith("<<") || Expr.startswith(">>"))
126  TokLen = 2;
127  Token = Expr.substr(0, TokLen);
128  }
129  return Token;
130  }
131 
132  EvalResult unexpectedToken(StringRef TokenStart, StringRef SubExpr,
133  StringRef ErrText) const {
134  std::string ErrorMsg("Encountered unexpected token '");
135  ErrorMsg += getTokenForError(TokenStart);
136  if (SubExpr != "") {
137  ErrorMsg += "' while parsing subexpression '";
138  ErrorMsg += SubExpr;
139  }
140  ErrorMsg += "'";
141  if (ErrText != "") {
142  ErrorMsg += " ";
143  ErrorMsg += ErrText;
144  }
145  return EvalResult(std::move(ErrorMsg));
146  }
147 
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";
152  return false;
153  }
154 
155  std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const {
156  if (Expr.empty())
157  return std::make_pair(BinOpToken::Invalid, "");
158 
159  // Handle the two 2-character tokens.
160  if (Expr.startswith("<<"))
161  return std::make_pair(BinOpToken::ShiftLeft, Expr.substr(2).ltrim());
162  if (Expr.startswith(">>"))
163  return std::make_pair(BinOpToken::ShiftRight, Expr.substr(2).ltrim());
164 
165  // Handle one-character tokens.
166  BinOpToken Op;
167  switch (Expr[0]) {
168  default:
169  return std::make_pair(BinOpToken::Invalid, Expr);
170  case '+':
171  Op = BinOpToken::Add;
172  break;
173  case '-':
174  Op = BinOpToken::Sub;
175  break;
176  case '&':
177  Op = BinOpToken::BitwiseAnd;
178  break;
179  case '|':
180  Op = BinOpToken::BitwiseOr;
181  break;
182  }
183 
184  return std::make_pair(Op, Expr.substr(1).ltrim());
185  }
186 
187  EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult,
188  const EvalResult &RHSResult) const {
189  switch (Op) {
190  default:
191  llvm_unreachable("Tried to evaluate unrecognized operation.");
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());
204  }
205  }
206 
207  // Parse a symbol and return a (string, string) pair representing the symbol
208  // name and expression remaining to be parsed.
209  std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const {
210  size_t FirstNonSymbol = Expr.find_first_not_of("0123456789"
211  "abcdefghijklmnopqrstuvwxyz"
212  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
213  ":_.$");
214  return std::make_pair(Expr.substr(0, FirstNonSymbol),
215  Expr.substr(FirstNonSymbol).ltrim());
216  }
217 
218  // Evaluate a call to decode_operand. Decode the instruction operand at the
219  // given symbol and get the value of the requested operand.
220  // Returns an error if the instruction cannot be decoded, or the requested
221  // operand is not an immediate.
222  // On success, returns a pair containing the value of the operand, plus
223  // the expression remaining to be evaluated.
224  std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const {
225  if (!Expr.startswith("("))
226  return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
227  StringRef RemainingExpr = Expr.substr(1).ltrim();
229  std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
230 
231  if (!Checker.isSymbolValid(Symbol))
232  return std::make_pair(
233  EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
234  "");
235 
236  // if there is an offset number expr
237  int64_t Offset = 0;
238  BinOpToken BinOp;
239  std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
240  switch (BinOp) {
241  case BinOpToken::Add: {
242  EvalResult Number;
243  std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr);
244  Offset = Number.getValue();
245  break;
246  }
247  case BinOpToken::Invalid:
248  break;
249  default:
250  return std::make_pair(
251  unexpectedToken(RemainingExpr, RemainingExpr,
252  "expected '+' for offset or ',' if no offset"),
253  "");
254  }
255 
256  if (!RemainingExpr.startswith(","))
257  return std::make_pair(
258  unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), "");
259  RemainingExpr = RemainingExpr.substr(1).ltrim();
260 
261  EvalResult OpIdxExpr;
262  std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
263  if (OpIdxExpr.hasError())
264  return std::make_pair(OpIdxExpr, "");
265 
266  if (!RemainingExpr.startswith(")"))
267  return std::make_pair(
268  unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
269  RemainingExpr = RemainingExpr.substr(1).ltrim();
270 
271  MCInst Inst;
272  uint64_t Size;
273  if (!decodeInst(Symbol, Inst, Size, Offset))
274  return std::make_pair(
275  EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
276  "");
277 
278  unsigned OpIdx = OpIdxExpr.getValue();
279  if (OpIdx >= Inst.getNumOperands()) {
280  std::string ErrMsg;
281  raw_string_ostream ErrMsgStream(ErrMsg);
282  ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx)
283  << "' for instruction '" << Symbol
284  << "'. Instruction has only "
285  << format("%i", Inst.getNumOperands())
286  << " operands.\nInstruction is:\n ";
287  Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
288  return std::make_pair(EvalResult(ErrMsgStream.str()), "");
289  }
290 
291  const MCOperand &Op = Inst.getOperand(OpIdx);
292  if (!Op.isImm()) {
293  std::string ErrMsg;
294  raw_string_ostream ErrMsgStream(ErrMsg);
295  ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
296  << Symbol << "' is not an immediate.\nInstruction is:\n ";
297  Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
298 
299  return std::make_pair(EvalResult(ErrMsgStream.str()), "");
300  }
301 
302  return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);
303  }
304 
305  // Evaluate a call to next_pc.
306  // Decode the instruction at the given symbol and return the following program
307  // counter.
308  // Returns an error if the instruction cannot be decoded.
309  // On success, returns a pair containing the next PC, plus of the
310  // expression remaining to be evaluated.
311  std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr,
312  ParseContext PCtx) const {
313  if (!Expr.startswith("("))
314  return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
315  StringRef RemainingExpr = Expr.substr(1).ltrim();
317  std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
318 
319  if (!Checker.isSymbolValid(Symbol))
320  return std::make_pair(
321  EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
322  "");
323 
324  if (!RemainingExpr.startswith(")"))
325  return std::make_pair(
326  unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
327  RemainingExpr = RemainingExpr.substr(1).ltrim();
328 
329  MCInst Inst;
330  uint64_t InstSize;
331  if (!decodeInst(Symbol, Inst, InstSize, 0))
332  return std::make_pair(
333  EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
334  "");
335 
336  uint64_t SymbolAddr = PCtx.IsInsideLoad
337  ? Checker.getSymbolLocalAddr(Symbol)
338  : Checker.getSymbolRemoteAddr(Symbol);
339  uint64_t NextPC = SymbolAddr + InstSize;
340 
341  return std::make_pair(EvalResult(NextPC), RemainingExpr);
342  }
343 
344  // Evaluate a call to stub_addr/got_addr.
345  // Look up and return the address of the stub for the given
346  // (<file name>, <section name>, <symbol name>) tuple.
347  // On success, returns a pair containing the stub address, plus the expression
348  // remaining to be evaluated.
349  std::pair<EvalResult, StringRef>
350  evalStubOrGOTAddr(StringRef Expr, ParseContext PCtx, bool IsStubAddr) const {
351  if (!Expr.startswith("("))
352  return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
353  StringRef RemainingExpr = Expr.substr(1).ltrim();
354 
355  // Handle file-name specially, as it may contain characters that aren't
356  // legal for symbols.
357  StringRef StubContainerName;
358  size_t ComaIdx = RemainingExpr.find(',');
359  StubContainerName = RemainingExpr.substr(0, ComaIdx).rtrim();
360  RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
361 
362  if (!RemainingExpr.startswith(","))
363  return std::make_pair(
364  unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
365  RemainingExpr = RemainingExpr.substr(1).ltrim();
366 
368  std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
369 
370  if (!RemainingExpr.startswith(")"))
371  return std::make_pair(
372  unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
373  RemainingExpr = RemainingExpr.substr(1).ltrim();
374 
375  uint64_t StubAddr;
376  std::string ErrorMsg;
377  std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor(
378  StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr);
379 
380  if (ErrorMsg != "")
381  return std::make_pair(EvalResult(ErrorMsg), "");
382 
383  return std::make_pair(EvalResult(StubAddr), RemainingExpr);
384  }
385 
386  std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr,
387  ParseContext PCtx) const {
388  if (!Expr.startswith("("))
389  return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
390  StringRef RemainingExpr = Expr.substr(1).ltrim();
391 
392  // Handle file-name specially, as it may contain characters that aren't
393  // legal for symbols.
394  StringRef FileName;
395  size_t ComaIdx = RemainingExpr.find(',');
396  FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
397  RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
398 
399  if (!RemainingExpr.startswith(","))
400  return std::make_pair(
401  unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
402  RemainingExpr = RemainingExpr.substr(1).ltrim();
403 
405  size_t CloseParensIdx = RemainingExpr.find(')');
406  SectionName = RemainingExpr.substr(0, CloseParensIdx).rtrim();
407  RemainingExpr = RemainingExpr.substr(CloseParensIdx).ltrim();
408 
409  if (!RemainingExpr.startswith(")"))
410  return std::make_pair(
411  unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
412  RemainingExpr = RemainingExpr.substr(1).ltrim();
413 
414  uint64_t StubAddr;
415  std::string ErrorMsg;
416  std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
417  FileName, SectionName, PCtx.IsInsideLoad);
418 
419  if (ErrorMsg != "")
420  return std::make_pair(EvalResult(ErrorMsg), "");
421 
422  return std::make_pair(EvalResult(StubAddr), RemainingExpr);
423  }
424 
425  // Evaluate an identiefer expr, which may be a symbol, or a call to
426  // one of the builtin functions: get_insn_opcode or get_insn_length.
427  // Return the result, plus the expression remaining to be parsed.
428  std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr,
429  ParseContext PCtx) const {
431  StringRef RemainingExpr;
432  std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
433 
434  // Check for builtin function calls.
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);
445 
446  if (!Checker.isSymbolValid(Symbol)) {
447  std::string ErrMsg("No known address for symbol '");
448  ErrMsg += Symbol;
449  ErrMsg += "'";
450  if (Symbol.startswith("L"))
451  ErrMsg += " (this appears to be an assembler local label - "
452  " perhaps drop the 'L'?)";
453 
454  return std::make_pair(EvalResult(ErrMsg), "");
455  }
456 
457  // The value for the symbol depends on the context we're evaluating in:
458  // Inside a load this is the address in the linker's memory, outside a
459  // load it's the address in the target processes memory.
460  uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
461  : Checker.getSymbolRemoteAddr(Symbol);
462 
463  // Looks like a plain symbol reference.
464  return std::make_pair(EvalResult(Value), RemainingExpr);
465  }
466 
467  // Parse a number (hexadecimal or decimal) and return a (string, string)
468  // pair representing the number and the expression remaining to be parsed.
469  std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const {
470  size_t FirstNonDigit = StringRef::npos;
471  if (Expr.startswith("0x")) {
472  FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2);
473  if (FirstNonDigit == StringRef::npos)
474  FirstNonDigit = Expr.size();
475  } else {
476  FirstNonDigit = Expr.find_first_not_of("0123456789");
477  if (FirstNonDigit == StringRef::npos)
478  FirstNonDigit = Expr.size();
479  }
480  return std::make_pair(Expr.substr(0, FirstNonDigit),
481  Expr.substr(FirstNonDigit));
482  }
483 
484  // Evaluate a constant numeric expression (hexadecimal or decimal) and
485  // return a pair containing the result, and the expression remaining to be
486  // evaluated.
487  std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const {
488  StringRef ValueStr;
489  StringRef RemainingExpr;
490  std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
491 
492  if (ValueStr.empty() || !isdigit(ValueStr[0]))
493  return std::make_pair(
494  unexpectedToken(RemainingExpr, RemainingExpr, "expected number"), "");
495  uint64_t Value;
496  ValueStr.getAsInteger(0, Value);
497  return std::make_pair(EvalResult(Value), RemainingExpr);
498  }
499 
500  // Evaluate an expression of the form "(<expr>)" and return a pair
501  // containing the result of evaluating <expr>, plus the expression
502  // remaining to be parsed.
503  std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr,
504  ParseContext PCtx) const {
505  assert(Expr.startswith("(") && "Not a parenthesized expression");
506  EvalResult SubExprResult;
507  StringRef RemainingExpr;
508  std::tie(SubExprResult, RemainingExpr) =
509  evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim(), PCtx), PCtx);
510  if (SubExprResult.hasError())
511  return std::make_pair(SubExprResult, "");
512  if (!RemainingExpr.startswith(")"))
513  return std::make_pair(
514  unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
515  RemainingExpr = RemainingExpr.substr(1).ltrim();
516  return std::make_pair(SubExprResult, RemainingExpr);
517  }
518 
519  // Evaluate an expression in one of the following forms:
520  // *{<number>}<expr>
521  // Return a pair containing the result, plus the expression remaining to be
522  // parsed.
523  std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const {
524  assert(Expr.startswith("*") && "Not a load expression");
525  StringRef RemainingExpr = Expr.substr(1).ltrim();
526 
527  // Parse read size.
528  if (!RemainingExpr.startswith("{"))
529  return std::make_pair(EvalResult("Expected '{' following '*'."), "");
530  RemainingExpr = RemainingExpr.substr(1).ltrim();
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."), "");
538  if (!RemainingExpr.startswith("}"))
539  return std::make_pair(EvalResult("Missing '}' for dereference."), "");
540  RemainingExpr = RemainingExpr.substr(1).ltrim();
541 
542  // Evaluate the expression representing the load address.
543  ParseContext LoadCtx(true);
544  EvalResult LoadAddrExprResult;
545  std::tie(LoadAddrExprResult, RemainingExpr) =
546  evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
547 
548  if (LoadAddrExprResult.hasError())
549  return std::make_pair(LoadAddrExprResult, "");
550 
551  uint64_t LoadAddr = LoadAddrExprResult.getValue();
552 
553  // If there is no error but the content pointer is null then this is a
554  // zero-fill symbol/section.
555  if (LoadAddr == 0)
556  return std::make_pair(0, RemainingExpr);
557 
558  return std::make_pair(
559  EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
560  RemainingExpr);
561  }
562 
563  // Evaluate a "simple" expression. This is any expression that _isn't_ an
564  // un-parenthesized binary expression.
565  //
566  // "Simple" expressions can be optionally bit-sliced. See evalSlicedExpr.
567  //
568  // Returns a pair containing the result of the evaluation, plus the
569  // expression remaining to be parsed.
570  std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr,
571  ParseContext PCtx) const {
572  EvalResult SubExprResult;
573  StringRef RemainingExpr;
574 
575  if (Expr.empty())
576  return std::make_pair(EvalResult("Unexpected end of expression"), "");
577 
578  if (Expr[0] == '(')
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);
586  else
587  return std::make_pair(
588  unexpectedToken(Expr, Expr,
589  "expected '(', '*', identifier, or number"), "");
590 
591  if (SubExprResult.hasError())
592  return std::make_pair(SubExprResult, RemainingExpr);
593 
594  // Evaluate bit-slice if present.
595  if (RemainingExpr.startswith("["))
596  std::tie(SubExprResult, RemainingExpr) =
597  evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
598 
599  return std::make_pair(SubExprResult, RemainingExpr);
600  }
601 
602  // Evaluate a bit-slice of an expression.
603  // A bit-slice has the form "<expr>[high:low]". The result of evaluating a
604  // slice is the bits between high and low (inclusive) in the original
605  // expression, right shifted so that the "low" bit is in position 0 in the
606  // result.
607  // Returns a pair containing the result of the slice operation, plus the
608  // expression remaining to be parsed.
609  std::pair<EvalResult, StringRef>
610  evalSliceExpr(const std::pair<EvalResult, StringRef> &Ctx) const {
611  EvalResult SubExprResult;
612  StringRef RemainingExpr;
613  std::tie(SubExprResult, RemainingExpr) = Ctx;
614 
615  assert(RemainingExpr.startswith("[") && "Not a slice expr.");
616  RemainingExpr = RemainingExpr.substr(1).ltrim();
617 
618  EvalResult HighBitExpr;
619  std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
620 
621  if (HighBitExpr.hasError())
622  return std::make_pair(HighBitExpr, RemainingExpr);
623 
624  if (!RemainingExpr.startswith(":"))
625  return std::make_pair(
626  unexpectedToken(RemainingExpr, RemainingExpr, "expected ':'"), "");
627  RemainingExpr = RemainingExpr.substr(1).ltrim();
628 
629  EvalResult LowBitExpr;
630  std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
631 
632  if (LowBitExpr.hasError())
633  return std::make_pair(LowBitExpr, RemainingExpr);
634 
635  if (!RemainingExpr.startswith("]"))
636  return std::make_pair(
637  unexpectedToken(RemainingExpr, RemainingExpr, "expected ']'"), "");
638  RemainingExpr = RemainingExpr.substr(1).ltrim();
639 
640  unsigned HighBit = HighBitExpr.getValue();
641  unsigned LowBit = LowBitExpr.getValue();
642  uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;
643  uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
644  return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
645  }
646 
647  // Evaluate a "complex" expression.
648  // Takes an already evaluated subexpression and checks for the presence of a
649  // binary operator, computing the result of the binary operation if one is
650  // found. Used to make arithmetic expressions left-associative.
651  // Returns a pair containing the ultimate result of evaluating the
652  // expression, plus the expression remaining to be evaluated.
653  std::pair<EvalResult, StringRef>
654  evalComplexExpr(const std::pair<EvalResult, StringRef> &LHSAndRemaining,
655  ParseContext PCtx) const {
656  EvalResult LHSResult;
657  StringRef RemainingExpr;
658  std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
659 
660  // If there was an error, or there's nothing left to evaluate, return the
661  // result.
662  if (LHSResult.hasError() || RemainingExpr == "")
663  return std::make_pair(LHSResult, RemainingExpr);
664 
665  // Otherwise check if this is a binary expressioan.
666  BinOpToken BinOp;
667  std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
668 
669  // If this isn't a recognized expression just return.
670  if (BinOp == BinOpToken::Invalid)
671  return std::make_pair(LHSResult, RemainingExpr);
672 
673  // This is a recognized bin-op. Evaluate the RHS, then evaluate the binop.
674  EvalResult RHSResult;
675  std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
676 
677  // If there was an error evaluating the RHS, return it.
678  if (RHSResult.hasError())
679  return std::make_pair(RHSResult, RemainingExpr);
680 
681  // This is a binary expression - evaluate and try to continue as a
682  // complex expr.
683  EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
684 
685  return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
686  }
687 
688  bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size,
689  int64_t Offset) const {
690  MCDisassembler *Dis = Checker.Disassembler;
691  StringRef SymbolMem = Checker.getSymbolContent(Symbol);
692  ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin() + Offset,
693  SymbolMem.size() - Offset);
694 
696  Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
697 
698  return (S == MCDisassembler::Success);
699  }
700 };
701 } // namespace llvm
702 
704  IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
705  GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
706  GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
707  MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
708  raw_ostream &ErrStream)
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) {}
715 
717  CheckExpr = CheckExpr.trim();
718  LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr
719  << "'...\n");
720  RuntimeDyldCheckerExprEval P(*this, ErrStream);
721  bool Result = P.evaluate(CheckExpr);
722  (void)Result;
723  LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "
724  << (Result ? "passed" : "FAILED") << ".\n");
725  return Result;
726 }
727 
729  MemoryBuffer *MemBuf) const {
730  bool DidAllTestsPass = true;
731  unsigned NumRules = 0;
732 
733  std::string CheckExpr;
734  const char *LineStart = MemBuf->getBufferStart();
735 
736  // Eat whitespace.
737  while (LineStart != MemBuf->getBufferEnd() && isSpace(*LineStart))
738  ++LineStart;
739 
740  while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') {
741  const char *LineEnd = LineStart;
742  while (LineEnd != MemBuf->getBufferEnd() && *LineEnd != '\r' &&
743  *LineEnd != '\n')
744  ++LineEnd;
745 
746  StringRef Line(LineStart, LineEnd - LineStart);
747  if (Line.startswith(RulePrefix))
748  CheckExpr += Line.substr(RulePrefix.size()).str();
749 
750  // If there's a check expr string...
751  if (!CheckExpr.empty()) {
752  // ... and it's complete then run it, otherwise remove the trailer '\'.
753  if (CheckExpr.back() != '\\') {
754  DidAllTestsPass &= check(CheckExpr);
755  CheckExpr.clear();
756  ++NumRules;
757  } else
758  CheckExpr.pop_back();
759  }
760 
761  // Eat whitespace.
762  LineStart = LineEnd;
763  while (LineStart != MemBuf->getBufferEnd() && isSpace(*LineStart))
764  ++LineStart;
765  }
766  return DidAllTestsPass && (NumRules != 0);
767 }
768 
769 bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
770  return IsSymbolValid(Symbol);
771 }
772 
773 uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
774  auto SymInfo = GetSymbolInfo(Symbol);
775  if (!SymInfo) {
776  logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
777  return 0;
778  }
779 
780  if (SymInfo->isZeroFill())
781  return 0;
782 
783  return static_cast<uint64_t>(
784  reinterpret_cast<uintptr_t>(SymInfo->getContent().data()));
785 }
786 
787 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
788  auto SymInfo = GetSymbolInfo(Symbol);
789  if (!SymInfo) {
790  logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
791  return 0;
792  }
793 
794  return SymInfo->getTargetAddress();
795 }
796 
797 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
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);
802 
803  switch (Size) {
804  case 1:
805  return support::endian::read<uint8_t>(Ptr, Endianness);
806  case 2:
807  return support::endian::read<uint16_t>(Ptr, Endianness);
808  case 4:
809  return support::endian::read<uint32_t>(Ptr, Endianness);
810  case 8:
811  return support::endian::read<uint64_t>(Ptr, Endianness);
812  }
813  llvm_unreachable("Unsupported read size");
814 }
815 
816 StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const {
817  auto SymInfo = GetSymbolInfo(Symbol);
818  if (!SymInfo) {
819  logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
820  return StringRef();
821  }
822  return {SymInfo->getContent().data(), SymInfo->getContent().size()};
823 }
824 
825 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
826  StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
827 
828  auto SecInfo = GetSectionInfo(FileName, SectionName);
829  if (!SecInfo) {
830  std::string ErrMsg;
831  {
832  raw_string_ostream ErrMsgStream(ErrMsg);
833  logAllUnhandledErrors(SecInfo.takeError(), ErrMsgStream,
834  "RTDyldChecker: ");
835  }
836  return std::make_pair(0, std::move(ErrMsg));
837  }
838 
839  // If this address is being looked up in "load" mode, return the content
840  // pointer, otherwise return the target address.
841 
842  uint64_t Addr = 0;
843 
844  if (IsInsideLoad) {
845  if (SecInfo->isZeroFill())
846  Addr = 0;
847  else
848  Addr = pointerToJITTargetAddress(SecInfo->getContent().data());
849  } else
850  Addr = SecInfo->getTargetAddress();
851 
852  return std::make_pair(Addr, "");
853 }
854 
855 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
856  StringRef StubContainerName, StringRef SymbolName, bool IsInsideLoad,
857  bool IsStubAddr) const {
858 
859  auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName)
860  : GetGOTInfo(StubContainerName, SymbolName);
861 
862  if (!StubInfo) {
863  std::string ErrMsg;
864  {
865  raw_string_ostream ErrMsgStream(ErrMsg);
866  logAllUnhandledErrors(StubInfo.takeError(), ErrMsgStream,
867  "RTDyldChecker: ");
868  }
869  return std::make_pair((uint64_t)0, std::move(ErrMsg));
870  }
871 
872  uint64_t Addr = 0;
873 
874  if (IsInsideLoad) {
875  if (StubInfo->isZeroFill())
876  return std::make_pair((uint64_t)0, "Detected zero-filled stub/GOT entry");
877  Addr = pointerToJITTargetAddress(StubInfo->getContent().data());
878  } else
879  Addr = StubInfo->getTargetAddress();
880 
881  return std::make_pair(Addr, "");
882 }
883 
885  IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
886  GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
888  MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
889  raw_ostream &ErrStream)
890  : Impl(::std::make_unique<RuntimeDyldCheckerImpl>(
891  std::move(IsSymbolValid), std::move(GetSymbolInfo),
892  std::move(GetSectionInfo), std::move(GetStubInfo),
893  std::move(GetGOTInfo), Endianness, Disassembler, InstPrinter,
894  ErrStream)) {}
895 
897 
898 bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
899  return Impl->check(CheckExpr);
900 }
901 
903  MemoryBuffer *MemBuf) const {
904  return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
905 }
906 
907 std::pair<uint64_t, std::string>
909  bool LocalAddress) {
910  return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
911 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
MemoryBuffer.h
llvm::RuntimeDyldChecker::IsSymbolValidFunction
std::function< bool(StringRef Symbol)> IsSymbolValidFunction
Definition: RuntimeDyldChecker.h:135
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::msgpack::Endianness
constexpr support::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
Definition: MsgPack.h:24
llvm::ms_demangle::IntrinsicFunctionKind::BitwiseAnd
@ BitwiseAnd
RuntimeDyldChecker.h
MCDisassembler.h
llvm::StringRef::trim
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:796
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:628
llvm::RuntimeDyldChecker::check
bool check(StringRef CheckExpr) const
Check a single expression against the attached RuntimeDyld instance.
Definition: RuntimeDyldChecker.cpp:898
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:52
Path.h
llvm::RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl
RuntimeDyldCheckerImpl(IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, llvm::raw_ostream &ErrStream)
Definition: RuntimeDyldChecker.cpp:703
llvm::MachO::Invalid
@ Invalid
Invalid file type.
Definition: InterfaceFile.h:55
MSVCErrorWorkarounds.h
llvm::StringRef::substr
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:553
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::nulls
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
Definition: raw_ostream.cpp:900
llvm::MCInst::getNumOperands
unsigned getNumOperands() const
Definition: MCInst.h:208
llvm::RuntimeDyldChecker::RuntimeDyldChecker
RuntimeDyldChecker(IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, raw_ostream &ErrStream)
Definition: RuntimeDyldChecker.cpp:884
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:241
llvm::RuntimeDyldCheckerExprEval::evaluate
bool evaluate(StringRef Expr) const
Definition: RuntimeDyldChecker.cpp:37
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::BitmaskEnumDetail::Mask
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.
Definition: BitmaskEnum.h:80
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:248
llvm::MemoryBuffer::getBufferEnd
const char * getBufferEnd() const
Definition: MemoryBuffer.h:66
MCContext.h
llvm::RuntimeDyldChecker::GetGOTInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef GOTContainer, StringRef TargetName)> GetGOTInfoFunction
Definition: RuntimeDyldChecker.h:143
llvm::RuntimeDyldChecker::getSectionAddr
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...
Definition: RuntimeDyldChecker.cpp:908
llvm::MCDisassembler::Success
@ Success
Definition: MCDisassembler.h:112
MCInst.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::AMDGPU::ElfNote::SectionName
const char SectionName[]
Definition: AMDGPUPTNote.h:24
llvm::MCDisassembler::getInstruction
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.
llvm::RuntimeDyldCheckerExprEval
Definition: RuntimeDyldChecker.cpp:31
llvm::MCDisassembler::DecodeStatus
DecodeStatus
Ternary decode status.
Definition: MCDisassembler.h:109
llvm::StringRef::getAsInteger
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:455
llvm::RuntimeDyldChecker::GetSectionInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef FileName, StringRef SectionName)> GetSectionInfoFunction
Definition: RuntimeDyldChecker.h:139
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
llvm::RuntimeDyldCheckerImpl::checkAllRulesInBuffer
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
Definition: RuntimeDyldChecker.cpp:728
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
uint64_t
llvm::MCInstPrinter
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:43
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::MCDisassembler
Superclass for all disassemblers.
Definition: MCDisassembler.h:85
llvm::StringRef::rtrim
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:784
StringExtras.h
llvm::StringRef::ltrim
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:772
llvm::RuntimeDyldChecker::GetSymbolInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef SymbolName)> GetSymbolInfoFunction
Definition: RuntimeDyldChecker.h:137
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1676
llvm::object::Token
Definition: COFFModuleDefinition.cpp:51
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::StringRef::find_first_not_of
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.
Definition: StringRef.cpp:248
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:107
llvm::ArrayRef< uint8_t >
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
Number
uint32_t Number
Definition: Profile.cpp:47
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
RuntimeDyldCheckerImpl.h
llvm::RuntimeDyldCheckerImpl
Definition: RuntimeDyldCheckerImpl.h:16
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::pointerToJITTargetAddress
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Definition: JITSymbol.h:69
llvm::logAllUnhandledErrors
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:63
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:129
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:65
std
Definition: BitVector.h:851
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::SectionName
Definition: DWARFSection.h:21
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::RuntimeDyldCheckerImpl::check
bool check(StringRef CheckExpr) const
Definition: RuntimeDyldChecker.cpp:716
llvm::RuntimeDyldCheckerExprEval::RuntimeDyldCheckerExprEval
RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker, raw_ostream &ErrStream)
Definition: RuntimeDyldChecker.cpp:33
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:185
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::MCInst::dump_pretty
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.
Definition: MCInst.cpp:81
SymInfo
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
Definition: DWARFContext.cpp:1458
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:213
llvm::StringRef::find
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:273
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::RuntimeDyldChecker::~RuntimeDyldChecker
~RuntimeDyldChecker()
llvm::RuntimeDyldChecker::checkAllRulesInBuffer
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const
Scan the given memory buffer for lines beginning with the string in RulePrefix.
Definition: RuntimeDyldChecker.cpp:902
Endian.h
llvm::ms_demangle::IntrinsicFunctionKind::BitwiseOr
@ BitwiseOr
llvm::RuntimeDyldChecker::GetStubInfoFunction
std::function< Expected< MemoryRegionInfo >(StringRef StubContainer, StringRef TargetName)> GetStubInfoFunction
Definition: RuntimeDyldChecker.h:141
llvm::Value
LLVM Value Representation.
Definition: Value.h:74