LLVM API Documentation

RuntimeDyldChecker.cpp
Go to the documentation of this file.
00001 //===--- RuntimeDyldChecker.cpp - RuntimeDyld tester framework --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/ADT/STLExtras.h"
00011 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
00012 #include "llvm/MC/MCContext.h"
00013 #include "llvm/MC/MCDisassembler.h"
00014 #include "llvm/MC/MCInst.h"
00015 #include "llvm/Support/StringRefMemoryObject.h"
00016 #include "llvm/Support/Path.h"
00017 #include "RuntimeDyldCheckerImpl.h"
00018 #include "RuntimeDyldImpl.h"
00019 #include <cctype>
00020 #include <memory>
00021 
00022 #define DEBUG_TYPE "rtdyld"
00023 
00024 using namespace llvm;
00025 
00026 namespace llvm {
00027 
00028 // Helper class that implements the language evaluated by RuntimeDyldChecker.
00029 class RuntimeDyldCheckerExprEval {
00030 public:
00031   RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker,
00032                              raw_ostream &ErrStream)
00033       : Checker(Checker) {}
00034 
00035   bool evaluate(StringRef Expr) const {
00036     // Expect equality expression of the form 'LHS = RHS'.
00037     Expr = Expr.trim();
00038     size_t EQIdx = Expr.find('=');
00039 
00040     ParseContext OutsideLoad(false);
00041 
00042     // Evaluate LHS.
00043     StringRef LHSExpr = Expr.substr(0, EQIdx).rtrim();
00044     StringRef RemainingExpr;
00045     EvalResult LHSResult;
00046     std::tie(LHSResult, RemainingExpr) =
00047         evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);
00048     if (LHSResult.hasError())
00049       return handleError(Expr, LHSResult);
00050     if (RemainingExpr != "")
00051       return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr, ""));
00052 
00053     // Evaluate RHS.
00054     StringRef RHSExpr = Expr.substr(EQIdx + 1).ltrim();
00055     EvalResult RHSResult;
00056     std::tie(RHSResult, RemainingExpr) =
00057         evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);
00058     if (RHSResult.hasError())
00059       return handleError(Expr, RHSResult);
00060     if (RemainingExpr != "")
00061       return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr, ""));
00062 
00063     if (LHSResult.getValue() != RHSResult.getValue()) {
00064       Checker.ErrStream << "Expression '" << Expr << "' is false: "
00065                         << format("0x%" PRIx64, LHSResult.getValue())
00066                         << " != " << format("0x%" PRIx64, RHSResult.getValue())
00067                         << "\n";
00068       return false;
00069     }
00070     return true;
00071   }
00072 
00073 private:
00074   // RuntimeDyldCheckerExprEval requires some context when parsing exprs. In
00075   // particular, it needs to know whether a symbol is being evaluated in the
00076   // context of a load, in which case we want the linker's local address for
00077   // the symbol, or outside of a load, in which case we want the symbol's
00078   // address in the remote target.
00079 
00080   struct ParseContext {
00081     bool IsInsideLoad;
00082     ParseContext(bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
00083   };
00084 
00085   const RuntimeDyldCheckerImpl &Checker;
00086 
00087   enum class BinOpToken : unsigned {
00088     Invalid,
00089     Add,
00090     Sub,
00091     BitwiseAnd,
00092     BitwiseOr,
00093     ShiftLeft,
00094     ShiftRight
00095   };
00096 
00097   class EvalResult {
00098   public:
00099     EvalResult() : Value(0), ErrorMsg("") {}
00100     EvalResult(uint64_t Value) : Value(Value), ErrorMsg("") {}
00101     EvalResult(std::string ErrorMsg) : Value(0), ErrorMsg(ErrorMsg) {}
00102     uint64_t getValue() const { return Value; }
00103     bool hasError() const { return ErrorMsg != ""; }
00104     const std::string &getErrorMsg() const { return ErrorMsg; }
00105 
00106   private:
00107     uint64_t Value;
00108     std::string ErrorMsg;
00109   };
00110 
00111   StringRef getTokenForError(StringRef Expr) const {
00112     if (Expr.empty())
00113       return "";
00114 
00115     StringRef Token, Remaining;
00116     if (isalpha(Expr[0]))
00117       std::tie(Token, Remaining) = parseSymbol(Expr);
00118     else if (isdigit(Expr[0]))
00119       std::tie(Token, Remaining) = parseNumberString(Expr);
00120     else {
00121       unsigned TokLen = 1;
00122       if (Expr.startswith("<<") || Expr.startswith(">>"))
00123         TokLen = 2;
00124       Token = Expr.substr(0, TokLen);
00125     }
00126     return Token;
00127   }
00128 
00129   EvalResult unexpectedToken(StringRef TokenStart, StringRef SubExpr,
00130                              StringRef ErrText) const {
00131     std::string ErrorMsg("Encountered unexpected token '");
00132     ErrorMsg += getTokenForError(TokenStart);
00133     if (SubExpr != "") {
00134       ErrorMsg += "' while parsing subexpression '";
00135       ErrorMsg += SubExpr;
00136     }
00137     ErrorMsg += "'";
00138     if (ErrText != "") {
00139       ErrorMsg += " ";
00140       ErrorMsg += ErrText;
00141     }
00142     return EvalResult(std::move(ErrorMsg));
00143   }
00144 
00145   bool handleError(StringRef Expr, const EvalResult &R) const {
00146     assert(R.hasError() && "Not an error result.");
00147     Checker.ErrStream << "Error evaluating expression '" << Expr
00148                       << "': " << R.getErrorMsg() << "\n";
00149     return false;
00150   }
00151 
00152   std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const {
00153     if (Expr.empty())
00154       return std::make_pair(BinOpToken::Invalid, "");
00155 
00156     // Handle the two 2-character tokens.
00157     if (Expr.startswith("<<"))
00158       return std::make_pair(BinOpToken::ShiftLeft, Expr.substr(2).ltrim());
00159     if (Expr.startswith(">>"))
00160       return std::make_pair(BinOpToken::ShiftRight, Expr.substr(2).ltrim());
00161 
00162     // Handle one-character tokens.
00163     BinOpToken Op;
00164     switch (Expr[0]) {
00165     default:
00166       return std::make_pair(BinOpToken::Invalid, Expr);
00167     case '+':
00168       Op = BinOpToken::Add;
00169       break;
00170     case '-':
00171       Op = BinOpToken::Sub;
00172       break;
00173     case '&':
00174       Op = BinOpToken::BitwiseAnd;
00175       break;
00176     case '|':
00177       Op = BinOpToken::BitwiseOr;
00178       break;
00179     }
00180 
00181     return std::make_pair(Op, Expr.substr(1).ltrim());
00182   }
00183 
00184   EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult,
00185                                 const EvalResult &RHSResult) const {
00186     switch (Op) {
00187     default:
00188       llvm_unreachable("Tried to evaluate unrecognized operation.");
00189     case BinOpToken::Add:
00190       return EvalResult(LHSResult.getValue() + RHSResult.getValue());
00191     case BinOpToken::Sub:
00192       return EvalResult(LHSResult.getValue() - RHSResult.getValue());
00193     case BinOpToken::BitwiseAnd:
00194       return EvalResult(LHSResult.getValue() & RHSResult.getValue());
00195     case BinOpToken::BitwiseOr:
00196       return EvalResult(LHSResult.getValue() | RHSResult.getValue());
00197     case BinOpToken::ShiftLeft:
00198       return EvalResult(LHSResult.getValue() << RHSResult.getValue());
00199     case BinOpToken::ShiftRight:
00200       return EvalResult(LHSResult.getValue() >> RHSResult.getValue());
00201     }
00202   }
00203 
00204   // Parse a symbol and return a (string, string) pair representing the symbol
00205   // name and expression remaining to be parsed.
00206   std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const {
00207     size_t FirstNonSymbol = Expr.find_first_not_of("0123456789"
00208                                                    "abcdefghijklmnopqrstuvwxyz"
00209                                                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00210                                                    ":_.$");
00211     return std::make_pair(Expr.substr(0, FirstNonSymbol),
00212                           Expr.substr(FirstNonSymbol).ltrim());
00213   }
00214 
00215   // Evaluate a call to decode_operand. Decode the instruction operand at the
00216   // given symbol and get the value of the requested operand.
00217   // Returns an error if the instruction cannot be decoded, or the requested
00218   // operand is not an immediate.
00219   // On success, retuns a pair containing the value of the operand, plus
00220   // the expression remaining to be evaluated.
00221   std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const {
00222     if (!Expr.startswith("("))
00223       return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
00224     StringRef RemainingExpr = Expr.substr(1).ltrim();
00225     StringRef Symbol;
00226     std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
00227 
00228     if (!Checker.isSymbolValid(Symbol))
00229       return std::make_pair(
00230           EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
00231           "");
00232 
00233     if (!RemainingExpr.startswith(","))
00234       return std::make_pair(
00235           unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), "");
00236     RemainingExpr = RemainingExpr.substr(1).ltrim();
00237 
00238     EvalResult OpIdxExpr;
00239     std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
00240     if (OpIdxExpr.hasError())
00241       return std::make_pair(OpIdxExpr, "");
00242 
00243     if (!RemainingExpr.startswith(")"))
00244       return std::make_pair(
00245           unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
00246     RemainingExpr = RemainingExpr.substr(1).ltrim();
00247 
00248     MCInst Inst;
00249     uint64_t Size;
00250     if (!decodeInst(Symbol, Inst, Size))
00251       return std::make_pair(
00252           EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
00253           "");
00254 
00255     unsigned OpIdx = OpIdxExpr.getValue();
00256     if (OpIdx >= Inst.getNumOperands()) {
00257       std::string ErrMsg;
00258       raw_string_ostream ErrMsgStream(ErrMsg);
00259       ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx)
00260                    << "' for instruction '" << Symbol
00261                    << "'. Instruction has only "
00262                    << format("%i", Inst.getNumOperands())
00263                    << " operands.\nInstruction is:\n  ";
00264       Inst.dump_pretty(ErrMsgStream,
00265                        Checker.Disassembler->getContext().getAsmInfo(),
00266                        Checker.InstPrinter);
00267       return std::make_pair(EvalResult(ErrMsgStream.str()), "");
00268     }
00269 
00270     const MCOperand &Op = Inst.getOperand(OpIdx);
00271     if (!Op.isImm()) {
00272       std::string ErrMsg;
00273       raw_string_ostream ErrMsgStream(ErrMsg);
00274       ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
00275                    << Symbol << "' is not an immediate.\nInstruction is:\n  ";
00276       Inst.dump_pretty(ErrMsgStream,
00277                        Checker.Disassembler->getContext().getAsmInfo(),
00278                        Checker.InstPrinter);
00279 
00280       return std::make_pair(EvalResult(ErrMsgStream.str()), "");
00281     }
00282 
00283     return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);
00284   }
00285 
00286   // Evaluate a call to next_pc.
00287   // Decode the instruction at the given symbol and return the following program
00288   // counter.
00289   // Returns an error if the instruction cannot be decoded.
00290   // On success, returns a pair containing the next PC, plus of the
00291   // expression remaining to be evaluated.
00292   std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr,
00293                                               ParseContext PCtx) const {
00294     if (!Expr.startswith("("))
00295       return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
00296     StringRef RemainingExpr = Expr.substr(1).ltrim();
00297     StringRef Symbol;
00298     std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
00299 
00300     if (!Checker.isSymbolValid(Symbol))
00301       return std::make_pair(
00302           EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
00303           "");
00304 
00305     if (!RemainingExpr.startswith(")"))
00306       return std::make_pair(
00307           unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
00308     RemainingExpr = RemainingExpr.substr(1).ltrim();
00309 
00310     MCInst Inst;
00311     uint64_t InstSize;
00312     if (!decodeInst(Symbol, Inst, InstSize))
00313       return std::make_pair(
00314           EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
00315           "");
00316 
00317     uint64_t SymbolAddr = PCtx.IsInsideLoad
00318                               ? Checker.getSymbolLinkerAddr(Symbol)
00319                               : Checker.getSymbolRemoteAddr(Symbol);
00320     uint64_t NextPC = SymbolAddr + InstSize;
00321 
00322     return std::make_pair(EvalResult(NextPC), RemainingExpr);
00323   }
00324 
00325   // Evaluate a call to stub_addr.
00326   // Look up and return the address of the stub for the given
00327   // (<file name>, <section name>, <symbol name>) tuple.
00328   // On success, returns a pair containing the stub address, plus the expression
00329   // remaining to be evaluated.
00330   std::pair<EvalResult, StringRef> evalStubAddr(StringRef Expr,
00331                                                 ParseContext PCtx) const {
00332     if (!Expr.startswith("("))
00333       return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
00334     StringRef RemainingExpr = Expr.substr(1).ltrim();
00335 
00336     // Handle file-name specially, as it may contain characters that aren't
00337     // legal for symbols.
00338     StringRef FileName;
00339     size_t ComaIdx = RemainingExpr.find(',');
00340     FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
00341     RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
00342 
00343     if (!RemainingExpr.startswith(","))
00344       return std::make_pair(
00345           unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
00346     RemainingExpr = RemainingExpr.substr(1).ltrim();
00347 
00348     StringRef SectionName;
00349     std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
00350 
00351     if (!RemainingExpr.startswith(","))
00352       return std::make_pair(
00353           unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
00354     RemainingExpr = RemainingExpr.substr(1).ltrim();
00355 
00356     StringRef Symbol;
00357     std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
00358 
00359     if (!RemainingExpr.startswith(")"))
00360       return std::make_pair(
00361           unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
00362     RemainingExpr = RemainingExpr.substr(1).ltrim();
00363 
00364     uint64_t StubAddr;
00365     std::string ErrorMsg = "";
00366     std::tie(StubAddr, ErrorMsg) = Checker.getStubAddrFor(
00367         FileName, SectionName, Symbol, PCtx.IsInsideLoad);
00368 
00369     if (ErrorMsg != "")
00370       return std::make_pair(EvalResult(ErrorMsg), "");
00371 
00372     return std::make_pair(EvalResult(StubAddr), RemainingExpr);
00373   }
00374 
00375   std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr,
00376                                                    ParseContext PCtx) const {
00377     if (!Expr.startswith("("))
00378       return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
00379     StringRef RemainingExpr = Expr.substr(1).ltrim();
00380 
00381     // Handle file-name specially, as it may contain characters that aren't
00382     // legal for symbols.
00383     StringRef FileName;
00384     size_t ComaIdx = RemainingExpr.find(',');
00385     FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
00386     RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
00387 
00388     if (!RemainingExpr.startswith(","))
00389       return std::make_pair(
00390           unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
00391     RemainingExpr = RemainingExpr.substr(1).ltrim();
00392 
00393     StringRef SectionName;
00394     std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
00395 
00396     if (!RemainingExpr.startswith(")"))
00397       return std::make_pair(
00398           unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
00399     RemainingExpr = RemainingExpr.substr(1).ltrim();
00400 
00401     uint64_t StubAddr;
00402     std::string ErrorMsg = "";
00403     std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
00404         FileName, SectionName, PCtx.IsInsideLoad);
00405 
00406     if (ErrorMsg != "")
00407       return std::make_pair(EvalResult(ErrorMsg), "");
00408 
00409     return std::make_pair(EvalResult(StubAddr), RemainingExpr);
00410   }
00411 
00412   // Evaluate an identiefer expr, which may be a symbol, or a call to
00413   // one of the builtin functions: get_insn_opcode or get_insn_length.
00414   // Return the result, plus the expression remaining to be parsed.
00415   std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr,
00416                                                       ParseContext PCtx) const {
00417     StringRef Symbol;
00418     StringRef RemainingExpr;
00419     std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
00420 
00421     // Check for builtin function calls.
00422     if (Symbol == "decode_operand")
00423       return evalDecodeOperand(RemainingExpr);
00424     else if (Symbol == "next_pc")
00425       return evalNextPC(RemainingExpr, PCtx);
00426     else if (Symbol == "stub_addr")
00427       return evalStubAddr(RemainingExpr, PCtx);
00428     else if (Symbol == "section_addr")
00429       return evalSectionAddr(RemainingExpr, PCtx);
00430 
00431     if (!Checker.isSymbolValid(Symbol)) {
00432       std::string ErrMsg("No known address for symbol '");
00433       ErrMsg += Symbol;
00434       ErrMsg += "'";
00435       if (Symbol.startswith("L"))
00436         ErrMsg += " (this appears to be an assembler local label - "
00437                   " perhaps drop the 'L'?)";
00438 
00439       return std::make_pair(EvalResult(ErrMsg), "");
00440     }
00441 
00442     // The value for the symbol depends on the context we're evaluating in:
00443     // Inside a load this is the address in the linker's memory, outside a
00444     // load it's the address in the target processes memory.
00445     uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLinkerAddr(Symbol)
00446                                        : Checker.getSymbolRemoteAddr(Symbol);
00447 
00448     // Looks like a plain symbol reference.
00449     return std::make_pair(EvalResult(Value), RemainingExpr);
00450   }
00451 
00452   // Parse a number (hexadecimal or decimal) and return a (string, string)
00453   // pair representing the number and the expression remaining to be parsed.
00454   std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const {
00455     size_t FirstNonDigit = StringRef::npos;
00456     if (Expr.startswith("0x")) {
00457       FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2);
00458       if (FirstNonDigit == StringRef::npos)
00459         FirstNonDigit = Expr.size();
00460     } else {
00461       FirstNonDigit = Expr.find_first_not_of("0123456789");
00462       if (FirstNonDigit == StringRef::npos)
00463         FirstNonDigit = Expr.size();
00464     }
00465     return std::make_pair(Expr.substr(0, FirstNonDigit),
00466                           Expr.substr(FirstNonDigit));
00467   }
00468 
00469   // Evaluate a constant numeric expression (hexidecimal or decimal) and
00470   // return a pair containing the result, and the expression remaining to be
00471   // evaluated.
00472   std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const {
00473     StringRef ValueStr;
00474     StringRef RemainingExpr;
00475     std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
00476 
00477     if (ValueStr.empty() || !isdigit(ValueStr[0]))
00478       return std::make_pair(
00479           unexpectedToken(RemainingExpr, RemainingExpr, "expected number"), "");
00480     uint64_t Value;
00481     ValueStr.getAsInteger(0, Value);
00482     return std::make_pair(EvalResult(Value), RemainingExpr);
00483   }
00484 
00485   // Evaluate an expression of the form "(<expr>)" and return a pair
00486   // containing the result of evaluating <expr>, plus the expression
00487   // remaining to be parsed.
00488   std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr,
00489                                                   ParseContext PCtx) const {
00490     assert(Expr.startswith("(") && "Not a parenthesized expression");
00491     EvalResult SubExprResult;
00492     StringRef RemainingExpr;
00493     std::tie(SubExprResult, RemainingExpr) =
00494         evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim(), PCtx), PCtx);
00495     if (SubExprResult.hasError())
00496       return std::make_pair(SubExprResult, "");
00497     if (!RemainingExpr.startswith(")"))
00498       return std::make_pair(
00499           unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
00500     RemainingExpr = RemainingExpr.substr(1).ltrim();
00501     return std::make_pair(SubExprResult, RemainingExpr);
00502   }
00503 
00504   // Evaluate an expression in one of the following forms:
00505   //   *{<number>}<expr>
00506   // Return a pair containing the result, plus the expression remaining to be
00507   // parsed.
00508   std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const {
00509     assert(Expr.startswith("*") && "Not a load expression");
00510     StringRef RemainingExpr = Expr.substr(1).ltrim();
00511 
00512     // Parse read size.
00513     if (!RemainingExpr.startswith("{"))
00514       return std::make_pair(EvalResult("Expected '{' following '*'."), "");
00515     RemainingExpr = RemainingExpr.substr(1).ltrim();
00516     EvalResult ReadSizeExpr;
00517     std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
00518     if (ReadSizeExpr.hasError())
00519       return std::make_pair(ReadSizeExpr, RemainingExpr);
00520     uint64_t ReadSize = ReadSizeExpr.getValue();
00521     if (ReadSize < 1 || ReadSize > 8)
00522       return std::make_pair(EvalResult("Invalid size for dereference."), "");
00523     if (!RemainingExpr.startswith("}"))
00524       return std::make_pair(EvalResult("Missing '}' for dereference."), "");
00525     RemainingExpr = RemainingExpr.substr(1).ltrim();
00526 
00527     // Evaluate the expression representing the load address.
00528     ParseContext LoadCtx(true);
00529     EvalResult LoadAddrExprResult;
00530     std::tie(LoadAddrExprResult, RemainingExpr) =
00531         evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
00532 
00533     if (LoadAddrExprResult.hasError())
00534       return std::make_pair(LoadAddrExprResult, "");
00535 
00536     uint64_t LoadAddr = LoadAddrExprResult.getValue();
00537 
00538     return std::make_pair(
00539         EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
00540         RemainingExpr);
00541   }
00542 
00543   // Evaluate a "simple" expression. This is any expression that _isn't_ an
00544   // un-parenthesized binary expression.
00545   //
00546   // "Simple" expressions can be optionally bit-sliced. See evalSlicedExpr.
00547   //
00548   // Returns a pair containing the result of the evaluation, plus the
00549   // expression remaining to be parsed.
00550   std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr,
00551                                                   ParseContext PCtx) const {
00552     EvalResult SubExprResult;
00553     StringRef RemainingExpr;
00554 
00555     if (Expr.empty())
00556       return std::make_pair(EvalResult("Unexpected end of expression"), "");
00557 
00558     if (Expr[0] == '(')
00559       std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
00560     else if (Expr[0] == '*')
00561       std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
00562     else if (isalpha(Expr[0]) || Expr[0] == '_')
00563       std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
00564     else if (isdigit(Expr[0]))
00565       std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
00566     else
00567       return std::make_pair(
00568           unexpectedToken(Expr, Expr,
00569                           "expected '(', '*', identifier, or number"), "");
00570 
00571     if (SubExprResult.hasError())
00572       return std::make_pair(SubExprResult, RemainingExpr);
00573 
00574     // Evaluate bit-slice if present.
00575     if (RemainingExpr.startswith("["))
00576       std::tie(SubExprResult, RemainingExpr) =
00577           evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
00578 
00579     return std::make_pair(SubExprResult, RemainingExpr);
00580   }
00581 
00582   // Evaluate a bit-slice of an expression.
00583   // A bit-slice has the form "<expr>[high:low]". The result of evaluating a
00584   // slice is the bits between high and low (inclusive) in the original
00585   // expression, right shifted so that the "low" bit is in position 0 in the
00586   // result.
00587   // Returns a pair containing the result of the slice operation, plus the
00588   // expression remaining to be parsed.
00589   std::pair<EvalResult, StringRef>
00590   evalSliceExpr(std::pair<EvalResult, StringRef> Ctx) const {
00591     EvalResult SubExprResult;
00592     StringRef RemainingExpr;
00593     std::tie(SubExprResult, RemainingExpr) = Ctx;
00594 
00595     assert(RemainingExpr.startswith("[") && "Not a slice expr.");
00596     RemainingExpr = RemainingExpr.substr(1).ltrim();
00597 
00598     EvalResult HighBitExpr;
00599     std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
00600 
00601     if (HighBitExpr.hasError())
00602       return std::make_pair(HighBitExpr, RemainingExpr);
00603 
00604     if (!RemainingExpr.startswith(":"))
00605       return std::make_pair(
00606           unexpectedToken(RemainingExpr, RemainingExpr, "expected ':'"), "");
00607     RemainingExpr = RemainingExpr.substr(1).ltrim();
00608 
00609     EvalResult LowBitExpr;
00610     std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
00611 
00612     if (LowBitExpr.hasError())
00613       return std::make_pair(LowBitExpr, RemainingExpr);
00614 
00615     if (!RemainingExpr.startswith("]"))
00616       return std::make_pair(
00617           unexpectedToken(RemainingExpr, RemainingExpr, "expected ']'"), "");
00618     RemainingExpr = RemainingExpr.substr(1).ltrim();
00619 
00620     unsigned HighBit = HighBitExpr.getValue();
00621     unsigned LowBit = LowBitExpr.getValue();
00622     uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;
00623     uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
00624     return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
00625   }
00626 
00627   // Evaluate a "complex" expression.
00628   // Takes an already evaluated subexpression and checks for the presence of a
00629   // binary operator, computing the result of the binary operation if one is
00630   // found. Used to make arithmetic expressions left-associative.
00631   // Returns a pair containing the ultimate result of evaluating the
00632   // expression, plus the expression remaining to be evaluated.
00633   std::pair<EvalResult, StringRef>
00634   evalComplexExpr(std::pair<EvalResult, StringRef> LHSAndRemaining,
00635                   ParseContext PCtx) const {
00636     EvalResult LHSResult;
00637     StringRef RemainingExpr;
00638     std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
00639 
00640     // If there was an error, or there's nothing left to evaluate, return the
00641     // result.
00642     if (LHSResult.hasError() || RemainingExpr == "")
00643       return std::make_pair(LHSResult, RemainingExpr);
00644 
00645     // Otherwise check if this is a binary expressioan.
00646     BinOpToken BinOp;
00647     std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
00648 
00649     // If this isn't a recognized expression just return.
00650     if (BinOp == BinOpToken::Invalid)
00651       return std::make_pair(LHSResult, RemainingExpr);
00652 
00653     // This is a recognized bin-op. Evaluate the RHS, then evaluate the binop.
00654     EvalResult RHSResult;
00655     std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
00656 
00657     // If there was an error evaluating the RHS, return it.
00658     if (RHSResult.hasError())
00659       return std::make_pair(RHSResult, RemainingExpr);
00660 
00661     // This is a binary expression - evaluate and try to continue as a
00662     // complex expr.
00663     EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
00664 
00665     return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
00666   }
00667 
00668   bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const {
00669     MCDisassembler *Dis = Checker.Disassembler;
00670     StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol);
00671     StringRefMemoryObject SectionBytes(SectionMem, 0);
00672 
00673     MCDisassembler::DecodeStatus S =
00674         Dis->getInstruction(Inst, Size, SectionBytes, 0, nulls(), nulls());
00675 
00676     return (S == MCDisassembler::Success);
00677   }
00678 };
00679 }
00680 
00681 RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld,
00682                                                MCDisassembler *Disassembler,
00683                                                MCInstPrinter *InstPrinter,
00684                                                raw_ostream &ErrStream)
00685     : RTDyld(RTDyld), Disassembler(Disassembler), InstPrinter(InstPrinter),
00686       ErrStream(ErrStream) {
00687   RTDyld.Checker = this;
00688 }
00689 
00690 bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
00691   CheckExpr = CheckExpr.trim();
00692   DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr << "'...\n");
00693   RuntimeDyldCheckerExprEval P(*this, ErrStream);
00694   bool Result = P.evaluate(CheckExpr);
00695   (void)Result;
00696   DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "
00697                << (Result ? "passed" : "FAILED") << ".\n");
00698   return Result;
00699 }
00700 
00701 bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
00702                                                    MemoryBuffer *MemBuf) const {
00703   bool DidAllTestsPass = true;
00704   unsigned NumRules = 0;
00705 
00706   const char *LineStart = MemBuf->getBufferStart();
00707 
00708   // Eat whitespace.
00709   while (LineStart != MemBuf->getBufferEnd() && std::isspace(*LineStart))
00710     ++LineStart;
00711 
00712   while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') {
00713     const char *LineEnd = LineStart;
00714     while (LineEnd != MemBuf->getBufferEnd() && *LineEnd != '\r' &&
00715            *LineEnd != '\n')
00716       ++LineEnd;
00717 
00718     StringRef Line(LineStart, LineEnd - LineStart);
00719     if (Line.startswith(RulePrefix)) {
00720       DidAllTestsPass &= check(Line.substr(RulePrefix.size()));
00721       ++NumRules;
00722     }
00723 
00724     // Eat whitespace.
00725     LineStart = LineEnd;
00726     while (LineStart != MemBuf->getBufferEnd() && std::isspace(*LineStart))
00727       ++LineStart;
00728   }
00729   return DidAllTestsPass && (NumRules != 0);
00730 }
00731 
00732 bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
00733   return getRTDyld().getSymbolAddress(Symbol) != nullptr;
00734 }
00735 
00736 uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const {
00737   return static_cast<uint64_t>(
00738       reinterpret_cast<uintptr_t>(getRTDyld().getSymbolAddress(Symbol)));
00739 }
00740 
00741 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
00742   return getRTDyld().getAnySymbolRemoteAddress(Symbol);
00743 }
00744 
00745 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
00746                                                   unsigned Size) const {
00747   uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr);
00748   assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
00749   uint8_t *Src = reinterpret_cast<uint8_t*>(PtrSizedAddr);
00750   return getRTDyld().readBytesUnaligned(Src, Size);
00751 }
00752 
00753 
00754 std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
00755 RuntimeDyldCheckerImpl::findSectionAddrInfo(StringRef FileName,
00756                                             StringRef SectionName) const {
00757 
00758   auto SectionMapItr = Stubs.find(FileName);
00759   if (SectionMapItr == Stubs.end()) {
00760     std::string ErrorMsg = "File '";
00761     ErrorMsg += FileName;
00762     ErrorMsg += "' not found. ";
00763     if (Stubs.empty())
00764       ErrorMsg += "No stubs registered.";
00765     else {
00766       ErrorMsg += "Available files are:";
00767       for (const auto& StubEntry : Stubs) {
00768         ErrorMsg += " '";
00769         ErrorMsg += StubEntry.first;
00770         ErrorMsg += "'";
00771       }
00772     }
00773     ErrorMsg += "\n";
00774     return std::make_pair(nullptr, ErrorMsg);
00775   }
00776 
00777   auto SectionInfoItr = SectionMapItr->second.find(SectionName);
00778   if (SectionInfoItr == SectionMapItr->second.end())
00779     return std::make_pair(nullptr,
00780                           ("Section '" + SectionName + "' not found in file '" +
00781                            FileName + "'\n").str());
00782 
00783   return std::make_pair(&SectionInfoItr->second, std::string(""));
00784 }
00785 
00786 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
00787     StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
00788 
00789   const SectionAddressInfo *SectionInfo = nullptr;
00790   {
00791     std::string ErrorMsg;
00792     std::tie(SectionInfo, ErrorMsg) =
00793       findSectionAddrInfo(FileName, SectionName);
00794     if (ErrorMsg != "")
00795       return std::make_pair(0, ErrorMsg);
00796   }
00797 
00798   unsigned SectionID = SectionInfo->SectionID;
00799   uint64_t Addr;
00800   if (IsInsideLoad)
00801     Addr =
00802       static_cast<uint64_t>(
00803         reinterpret_cast<uintptr_t>(getRTDyld().Sections[SectionID].Address));
00804   else
00805     Addr = getRTDyld().Sections[SectionID].LoadAddress;
00806 
00807   return std::make_pair(Addr, std::string(""));
00808 }
00809 
00810 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
00811     StringRef FileName, StringRef SectionName, StringRef SymbolName,
00812     bool IsInsideLoad) const {
00813 
00814   const SectionAddressInfo *SectionInfo = nullptr;
00815   {
00816     std::string ErrorMsg;
00817     std::tie(SectionInfo, ErrorMsg) =
00818       findSectionAddrInfo(FileName, SectionName);
00819     if (ErrorMsg != "")
00820       return std::make_pair(0, ErrorMsg);
00821   }
00822 
00823   unsigned SectionID = SectionInfo->SectionID;
00824   const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
00825   auto StubOffsetItr = SymbolStubs.find(SymbolName);
00826   if (StubOffsetItr == SymbolStubs.end())
00827     return std::make_pair(0,
00828                           ("Stub for symbol '" + SymbolName + "' not found. "
00829                            "If '" + SymbolName + "' is an internal symbol this "
00830                            "may indicate that the stub target offset is being "
00831                            "computed incorrectly.\n").str());
00832 
00833   uint64_t StubOffset = StubOffsetItr->second;
00834 
00835   uint64_t Addr;
00836   if (IsInsideLoad) {
00837     uintptr_t SectionBase =
00838         reinterpret_cast<uintptr_t>(getRTDyld().Sections[SectionID].Address);
00839     Addr = static_cast<uint64_t>(SectionBase) + StubOffset;
00840   } else {
00841     uint64_t SectionBase = getRTDyld().Sections[SectionID].LoadAddress;
00842     Addr = SectionBase + StubOffset;
00843   }
00844 
00845   return std::make_pair(Addr, std::string(""));
00846 }
00847 
00848 StringRef
00849 RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
00850   RuntimeDyldImpl::SymbolTableMap::const_iterator pos =
00851       getRTDyld().GlobalSymbolTable.find(Name);
00852   if (pos == getRTDyld().GlobalSymbolTable.end())
00853     return StringRef();
00854   RuntimeDyldImpl::SymbolLoc Loc = pos->second;
00855   uint8_t *SectionAddr = getRTDyld().getSectionAddress(Loc.first);
00856   return StringRef(reinterpret_cast<const char *>(SectionAddr) + Loc.second,
00857                    getRTDyld().Sections[Loc.first].Size - Loc.second);
00858 }
00859 
00860 void RuntimeDyldCheckerImpl::registerSection(
00861     StringRef FilePath, unsigned SectionID) {
00862   StringRef FileName = sys::path::filename(FilePath);
00863   const SectionEntry &Section = getRTDyld().Sections[SectionID];
00864   StringRef SectionName = Section.Name;
00865 
00866   Stubs[FileName][SectionName].SectionID = SectionID;
00867 }
00868 
00869 void RuntimeDyldCheckerImpl::registerStubMap(
00870     StringRef FilePath, unsigned SectionID,
00871     const RuntimeDyldImpl::StubMap &RTDyldStubs) {
00872   StringRef FileName = sys::path::filename(FilePath);
00873   const SectionEntry &Section = getRTDyld().Sections[SectionID];
00874   StringRef SectionName = Section.Name;
00875 
00876   Stubs[FileName][SectionName].SectionID = SectionID;
00877 
00878   for (auto &StubMapEntry : RTDyldStubs) {
00879     std::string SymbolName = "";
00880 
00881     if (StubMapEntry.first.SymbolName)
00882       SymbolName = StubMapEntry.first.SymbolName;
00883     else {
00884       // If this is a (Section, Offset) pair, do a reverse lookup in the
00885       // global symbol table to find the name.
00886       for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
00887         if (GSTEntry.second.first == StubMapEntry.first.SectionID &&
00888             GSTEntry.second.second ==
00889                 static_cast<uint64_t>(StubMapEntry.first.Offset)) {
00890           SymbolName = GSTEntry.first();
00891           break;
00892         }
00893       }
00894     }
00895 
00896     if (SymbolName != "")
00897       Stubs[FileName][SectionName].StubOffsets[SymbolName] =
00898         StubMapEntry.second;
00899   }
00900 }
00901 
00902 RuntimeDyldChecker::RuntimeDyldChecker(RuntimeDyld &RTDyld,
00903                                        MCDisassembler *Disassembler,
00904                                        MCInstPrinter *InstPrinter,
00905                                        raw_ostream &ErrStream)
00906     : Impl(make_unique<RuntimeDyldCheckerImpl>(RTDyld, Disassembler,
00907                                                InstPrinter, ErrStream)) {}
00908 
00909 RuntimeDyldChecker::~RuntimeDyldChecker() {}
00910 
00911 RuntimeDyld& RuntimeDyldChecker::getRTDyld() {
00912   return Impl->RTDyld;
00913 }
00914 
00915 const RuntimeDyld& RuntimeDyldChecker::getRTDyld() const {
00916   return Impl->RTDyld;
00917 }
00918 
00919 bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
00920   return Impl->check(CheckExpr);
00921 }
00922 
00923 bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
00924                                                MemoryBuffer *MemBuf) const {
00925   return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
00926 }
00927 
00928 std::pair<uint64_t, std::string>
00929 RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
00930                                    bool LinkerAddress) {
00931   return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
00932 }