1 //===--- RuntimeDyldChecker.cpp - RuntimeDyld tester framework --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 10 #include "RuntimeDyldCheckerImpl.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/StringExtras.h" 13 #include "llvm/MC/MCAsmInfo.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 16 #include "llvm/MC/MCInst.h" 17 #include "llvm/MC/MCInstPrinter.h" 18 #include "llvm/MC/MCInstrInfo.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/MC/MCTargetOptions.h" 22 #include "llvm/MC/TargetRegistry.h" 23 #include "llvm/Support/Endian.h" 24 #include "llvm/Support/MSVCErrorWorkarounds.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include "llvm/Support/Path.h" 27 #include <cctype> 28 #include <memory> 29 #include <utility> 30 31 #define DEBUG_TYPE "rtdyld" 32 33 using namespace llvm; 34 35 namespace { 36 struct TargetInfo { 37 const Target *TheTarget; 38 std::unique_ptr<MCSubtargetInfo> STI; 39 std::unique_ptr<MCRegisterInfo> MRI; 40 std::unique_ptr<MCAsmInfo> MAI; 41 std::unique_ptr<MCContext> Ctx; 42 std::unique_ptr<MCDisassembler> Disassembler; 43 std::unique_ptr<MCInstrInfo> MII; 44 std::unique_ptr<MCInstPrinter> InstPrinter; 45 }; 46 } // anonymous namespace 47 48 namespace llvm { 49 50 // Helper class that implements the language evaluated by RuntimeDyldChecker. 51 class RuntimeDyldCheckerExprEval { 52 public: 53 RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker, 54 raw_ostream &ErrStream) 55 : Checker(Checker) {} 56 57 bool evaluate(StringRef Expr) const { 58 // Expect equality expression of the form 'LHS = RHS'. 59 Expr = Expr.trim(); 60 size_t EQIdx = Expr.find('='); 61 62 ParseContext OutsideLoad(false); 63 64 // Evaluate LHS. 65 StringRef LHSExpr = Expr.substr(0, EQIdx).rtrim(); 66 StringRef RemainingExpr; 67 EvalResult LHSResult; 68 std::tie(LHSResult, RemainingExpr) = 69 evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad); 70 if (LHSResult.hasError()) 71 return handleError(Expr, LHSResult); 72 if (RemainingExpr != "") 73 return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr, "")); 74 75 // Evaluate RHS. 76 StringRef RHSExpr = Expr.substr(EQIdx + 1).ltrim(); 77 EvalResult RHSResult; 78 std::tie(RHSResult, RemainingExpr) = 79 evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad); 80 if (RHSResult.hasError()) 81 return handleError(Expr, RHSResult); 82 if (RemainingExpr != "") 83 return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr, "")); 84 85 if (LHSResult.getValue() != RHSResult.getValue()) { 86 Checker.ErrStream << "Expression '" << Expr << "' is false: " 87 << format("0x%" PRIx64, LHSResult.getValue()) 88 << " != " << format("0x%" PRIx64, RHSResult.getValue()) 89 << "\n"; 90 return false; 91 } 92 return true; 93 } 94 95 private: 96 // RuntimeDyldCheckerExprEval requires some context when parsing exprs. In 97 // particular, it needs to know whether a symbol is being evaluated in the 98 // context of a load, in which case we want the linker's local address for 99 // the symbol, or outside of a load, in which case we want the symbol's 100 // address in the remote target. 101 102 struct ParseContext { 103 bool IsInsideLoad; 104 ParseContext(bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {} 105 }; 106 107 const RuntimeDyldCheckerImpl &Checker; 108 109 enum class BinOpToken : unsigned { 110 Invalid, 111 Add, 112 Sub, 113 BitwiseAnd, 114 BitwiseOr, 115 ShiftLeft, 116 ShiftRight 117 }; 118 119 class EvalResult { 120 public: 121 EvalResult() : Value(0) {} 122 EvalResult(uint64_t Value) : Value(Value) {} 123 EvalResult(std::string ErrorMsg) 124 : Value(0), ErrorMsg(std::move(ErrorMsg)) {} 125 uint64_t getValue() const { return Value; } 126 bool hasError() const { return ErrorMsg != ""; } 127 const std::string &getErrorMsg() const { return ErrorMsg; } 128 129 private: 130 uint64_t Value; 131 std::string ErrorMsg; 132 }; 133 134 StringRef getTokenForError(StringRef Expr) const { 135 if (Expr.empty()) 136 return ""; 137 138 StringRef Token, Remaining; 139 if (isalpha(Expr[0])) 140 std::tie(Token, Remaining) = parseSymbol(Expr); 141 else if (isdigit(Expr[0])) 142 std::tie(Token, Remaining) = parseNumberString(Expr); 143 else { 144 unsigned TokLen = 1; 145 if (Expr.starts_with("<<") || Expr.starts_with(">>")) 146 TokLen = 2; 147 Token = Expr.substr(0, TokLen); 148 } 149 return Token; 150 } 151 152 EvalResult unexpectedToken(StringRef TokenStart, StringRef SubExpr, 153 StringRef ErrText) const { 154 std::string ErrorMsg("Encountered unexpected token '"); 155 ErrorMsg += getTokenForError(TokenStart); 156 if (SubExpr != "") { 157 ErrorMsg += "' while parsing subexpression '"; 158 ErrorMsg += SubExpr; 159 } 160 ErrorMsg += "'"; 161 if (ErrText != "") { 162 ErrorMsg += " "; 163 ErrorMsg += ErrText; 164 } 165 return EvalResult(std::move(ErrorMsg)); 166 } 167 168 bool handleError(StringRef Expr, const EvalResult &R) const { 169 assert(R.hasError() && "Not an error result."); 170 Checker.ErrStream << "Error evaluating expression '" << Expr 171 << "': " << R.getErrorMsg() << "\n"; 172 return false; 173 } 174 175 std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const { 176 if (Expr.empty()) 177 return std::make_pair(BinOpToken::Invalid, ""); 178 179 // Handle the two 2-character tokens. 180 if (Expr.starts_with("<<")) 181 return std::make_pair(BinOpToken::ShiftLeft, Expr.substr(2).ltrim()); 182 if (Expr.starts_with(">>")) 183 return std::make_pair(BinOpToken::ShiftRight, Expr.substr(2).ltrim()); 184 185 // Handle one-character tokens. 186 BinOpToken Op; 187 switch (Expr[0]) { 188 default: 189 return std::make_pair(BinOpToken::Invalid, Expr); 190 case '+': 191 Op = BinOpToken::Add; 192 break; 193 case '-': 194 Op = BinOpToken::Sub; 195 break; 196 case '&': 197 Op = BinOpToken::BitwiseAnd; 198 break; 199 case '|': 200 Op = BinOpToken::BitwiseOr; 201 break; 202 } 203 204 return std::make_pair(Op, Expr.substr(1).ltrim()); 205 } 206 207 EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult, 208 const EvalResult &RHSResult) const { 209 switch (Op) { 210 default: 211 llvm_unreachable("Tried to evaluate unrecognized operation."); 212 case BinOpToken::Add: 213 return EvalResult(LHSResult.getValue() + RHSResult.getValue()); 214 case BinOpToken::Sub: 215 return EvalResult(LHSResult.getValue() - RHSResult.getValue()); 216 case BinOpToken::BitwiseAnd: 217 return EvalResult(LHSResult.getValue() & RHSResult.getValue()); 218 case BinOpToken::BitwiseOr: 219 return EvalResult(LHSResult.getValue() | RHSResult.getValue()); 220 case BinOpToken::ShiftLeft: 221 return EvalResult(LHSResult.getValue() << RHSResult.getValue()); 222 case BinOpToken::ShiftRight: 223 return EvalResult(LHSResult.getValue() >> RHSResult.getValue()); 224 } 225 } 226 227 // Parse a symbol and return a (string, string) pair representing the symbol 228 // name and expression remaining to be parsed. 229 std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const { 230 size_t FirstNonSymbol = Expr.find_first_not_of("0123456789" 231 "abcdefghijklmnopqrstuvwxyz" 232 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 233 ":_.$"); 234 return std::make_pair(Expr.substr(0, FirstNonSymbol), 235 Expr.substr(FirstNonSymbol).ltrim()); 236 } 237 238 // Evaluate a call to decode_operand. Decode the instruction operand at the 239 // given symbol and get the value of the requested operand. 240 // Returns an error if the instruction cannot be decoded, or the requested 241 // operand is not an immediate. 242 // On success, returns a pair containing the value of the operand, plus 243 // the expression remaining to be evaluated. 244 std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const { 245 if (!Expr.starts_with("(")) 246 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 247 StringRef RemainingExpr = Expr.substr(1).ltrim(); 248 StringRef Symbol; 249 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 250 251 if (!Checker.isSymbolValid(Symbol)) 252 return std::make_pair( 253 EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()), 254 ""); 255 256 // if there is an offset number expr 257 int64_t Offset = 0; 258 BinOpToken BinOp; 259 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr); 260 switch (BinOp) { 261 case BinOpToken::Add: { 262 EvalResult Number; 263 std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr); 264 Offset = Number.getValue(); 265 break; 266 } 267 case BinOpToken::Invalid: 268 break; 269 default: 270 return std::make_pair( 271 unexpectedToken(RemainingExpr, RemainingExpr, 272 "expected '+' for offset or ',' if no offset"), 273 ""); 274 } 275 276 if (!RemainingExpr.starts_with(",")) 277 return std::make_pair( 278 unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), ""); 279 RemainingExpr = RemainingExpr.substr(1).ltrim(); 280 281 EvalResult OpIdxExpr; 282 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 283 if (OpIdxExpr.hasError()) 284 return std::make_pair(OpIdxExpr, ""); 285 286 if (!RemainingExpr.starts_with(")")) 287 return std::make_pair( 288 unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), ""); 289 RemainingExpr = RemainingExpr.substr(1).ltrim(); 290 291 MCInst Inst; 292 uint64_t Size; 293 if (!decodeInst(Symbol, Inst, Size, Offset)) 294 return std::make_pair( 295 EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()), 296 ""); 297 298 unsigned OpIdx = OpIdxExpr.getValue(); 299 300 auto printInst = [this](StringRef Symbol, MCInst Inst, 301 raw_string_ostream &ErrMsgStream) { 302 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol)); 303 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures()); 304 if (auto E = TI.takeError()) { 305 errs() << "Error obtaining instruction printer: " 306 << toString(std::move(E)) << "\n"; 307 return std::make_pair(EvalResult(ErrMsgStream.str()), ""); 308 } 309 Inst.dump_pretty(ErrMsgStream, TI->InstPrinter.get()); 310 return std::make_pair(EvalResult(ErrMsgStream.str()), ""); 311 }; 312 313 if (OpIdx >= Inst.getNumOperands()) { 314 std::string ErrMsg; 315 raw_string_ostream ErrMsgStream(ErrMsg); 316 ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx) 317 << "' for instruction '" << Symbol 318 << "'. Instruction has only " 319 << format("%i", Inst.getNumOperands()) 320 << " operands.\nInstruction is:\n "; 321 322 return printInst(Symbol, Inst, ErrMsgStream); 323 } 324 325 const MCOperand &Op = Inst.getOperand(OpIdx); 326 if (!Op.isImm()) { 327 std::string ErrMsg; 328 raw_string_ostream ErrMsgStream(ErrMsg); 329 ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '" 330 << Symbol << "' is not an immediate.\nInstruction is:\n "; 331 332 return printInst(Symbol, Inst, ErrMsgStream); 333 } 334 335 return std::make_pair(EvalResult(Op.getImm()), RemainingExpr); 336 } 337 338 // Evaluate a call to next_pc. 339 // Decode the instruction at the given symbol and return the following program 340 // counter. 341 // Returns an error if the instruction cannot be decoded. 342 // On success, returns a pair containing the next PC, plus of the 343 // expression remaining to be evaluated. 344 std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr, 345 ParseContext PCtx) const { 346 if (!Expr.starts_with("(")) 347 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 348 StringRef RemainingExpr = Expr.substr(1).ltrim(); 349 StringRef Symbol; 350 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 351 352 if (!Checker.isSymbolValid(Symbol)) 353 return std::make_pair( 354 EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()), 355 ""); 356 357 if (!RemainingExpr.starts_with(")")) 358 return std::make_pair( 359 unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), ""); 360 RemainingExpr = RemainingExpr.substr(1).ltrim(); 361 362 MCInst Inst; 363 uint64_t InstSize; 364 if (!decodeInst(Symbol, Inst, InstSize, 0)) 365 return std::make_pair( 366 EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()), 367 ""); 368 369 uint64_t SymbolAddr = PCtx.IsInsideLoad 370 ? Checker.getSymbolLocalAddr(Symbol) 371 : Checker.getSymbolRemoteAddr(Symbol); 372 uint64_t NextPC = SymbolAddr + InstSize; 373 374 return std::make_pair(EvalResult(NextPC), RemainingExpr); 375 } 376 377 // Evaluate a call to stub_addr/got_addr. 378 // Look up and return the address of the stub for the given 379 // (<file name>, <section name>, <symbol name>) tuple. 380 // On success, returns a pair containing the stub address, plus the expression 381 // remaining to be evaluated. 382 std::pair<EvalResult, StringRef> 383 evalStubOrGOTAddr(StringRef Expr, ParseContext PCtx, bool IsStubAddr) const { 384 if (!Expr.starts_with("(")) 385 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 386 StringRef RemainingExpr = Expr.substr(1).ltrim(); 387 388 // Handle file-name specially, as it may contain characters that aren't 389 // legal for symbols. 390 StringRef StubContainerName; 391 size_t ComaIdx = RemainingExpr.find(','); 392 StubContainerName = RemainingExpr.substr(0, ComaIdx).rtrim(); 393 RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim(); 394 395 if (!RemainingExpr.starts_with(",")) 396 return std::make_pair( 397 unexpectedToken(RemainingExpr, Expr, "expected ','"), ""); 398 RemainingExpr = RemainingExpr.substr(1).ltrim(); 399 400 StringRef Symbol; 401 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); 402 403 if (!RemainingExpr.starts_with(")")) 404 return std::make_pair( 405 unexpectedToken(RemainingExpr, Expr, "expected ')'"), ""); 406 RemainingExpr = RemainingExpr.substr(1).ltrim(); 407 408 uint64_t StubAddr; 409 std::string ErrorMsg; 410 std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor( 411 StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr); 412 413 if (ErrorMsg != "") 414 return std::make_pair(EvalResult(ErrorMsg), ""); 415 416 return std::make_pair(EvalResult(StubAddr), RemainingExpr); 417 } 418 419 std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr, 420 ParseContext PCtx) const { 421 if (!Expr.starts_with("(")) 422 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); 423 StringRef RemainingExpr = Expr.substr(1).ltrim(); 424 425 // Handle file-name specially, as it may contain characters that aren't 426 // legal for symbols. 427 StringRef FileName; 428 size_t ComaIdx = RemainingExpr.find(','); 429 FileName = RemainingExpr.substr(0, ComaIdx).rtrim(); 430 RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim(); 431 432 if (!RemainingExpr.starts_with(",")) 433 return std::make_pair( 434 unexpectedToken(RemainingExpr, Expr, "expected ','"), ""); 435 RemainingExpr = RemainingExpr.substr(1).ltrim(); 436 437 StringRef SectionName; 438 size_t CloseParensIdx = RemainingExpr.find(')'); 439 SectionName = RemainingExpr.substr(0, CloseParensIdx).rtrim(); 440 RemainingExpr = RemainingExpr.substr(CloseParensIdx).ltrim(); 441 442 if (!RemainingExpr.starts_with(")")) 443 return std::make_pair( 444 unexpectedToken(RemainingExpr, Expr, "expected ')'"), ""); 445 RemainingExpr = RemainingExpr.substr(1).ltrim(); 446 447 uint64_t StubAddr; 448 std::string ErrorMsg; 449 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr( 450 FileName, SectionName, PCtx.IsInsideLoad); 451 452 if (ErrorMsg != "") 453 return std::make_pair(EvalResult(ErrorMsg), ""); 454 455 return std::make_pair(EvalResult(StubAddr), RemainingExpr); 456 } 457 458 // Evaluate an identifier expr, which may be a symbol, or a call to 459 // one of the builtin functions: get_insn_opcode or get_insn_length. 460 // Return the result, plus the expression remaining to be parsed. 461 std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr, 462 ParseContext PCtx) const { 463 StringRef Symbol; 464 StringRef RemainingExpr; 465 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr); 466 467 // Check for builtin function calls. 468 if (Symbol == "decode_operand") 469 return evalDecodeOperand(RemainingExpr); 470 else if (Symbol == "next_pc") 471 return evalNextPC(RemainingExpr, PCtx); 472 else if (Symbol == "stub_addr") 473 return evalStubOrGOTAddr(RemainingExpr, PCtx, true); 474 else if (Symbol == "got_addr") 475 return evalStubOrGOTAddr(RemainingExpr, PCtx, false); 476 else if (Symbol == "section_addr") 477 return evalSectionAddr(RemainingExpr, PCtx); 478 479 if (!Checker.isSymbolValid(Symbol)) { 480 std::string ErrMsg("No known address for symbol '"); 481 ErrMsg += Symbol; 482 ErrMsg += "'"; 483 if (Symbol.starts_with("L")) 484 ErrMsg += " (this appears to be an assembler local label - " 485 " perhaps drop the 'L'?)"; 486 487 return std::make_pair(EvalResult(ErrMsg), ""); 488 } 489 490 // The value for the symbol depends on the context we're evaluating in: 491 // Inside a load this is the address in the linker's memory, outside a 492 // load it's the address in the target processes memory. 493 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol) 494 : Checker.getSymbolRemoteAddr(Symbol); 495 496 // Looks like a plain symbol reference. 497 return std::make_pair(EvalResult(Value), RemainingExpr); 498 } 499 500 // Parse a number (hexadecimal or decimal) and return a (string, string) 501 // pair representing the number and the expression remaining to be parsed. 502 std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const { 503 size_t FirstNonDigit = StringRef::npos; 504 if (Expr.starts_with("0x")) { 505 FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2); 506 if (FirstNonDigit == StringRef::npos) 507 FirstNonDigit = Expr.size(); 508 } else { 509 FirstNonDigit = Expr.find_first_not_of("0123456789"); 510 if (FirstNonDigit == StringRef::npos) 511 FirstNonDigit = Expr.size(); 512 } 513 return std::make_pair(Expr.substr(0, FirstNonDigit), 514 Expr.substr(FirstNonDigit)); 515 } 516 517 // Evaluate a constant numeric expression (hexadecimal or decimal) and 518 // return a pair containing the result, and the expression remaining to be 519 // evaluated. 520 std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const { 521 StringRef ValueStr; 522 StringRef RemainingExpr; 523 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr); 524 525 if (ValueStr.empty() || !isdigit(ValueStr[0])) 526 return std::make_pair( 527 unexpectedToken(RemainingExpr, RemainingExpr, "expected number"), ""); 528 uint64_t Value; 529 ValueStr.getAsInteger(0, Value); 530 return std::make_pair(EvalResult(Value), RemainingExpr); 531 } 532 533 // Evaluate an expression of the form "(<expr>)" and return a pair 534 // containing the result of evaluating <expr>, plus the expression 535 // remaining to be parsed. 536 std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr, 537 ParseContext PCtx) const { 538 assert(Expr.starts_with("(") && "Not a parenthesized expression"); 539 EvalResult SubExprResult; 540 StringRef RemainingExpr; 541 std::tie(SubExprResult, RemainingExpr) = 542 evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim(), PCtx), PCtx); 543 if (SubExprResult.hasError()) 544 return std::make_pair(SubExprResult, ""); 545 if (!RemainingExpr.starts_with(")")) 546 return std::make_pair( 547 unexpectedToken(RemainingExpr, Expr, "expected ')'"), ""); 548 RemainingExpr = RemainingExpr.substr(1).ltrim(); 549 return std::make_pair(SubExprResult, RemainingExpr); 550 } 551 552 // Evaluate an expression in one of the following forms: 553 // *{<number>}<expr> 554 // Return a pair containing the result, plus the expression remaining to be 555 // parsed. 556 std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const { 557 assert(Expr.starts_with("*") && "Not a load expression"); 558 StringRef RemainingExpr = Expr.substr(1).ltrim(); 559 560 // Parse read size. 561 if (!RemainingExpr.starts_with("{")) 562 return std::make_pair(EvalResult("Expected '{' following '*'."), ""); 563 RemainingExpr = RemainingExpr.substr(1).ltrim(); 564 EvalResult ReadSizeExpr; 565 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 566 if (ReadSizeExpr.hasError()) 567 return std::make_pair(ReadSizeExpr, RemainingExpr); 568 uint64_t ReadSize = ReadSizeExpr.getValue(); 569 if (ReadSize < 1 || ReadSize > 8) 570 return std::make_pair(EvalResult("Invalid size for dereference."), ""); 571 if (!RemainingExpr.starts_with("}")) 572 return std::make_pair(EvalResult("Missing '}' for dereference."), ""); 573 RemainingExpr = RemainingExpr.substr(1).ltrim(); 574 575 // Evaluate the expression representing the load address. 576 ParseContext LoadCtx(true); 577 EvalResult LoadAddrExprResult; 578 std::tie(LoadAddrExprResult, RemainingExpr) = 579 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx); 580 581 if (LoadAddrExprResult.hasError()) 582 return std::make_pair(LoadAddrExprResult, ""); 583 584 uint64_t LoadAddr = LoadAddrExprResult.getValue(); 585 586 // If there is no error but the content pointer is null then this is a 587 // zero-fill symbol/section. 588 if (LoadAddr == 0) 589 return std::make_pair(0, RemainingExpr); 590 591 return std::make_pair( 592 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)), 593 RemainingExpr); 594 } 595 596 // Evaluate a "simple" expression. This is any expression that _isn't_ an 597 // un-parenthesized binary expression. 598 // 599 // "Simple" expressions can be optionally bit-sliced. See evalSlicedExpr. 600 // 601 // Returns a pair containing the result of the evaluation, plus the 602 // expression remaining to be parsed. 603 std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr, 604 ParseContext PCtx) const { 605 EvalResult SubExprResult; 606 StringRef RemainingExpr; 607 608 if (Expr.empty()) 609 return std::make_pair(EvalResult("Unexpected end of expression"), ""); 610 611 if (Expr[0] == '(') 612 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx); 613 else if (Expr[0] == '*') 614 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr); 615 else if (isalpha(Expr[0]) || Expr[0] == '_') 616 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx); 617 else if (isdigit(Expr[0])) 618 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr); 619 else 620 return std::make_pair( 621 unexpectedToken(Expr, Expr, 622 "expected '(', '*', identifier, or number"), ""); 623 624 if (SubExprResult.hasError()) 625 return std::make_pair(SubExprResult, RemainingExpr); 626 627 // Evaluate bit-slice if present. 628 if (RemainingExpr.starts_with("[")) 629 std::tie(SubExprResult, RemainingExpr) = 630 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr)); 631 632 return std::make_pair(SubExprResult, RemainingExpr); 633 } 634 635 // Evaluate a bit-slice of an expression. 636 // A bit-slice has the form "<expr>[high:low]". The result of evaluating a 637 // slice is the bits between high and low (inclusive) in the original 638 // expression, right shifted so that the "low" bit is in position 0 in the 639 // result. 640 // Returns a pair containing the result of the slice operation, plus the 641 // expression remaining to be parsed. 642 std::pair<EvalResult, StringRef> 643 evalSliceExpr(const std::pair<EvalResult, StringRef> &Ctx) const { 644 EvalResult SubExprResult; 645 StringRef RemainingExpr; 646 std::tie(SubExprResult, RemainingExpr) = Ctx; 647 648 assert(RemainingExpr.starts_with("[") && "Not a slice expr."); 649 RemainingExpr = RemainingExpr.substr(1).ltrim(); 650 651 EvalResult HighBitExpr; 652 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 653 654 if (HighBitExpr.hasError()) 655 return std::make_pair(HighBitExpr, RemainingExpr); 656 657 if (!RemainingExpr.starts_with(":")) 658 return std::make_pair( 659 unexpectedToken(RemainingExpr, RemainingExpr, "expected ':'"), ""); 660 RemainingExpr = RemainingExpr.substr(1).ltrim(); 661 662 EvalResult LowBitExpr; 663 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr); 664 665 if (LowBitExpr.hasError()) 666 return std::make_pair(LowBitExpr, RemainingExpr); 667 668 if (!RemainingExpr.starts_with("]")) 669 return std::make_pair( 670 unexpectedToken(RemainingExpr, RemainingExpr, "expected ']'"), ""); 671 RemainingExpr = RemainingExpr.substr(1).ltrim(); 672 673 unsigned HighBit = HighBitExpr.getValue(); 674 unsigned LowBit = LowBitExpr.getValue(); 675 uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1; 676 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask; 677 return std::make_pair(EvalResult(SlicedValue), RemainingExpr); 678 } 679 680 // Evaluate a "complex" expression. 681 // Takes an already evaluated subexpression and checks for the presence of a 682 // binary operator, computing the result of the binary operation if one is 683 // found. Used to make arithmetic expressions left-associative. 684 // Returns a pair containing the ultimate result of evaluating the 685 // expression, plus the expression remaining to be evaluated. 686 std::pair<EvalResult, StringRef> 687 evalComplexExpr(const std::pair<EvalResult, StringRef> &LHSAndRemaining, 688 ParseContext PCtx) const { 689 EvalResult LHSResult; 690 StringRef RemainingExpr; 691 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining; 692 693 // If there was an error, or there's nothing left to evaluate, return the 694 // result. 695 if (LHSResult.hasError() || RemainingExpr == "") 696 return std::make_pair(LHSResult, RemainingExpr); 697 698 // Otherwise check if this is a binary expression. 699 BinOpToken BinOp; 700 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr); 701 702 // If this isn't a recognized expression just return. 703 if (BinOp == BinOpToken::Invalid) 704 return std::make_pair(LHSResult, RemainingExpr); 705 706 // This is a recognized bin-op. Evaluate the RHS, then evaluate the binop. 707 EvalResult RHSResult; 708 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx); 709 710 // If there was an error evaluating the RHS, return it. 711 if (RHSResult.hasError()) 712 return std::make_pair(RHSResult, RemainingExpr); 713 714 // This is a binary expression - evaluate and try to continue as a 715 // complex expr. 716 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult)); 717 718 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx); 719 } 720 721 bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size, 722 int64_t Offset) const { 723 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol)); 724 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures()); 725 726 if (auto E = TI.takeError()) { 727 errs() << "Error obtaining disassembler: " << toString(std::move(E)) 728 << "\n"; 729 return false; 730 } 731 732 StringRef SymbolMem = Checker.getSymbolContent(Symbol); 733 ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin() + Offset, 734 SymbolMem.size() - Offset); 735 736 MCDisassembler::DecodeStatus S = 737 TI->Disassembler->getInstruction(Inst, Size, SymbolBytes, 0, nulls()); 738 739 return (S == MCDisassembler::Success); 740 } 741 742 Expected<TargetInfo> getTargetInfo(const Triple &TT, const StringRef &CPU, 743 const SubtargetFeatures &TF) const { 744 745 auto TripleName = TT.str(); 746 std::string ErrorStr; 747 const Target *TheTarget = 748 TargetRegistry::lookupTarget(TripleName, ErrorStr); 749 if (!TheTarget) 750 return make_error<StringError>("Error accessing target '" + TripleName + 751 "': " + ErrorStr, 752 inconvertibleErrorCode()); 753 754 std::unique_ptr<MCSubtargetInfo> STI( 755 TheTarget->createMCSubtargetInfo(TripleName, CPU, TF.getString())); 756 if (!STI) 757 return make_error<StringError>("Unable to create subtarget for " + 758 TripleName, 759 inconvertibleErrorCode()); 760 761 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 762 if (!MRI) 763 return make_error<StringError>("Unable to create target register info " 764 "for " + 765 TripleName, 766 inconvertibleErrorCode()); 767 768 MCTargetOptions MCOptions; 769 std::unique_ptr<MCAsmInfo> MAI( 770 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 771 if (!MAI) 772 return make_error<StringError>("Unable to create target asm info " + 773 TripleName, 774 inconvertibleErrorCode()); 775 776 auto Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(), 777 MRI.get(), STI.get()); 778 779 std::unique_ptr<MCDisassembler> Disassembler( 780 TheTarget->createMCDisassembler(*STI, *Ctx)); 781 if (!Disassembler) 782 return make_error<StringError>("Unable to create disassembler for " + 783 TripleName, 784 inconvertibleErrorCode()); 785 786 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 787 if (!MII) 788 return make_error<StringError>("Unable to create instruction info for" + 789 TripleName, 790 inconvertibleErrorCode()); 791 792 std::unique_ptr<MCInstPrinter> InstPrinter(TheTarget->createMCInstPrinter( 793 Triple(TripleName), 0, *MAI, *MII, *MRI)); 794 if (!InstPrinter) 795 return make_error<StringError>( 796 "Unable to create instruction printer for" + TripleName, 797 inconvertibleErrorCode()); 798 799 return TargetInfo({TheTarget, std::move(STI), std::move(MRI), 800 std::move(MAI), std::move(Ctx), std::move(Disassembler), 801 std::move(MII), std::move(InstPrinter)}); 802 } 803 }; 804 } // namespace llvm 805 806 RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl( 807 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, 808 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, 809 GetGOTInfoFunction GetGOTInfo, llvm::endianness Endianness, Triple TT, 810 StringRef CPU, SubtargetFeatures TF, raw_ostream &ErrStream) 811 : IsSymbolValid(std::move(IsSymbolValid)), 812 GetSymbolInfo(std::move(GetSymbolInfo)), 813 GetSectionInfo(std::move(GetSectionInfo)), 814 GetStubInfo(std::move(GetStubInfo)), GetGOTInfo(std::move(GetGOTInfo)), 815 Endianness(Endianness), TT(std::move(TT)), CPU(std::move(CPU)), 816 TF(std::move(TF)), ErrStream(ErrStream) {} 817 818 bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const { 819 CheckExpr = CheckExpr.trim(); 820 LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr 821 << "'...\n"); 822 RuntimeDyldCheckerExprEval P(*this, ErrStream); 823 bool Result = P.evaluate(CheckExpr); 824 (void)Result; 825 LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' " 826 << (Result ? "passed" : "FAILED") << ".\n"); 827 return Result; 828 } 829 830 bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix, 831 MemoryBuffer *MemBuf) const { 832 bool DidAllTestsPass = true; 833 unsigned NumRules = 0; 834 835 std::string CheckExpr; 836 const char *LineStart = MemBuf->getBufferStart(); 837 838 // Eat whitespace. 839 while (LineStart != MemBuf->getBufferEnd() && isSpace(*LineStart)) 840 ++LineStart; 841 842 while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') { 843 const char *LineEnd = LineStart; 844 while (LineEnd != MemBuf->getBufferEnd() && *LineEnd != '\r' && 845 *LineEnd != '\n') 846 ++LineEnd; 847 848 StringRef Line(LineStart, LineEnd - LineStart); 849 if (Line.starts_with(RulePrefix)) 850 CheckExpr += Line.substr(RulePrefix.size()).str(); 851 852 // If there's a check expr string... 853 if (!CheckExpr.empty()) { 854 // ... and it's complete then run it, otherwise remove the trailer '\'. 855 if (CheckExpr.back() != '\\') { 856 DidAllTestsPass &= check(CheckExpr); 857 CheckExpr.clear(); 858 ++NumRules; 859 } else 860 CheckExpr.pop_back(); 861 } 862 863 // Eat whitespace. 864 LineStart = LineEnd; 865 while (LineStart != MemBuf->getBufferEnd() && isSpace(*LineStart)) 866 ++LineStart; 867 } 868 return DidAllTestsPass && (NumRules != 0); 869 } 870 871 bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const { 872 return IsSymbolValid(Symbol); 873 } 874 875 uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const { 876 auto SymInfo = GetSymbolInfo(Symbol); 877 if (!SymInfo) { 878 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 879 return 0; 880 } 881 882 if (SymInfo->isZeroFill()) 883 return 0; 884 885 return static_cast<uint64_t>( 886 reinterpret_cast<uintptr_t>(SymInfo->getContent().data())); 887 } 888 889 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const { 890 auto SymInfo = GetSymbolInfo(Symbol); 891 if (!SymInfo) { 892 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 893 return 0; 894 } 895 896 return SymInfo->getTargetAddress(); 897 } 898 899 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr, 900 unsigned Size) const { 901 uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr); 902 assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range."); 903 void *Ptr = reinterpret_cast<void*>(PtrSizedAddr); 904 905 switch (Size) { 906 case 1: 907 return support::endian::read<uint8_t>(Ptr, Endianness); 908 case 2: 909 return support::endian::read<uint16_t>(Ptr, Endianness); 910 case 4: 911 return support::endian::read<uint32_t>(Ptr, Endianness); 912 case 8: 913 return support::endian::read<uint64_t>(Ptr, Endianness); 914 } 915 llvm_unreachable("Unsupported read size"); 916 } 917 918 StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const { 919 auto SymInfo = GetSymbolInfo(Symbol); 920 if (!SymInfo) { 921 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 922 return StringRef(); 923 } 924 return {SymInfo->getContent().data(), SymInfo->getContent().size()}; 925 } 926 927 TargetFlagsType RuntimeDyldCheckerImpl::getTargetFlag(StringRef Symbol) const { 928 auto SymInfo = GetSymbolInfo(Symbol); 929 if (!SymInfo) { 930 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 931 return TargetFlagsType{}; 932 } 933 return SymInfo->getTargetFlags(); 934 } 935 936 Triple 937 RuntimeDyldCheckerImpl::getTripleForSymbol(TargetFlagsType Flag) const { 938 Triple TheTriple = TT; 939 940 switch (TT.getArch()) { 941 case Triple::ArchType::arm: 942 if (~Flag & 0x1) 943 return TT; 944 TheTriple.setArchName((Twine("thumb") + TT.getArchName().substr(3)).str()); 945 return TheTriple; 946 case Triple::ArchType::thumb: 947 if (Flag & 0x1) 948 return TT; 949 TheTriple.setArchName((Twine("arm") + TT.getArchName().substr(5)).str()); 950 return TheTriple; 951 952 default: 953 return TT; 954 } 955 } 956 957 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr( 958 StringRef FileName, StringRef SectionName, bool IsInsideLoad) const { 959 960 auto SecInfo = GetSectionInfo(FileName, SectionName); 961 if (!SecInfo) { 962 std::string ErrMsg; 963 { 964 raw_string_ostream ErrMsgStream(ErrMsg); 965 logAllUnhandledErrors(SecInfo.takeError(), ErrMsgStream, 966 "RTDyldChecker: "); 967 } 968 return std::make_pair(0, std::move(ErrMsg)); 969 } 970 971 // If this address is being looked up in "load" mode, return the content 972 // pointer, otherwise return the target address. 973 974 uint64_t Addr = 0; 975 976 if (IsInsideLoad) { 977 if (SecInfo->isZeroFill()) 978 Addr = 0; 979 else 980 Addr = pointerToJITTargetAddress(SecInfo->getContent().data()); 981 } else 982 Addr = SecInfo->getTargetAddress(); 983 984 return std::make_pair(Addr, ""); 985 } 986 987 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor( 988 StringRef StubContainerName, StringRef SymbolName, bool IsInsideLoad, 989 bool IsStubAddr) const { 990 991 auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName) 992 : GetGOTInfo(StubContainerName, SymbolName); 993 994 if (!StubInfo) { 995 std::string ErrMsg; 996 { 997 raw_string_ostream ErrMsgStream(ErrMsg); 998 logAllUnhandledErrors(StubInfo.takeError(), ErrMsgStream, 999 "RTDyldChecker: "); 1000 } 1001 return std::make_pair((uint64_t)0, std::move(ErrMsg)); 1002 } 1003 1004 uint64_t Addr = 0; 1005 1006 if (IsInsideLoad) { 1007 if (StubInfo->isZeroFill()) 1008 return std::make_pair((uint64_t)0, "Detected zero-filled stub/GOT entry"); 1009 Addr = pointerToJITTargetAddress(StubInfo->getContent().data()); 1010 } else 1011 Addr = StubInfo->getTargetAddress(); 1012 1013 return std::make_pair(Addr, ""); 1014 } 1015 1016 RuntimeDyldChecker::RuntimeDyldChecker( 1017 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, 1018 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, 1019 GetGOTInfoFunction GetGOTInfo, llvm::endianness Endianness, Triple TT, 1020 StringRef CPU, SubtargetFeatures TF, raw_ostream &ErrStream) 1021 : Impl(::std::make_unique<RuntimeDyldCheckerImpl>( 1022 std::move(IsSymbolValid), std::move(GetSymbolInfo), 1023 std::move(GetSectionInfo), std::move(GetStubInfo), 1024 std::move(GetGOTInfo), Endianness, std::move(TT), std::move(CPU), 1025 std::move(TF), ErrStream)) {} 1026 1027 RuntimeDyldChecker::~RuntimeDyldChecker() = default; 1028 1029 bool RuntimeDyldChecker::check(StringRef CheckExpr) const { 1030 return Impl->check(CheckExpr); 1031 } 1032 1033 bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix, 1034 MemoryBuffer *MemBuf) const { 1035 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf); 1036 } 1037 1038 std::pair<uint64_t, std::string> 1039 RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName, 1040 bool LocalAddress) { 1041 return Impl->getSectionAddr(FileName, SectionName, LocalAddress); 1042 } 1043