1cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===--- RuntimeDyldChecker.cpp - RuntimeDyld tester framework --*- C++ -*-===// 2cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 3cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// The LLVM Compiler Infrastructure 4cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 5cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// This file is distributed under the University of Illinois Open Source 6cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// License. See LICENSE.TXT for details. 7cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 8cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===----------------------------------------------------------------------===// 9cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 10cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 11cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCContext.h" 12cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCDisassembler.h" 13cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCInst.h" 14cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Support/StringRefMemoryObject.h" 15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "RuntimeDyldImpl.h" 16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <cctype> 17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <memory> 18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 19cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#define DEBUG_TYPE "rtdyld" 20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesusing namespace llvm; 22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesnamespace llvm { 24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 25cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Helper class that implements the language evaluated by RuntimeDyldChecker. 26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines class RuntimeDyldCheckerExprEval { 27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines public: 28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RuntimeDyldCheckerExprEval(const RuntimeDyldChecker &Checker, 30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines llvm::raw_ostream &ErrStream) 31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : Checker(Checker), ErrStream(ErrStream) {} 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool evaluate(StringRef Expr) const { 34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Expect equality expression of the form 'LHS = RHS'. 35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr = Expr.trim(); 36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines size_t EQIdx = Expr.find('='); 37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate LHS. 39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef LHSExpr = Expr.substr(0, EQIdx).rtrim(); 40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult LHSResult; 42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(LHSResult, RemainingExpr) = 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines evalComplexExpr(evalSimpleExpr(LHSExpr)); 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (LHSResult.hasError()) 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return handleError(Expr, LHSResult); 46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RemainingExpr != "") 47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr, "")); 48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate RHS. 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RHSExpr = Expr.substr(EQIdx + 1).ltrim(); 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult RHSResult; 52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(RHSResult, RemainingExpr) = 53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines evalComplexExpr(evalSimpleExpr(RHSExpr)); 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RHSResult.hasError()) 55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return handleError(Expr, RHSResult); 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RemainingExpr != "") 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr, "")); 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (LHSResult.getValue() != RHSResult.getValue()) { 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrStream << "Expression '" << Expr << "' is false: " 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format("0x%lx", LHSResult.getValue()) << " != " 62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format("0x%lx", RHSResult.getValue()) << "\n"; 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 67cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines private: 69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const RuntimeDyldChecker &Checker; 70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines llvm::raw_ostream &ErrStream; 71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 72cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines enum class BinOpToken : unsigned { Invalid, Add, Sub, BitwiseAnd, 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BitwiseOr, ShiftLeft, ShiftRight }; 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines class EvalResult { 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines public: 77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult() 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : Value(0), ErrorMsg("") {} 79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult(uint64_t Value) 80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : Value(Value), ErrorMsg("") {} 81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult(std::string ErrorMsg) 82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : Value(0), ErrorMsg(ErrorMsg) {} 83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t getValue() const { return Value; } 84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasError() const { return ErrorMsg != ""; } 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const std::string& getErrorMsg() const { return ErrorMsg; } 86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines private: 87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Value; 88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string ErrorMsg; 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 91cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef getTokenForError(StringRef Expr) const { 92cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.empty()) 93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ""; 94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Token, Remaining; 96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isalpha(Expr[0])) 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Token, Remaining) = parseSymbol(Expr); 98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (isdigit(Expr[0])) 99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Token, Remaining) = parseNumberString(Expr); 100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else { 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned TokLen = 1; 102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.startswith("<<") || Expr.startswith(">>")) 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TokLen = 2; 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Token = Expr.substr(0, TokLen); 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Token; 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult unexpectedToken(StringRef TokenStart, 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SubExpr, 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef ErrText) const { 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string ErrorMsg("Encountered unexpected token '"); 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += getTokenForError(TokenStart); 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SubExpr != "") { 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += "' while parsing subexpression '"; 116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += SubExpr; 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += "'"; 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ErrText != "") { 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += " "; 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorMsg += ErrText; 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(std::move(ErrorMsg)); 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool handleError(StringRef Expr, const EvalResult &R) const { 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(R.hasError() && "Not an error result."); 128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrStream << "Error evaluating expression '" << Expr << "': " 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << R.getErrorMsg() << "\n"; 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const { 134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.empty()) 135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(BinOpToken::Invalid, ""); 136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Handle the two 2-character tokens. 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.startswith("<<")) 139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(BinOpToken::ShiftLeft, 140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr.substr(2).ltrim()); 141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.startswith(">>")) 142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(BinOpToken::ShiftRight, 143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr.substr(2).ltrim()); 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Handle one-character tokens. 146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BinOpToken Op; 147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (Expr[0]) { 148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: return std::make_pair(BinOpToken::Invalid, Expr); 149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case '+': Op = BinOpToken::Add; break; 150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case '-': Op = BinOpToken::Sub; break; 151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case '&': Op = BinOpToken::BitwiseAnd; break; 152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case '|': Op = BinOpToken::BitwiseOr; break; 153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(Op, Expr.substr(1).ltrim()); 156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult, 159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const EvalResult &RHSResult) const { 160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (Op) { 161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: llvm_unreachable("Tried to evaluate unrecognized operation."); 162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::Add: 163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() + RHSResult.getValue()); 164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::Sub: 165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() - RHSResult.getValue()); 166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::BitwiseAnd: 167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() & RHSResult.getValue()); 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::BitwiseOr: 169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() | RHSResult.getValue()); 170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::ShiftLeft: 171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() << RHSResult.getValue()); 172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case BinOpToken::ShiftRight: 173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return EvalResult(LHSResult.getValue() >> RHSResult.getValue()); 174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Parse a symbol and return a (string, string) pair representing the symbol 178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // name and expression remaining to be parsed. 179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const { 180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines size_t FirstNonSymbol = 181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr.find_first_not_of("0123456789" 182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "abcdefghijklmnopqrstuvwxyz" 183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ":_"); 185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(Expr.substr(0, FirstNonSymbol), 186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr.substr(FirstNonSymbol).ltrim()); 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a call to decode_operand. Decode the instruction operand at the 190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // given symbol and get the value of the requested operand. 191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns an error if the instruction cannot be decoded, or the requested 192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // operand is not an immediate. 193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // On success, retuns a pair containing the value of the operand, plus 194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the expression remaining to be evaluated. 195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const { 196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Expr.startswith("(")) 197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr = Expr.substr(1).ltrim(); 199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Symbol; 200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Checker.checkSymbolIsValidForLoad(Symbol)) 203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(("Cannot decode unknown symbol '" + 204cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Symbol + "'").str()), 205cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 206cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 207cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(",")) 208cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ','"), 210cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 211cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 212cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult OpIdxExpr; 214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OpIdxExpr.hasError()) 216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(OpIdxExpr, ""); 217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(")")) 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ')'"), 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCInst Inst; 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Size; 226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!decodeInst(Symbol, Inst, Size)) 227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(("Couldn't decode instruction at '" + 228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Symbol + "'").str()), 229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned OpIdx = OpIdxExpr.getValue(); 232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OpIdx >= Inst.getNumOperands()) { 233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string ErrMsg; 234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines raw_string_ostream ErrMsgStream(ErrMsg); 235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx) 236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " for instruction '" << Symbol 237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ". Instruction has only " 238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format("%i", Inst.getNumOperands()) << " operands."; 239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(ErrMsgStream.str()), ""); 240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCOperand &Op = Inst.getOperand(OpIdx); 243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Op.isImm()) { 244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string ErrMsg; 245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines raw_string_ostream ErrMsgStream(ErrMsg); 246cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrMsgStream << "Operand '" << format("%i", OpIdx) 247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "' of instruction '" << Symbol 248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "' is not an immediate.\nInstruction is:\n "; 249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Inst.dump_pretty(ErrMsgStream, 250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Checker.Disassembler->getContext().getAsmInfo(), 251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Checker.InstPrinter); 252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(ErrMsgStream.str()), ""); 254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(Op.getImm()), RemainingExpr); 257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a call to next_pc. Decode the instruction at the given 260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // symbol and return the following program counter.. 261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns an error if the instruction cannot be decoded. 262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // On success, returns a pair containing the next PC, plus the length of the 263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // expression remaining to be evaluated. 264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr) const { 265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Expr.startswith("(")) 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr = Expr.substr(1).ltrim(); 268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Symbol; 269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Checker.checkSymbolIsValidForLoad(Symbol)) 272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(("Cannot decode unknown symbol '" 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines + Symbol + "'").str()), 274cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 275cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 276cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(")")) 277cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ')'"), 279cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCInst Inst; 283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Size; 284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!decodeInst(Symbol, Inst, Size)) 285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(("Couldn't decode instruction at '" + 286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Symbol + "'").str()), 287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t NextPC = Checker.getSymbolAddress(Symbol) + Size; 289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(NextPC), RemainingExpr); 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate an identiefer expr, which may be a symbol, or a call to 294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // one of the builtin functions: get_insn_opcode or get_insn_length. 295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Return the result, plus the expression remaining to be parsed. 296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr) const { 297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Symbol; 298cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 299cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Symbol, RemainingExpr) = parseSymbol(Expr); 300cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 301cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Check for builtin function calls. 302cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Symbol == "decode_operand") 303cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return evalDecodeOperand(RemainingExpr); 304cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Symbol == "next_pc") 305cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return evalNextPC(RemainingExpr); 306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Looks like a plain symbol reference. 308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(Checker.getSymbolAddress(Symbol)), 309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr); 310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Parse a number (hexadecimal or decimal) and return a (string, string) 313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // pair representing the number and the expression remaining to be parsed. 314cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const { 315cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines size_t FirstNonDigit = StringRef::npos; 316cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.startswith("0x")) { 317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2); 318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (FirstNonDigit == StringRef::npos) 319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FirstNonDigit = Expr.size(); 320cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 321cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FirstNonDigit = Expr.find_first_not_of("0123456789"); 322cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (FirstNonDigit == StringRef::npos) 323cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FirstNonDigit = Expr.size(); 324cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 325cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(Expr.substr(0, FirstNonDigit), 326cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Expr.substr(FirstNonDigit)); 327cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 328cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 329cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a constant numeric expression (hexidecimal or decimal) and 330cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // return a pair containing the result, and the expression remaining to be 331cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // evaluated. 332cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const { 333cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef ValueStr; 334cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 335cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr); 336cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 337cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ValueStr.empty() || !isdigit(ValueStr[0])) 338cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected number"), 340cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 341cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Value; 342cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ValueStr.getAsInteger(0, Value); 343cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(Value), RemainingExpr); 344cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 345cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 346cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate an expression of the form "(<expr>)" and return a pair 347cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // containing the result of evaluating <expr>, plus the expression 348cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // remaining to be parsed. 349cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr) const { 350cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(Expr.startswith("(") && "Not a parenthesized expression"); 351cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult SubExprResult; 352cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 353cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = 354cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim())); 355cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SubExprResult.hasError()) 356cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(SubExprResult, ""); 357cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(")")) 358cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, Expr, 359cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ')'"), 360cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 361cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 362cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(SubExprResult, RemainingExpr); 363cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 364cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 365cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate an expression in one of the following forms: 366cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // *{<number>}<symbol> 367cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // *{<number>}(<symbol> + <number>) 368cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // *{<number>}(<symbol> - <number>) 369cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Return a pair containing the result, plus the expression remaining to be 370cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // parsed. 371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const { 372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(Expr.startswith("*") && "Not a load expression"); 373cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr = Expr.substr(1).ltrim(); 374cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Parse read size. 375cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith("{")) 376cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Expected '{' following '*'."), ""); 377cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 378cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult ReadSizeExpr; 379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 380cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ReadSizeExpr.hasError()) 381cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(ReadSizeExpr, RemainingExpr); 382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t ReadSize = ReadSizeExpr.getValue(); 383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ReadSize < 1 || ReadSize > 8) 384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Invalid size for dereference."), ""); 385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith("}")) 386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Missing '}' for dereference."), ""); 387cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 388cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 389cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Check for '(symbol +/- constant)' form. 390cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool SymbolPlusConstant = false; 391cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RemainingExpr.startswith("(")) { 392cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SymbolPlusConstant = true; 393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 394cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 395cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 396cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Read symbol. 397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Symbol; 398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 399cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Checker.checkSymbolIsValidForLoad(Symbol)) 401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(("Cannot dereference unknown symbol '" 402cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines + Symbol + "'").str()), 403cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Set up defaut offset. 406cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int64_t Offset = 0; 407cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 408cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Handle "+/- constant)" portion if necessary. 409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SymbolPlusConstant) { 410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines char OpChar = RemainingExpr[0]; 411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OpChar != '+' && OpChar != '-') 412cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Invalid operator in load address."), 413cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 414cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 415cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 416cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult OffsetExpr; 417cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(OffsetExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 418cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 419cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Offset = (OpChar == '+') ? 420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OffsetExpr.getValue() : -1 * OffsetExpr.getValue(); 421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 422cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(")")) 423cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Missing ')' in load address."), 424cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 425cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 426cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 427cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 428cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 429cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair( 430cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult(Checker.readMemoryAtSymbol(Symbol, Offset, ReadSize)), 431cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr); 432cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 433cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 434cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a "simple" expression. This is any expression that _isn't_ an 435cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // un-parenthesized binary expression. 436cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 437cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // "Simple" expressions can be optionally bit-sliced. See evalSlicedExpr. 438cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 439cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns a pair containing the result of the evaluation, plus the 440cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // expression remaining to be parsed. 441cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr) const { 442cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult SubExprResult; 443cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 444cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 445cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr.empty()) 446cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult("Unexpected end of expression"), ""); 447cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 448cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Expr[0] == '(') 449cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr); 450cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Expr[0] == '*') 451cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr); 452cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (isalpha(Expr[0])) 453cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr); 454cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (isdigit(Expr[0])) 455cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr); 456cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 457cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SubExprResult.hasError()) 458cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(SubExprResult, RemainingExpr); 459cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 460cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate bit-slice if present. 461cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RemainingExpr.startswith("[")) 462cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = 463cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr)); 464cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 465cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(SubExprResult, RemainingExpr); 466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a bit-slice of an expression. 469cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // A bit-slice has the form "<expr>[high:low]". The result of evaluating a 470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // slice is the bits between high and low (inclusive) in the original 471cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // expression, right shifted so that the "low" bit is in position 0 in the 472cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // result. 473cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns a pair containing the result of the slice operation, plus the 474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // expression remaining to be parsed. 475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalSliceExpr( 476cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> Ctx) const{ 477cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult SubExprResult; 478cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 479cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(SubExprResult, RemainingExpr) = Ctx; 480cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 481cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(RemainingExpr.startswith("[") && "Not a slice expr."); 482cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 483cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 484cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult HighBitExpr; 485cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 486cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 487cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (HighBitExpr.hasError()) 488cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(HighBitExpr, RemainingExpr); 489cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 490cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith(":")) 491cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 492cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ':'"), 493cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 494cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 495cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 496cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult LowBitExpr; 497cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 498cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 499cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (LowBitExpr.hasError()) 500cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(LowBitExpr, RemainingExpr); 501cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 502cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RemainingExpr.startswith("]")) 503cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(unexpectedToken(RemainingExpr, RemainingExpr, 504cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "expected ']'"), 505cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ""); 506cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RemainingExpr = RemainingExpr.substr(1).ltrim(); 507cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 508cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned HighBit = HighBitExpr.getValue(); 509cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned LowBit = LowBitExpr.getValue(); 510cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1; 511cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask; 512cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(EvalResult(SlicedValue), RemainingExpr); 513cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 514cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 515cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Evaluate a "complex" expression. 516cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Takes an already evaluated subexpression and checks for the presence of a 517cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // binary operator, computing the result of the binary operation if one is 518cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // found. Used to make arithmetic expressions left-associative. 519cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns a pair containing the ultimate result of evaluating the 520cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // expression, plus the expression remaining to be evaluated. 521cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> evalComplexExpr( 522cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<EvalResult, StringRef> Ctx) const { 523cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult LHSResult; 524cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef RemainingExpr; 525cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(LHSResult, RemainingExpr) = Ctx; 526cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 527cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If there was an error, or there's nothing left to evaluate, return the 528cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // result. 529cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (LHSResult.hasError() || RemainingExpr == "") 530cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(LHSResult, RemainingExpr); 531cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Otherwise check if this is a binary expressioan. 533cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BinOpToken BinOp; 534cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr); 535cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 536cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If this isn't a recognized expression just return. 537cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (BinOp == BinOpToken::Invalid) 538cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(LHSResult, RemainingExpr); 539cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 540cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This is a recognized bin-op. Evaluate the RHS, then evaluate the binop. 541cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult RHSResult; 542cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr); 543cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 544cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If there was an error evaluating the RHS, return it. 545cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RHSResult.hasError()) 546cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::make_pair(RHSResult, RemainingExpr); 547cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 548cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This is a binary expression - evaluate and try to continue as a 549cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // complex expr. 550cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult)); 551cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 552cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr)); 553cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 554cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 555cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const { 556cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCDisassembler *Dis = Checker.Disassembler; 557cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol); 558cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRefMemoryObject SectionBytes(SectionMem, 0); 559cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 560cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCDisassembler::DecodeStatus S = 561cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Dis->getInstruction(Inst, Size, SectionBytes, 0, nulls(), nulls()); 562cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 563cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (S == MCDisassembler::Success); 564cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 565cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 566cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 567cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 568cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 569cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 570cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool RuntimeDyldChecker::check(StringRef CheckExpr) const { 571cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CheckExpr = CheckExpr.trim(); 572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DEBUG(llvm::dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr 573cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "'...\n"); 574cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RuntimeDyldCheckerExprEval P(*this, ErrStream); 575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool Result = P.evaluate(CheckExpr); 576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (void)Result; 577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DEBUG(llvm::dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' " 578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << (Result ? "passed" : "FAILED") << ".\n"); 579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Result; 580cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 581cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix, 583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer* MemBuf) const { 584cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool DidAllTestsPass = true; 585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned NumRules = 0; 586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const char *LineStart = MemBuf->getBufferStart(); 588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Eat whitespace. 590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines while (LineStart != MemBuf->getBufferEnd() && 591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::isspace(*LineStart)) 592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++LineStart; 593cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 594cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') { 595cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const char *LineEnd = LineStart; 596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines while (LineEnd != MemBuf->getBufferEnd() && 597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *LineEnd != '\r' && *LineEnd != '\n') 598cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++LineEnd; 599cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Line(LineStart, LineEnd - LineStart); 601cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Line.startswith(RulePrefix)) { 602cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DidAllTestsPass &= check(Line.substr(RulePrefix.size())); 603cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++NumRules; 604cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 605cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 606cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Eat whitespace. 607cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines LineStart = LineEnd; 608cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines while (LineStart != MemBuf->getBufferEnd() && 609cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::isspace(*LineStart)) 610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++LineStart; 611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return DidAllTestsPass && (NumRules != 0); 613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool RuntimeDyldChecker::checkSymbolIsValidForLoad(StringRef Symbol) const { 616cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return RTDyld.getSymbolAddress(Symbol) != nullptr; 617cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 618cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesuint64_t RuntimeDyldChecker::getSymbolAddress(StringRef Symbol) const { 620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return RTDyld.getAnySymbolRemoteAddress(Symbol); 621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesuint64_t RuntimeDyldChecker::readMemoryAtSymbol(StringRef Symbol, 624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int64_t Offset, 625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Size) const { 626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint8_t *Src = RTDyld.getSymbolAddress(Symbol); 627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Result = 0; 628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines memcpy(&Result, Src + Offset, Size); 629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Result; 630cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 631cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 632cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesStringRef RuntimeDyldChecker::getSubsectionStartingAt(StringRef Name) const { 633cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RuntimeDyldImpl::SymbolTableMap::const_iterator pos = 634cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RTDyld.GlobalSymbolTable.find(Name); 635cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (pos == RTDyld.GlobalSymbolTable.end()) 636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return StringRef(); 637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RuntimeDyldImpl::SymbolLoc Loc = pos->second; 638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint8_t *SectionAddr = RTDyld.getSectionAddress(Loc.first); 639cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return StringRef(reinterpret_cast<const char*>(SectionAddr) + Loc.second, 640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RTDyld.Sections[Loc.first].Size - Loc.second); 641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 642