LLVM: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp Source File (original) (raw)

49public:

53

55

56 Expr = Expr.trim();

57 size_t EQIdx = Expr.find('=');

58

59 ParseContext OutsideLoad(false);

60

61

64 EvalResult LHSResult;

65 std::tie(LHSResult, RemainingExpr) =

66 evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);

67 if (LHSResult.hasError())

68 return handleError(Expr, LHSResult);

69 if (RemainingExpr != "")

70 return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr, ""));

71

72

74 EvalResult RHSResult;

75 std::tie(RHSResult, RemainingExpr) =

76 evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);

77 if (RHSResult.hasError())

78 return handleError(Expr, RHSResult);

79 if (RemainingExpr != "")

80 return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr, ""));

81

82 if (LHSResult.getValue() != RHSResult.getValue()) {

83 Checker.ErrStream << "Expression '" << Expr << "' is false: "

84 << format("0x%" PRIx64, LHSResult.getValue())

85 << " != " << format("0x%" PRIx64, RHSResult.getValue())

86 << "\n";

87 return false;

88 }

89 return true;

90 }

91

92private:

93

94

95

96

97

98

99 struct ParseContext {

100 bool IsInsideLoad;

101 ParseContext(bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}

102 };

103

104 const RuntimeDyldCheckerImpl &Checker;

105

106 enum class BinOpToken : unsigned {

107 Invalid,

108 Add,

109 Sub,

110 BitwiseAnd,

111 BitwiseOr,

112 ShiftLeft,

113 ShiftRight

114 };

115

116 class EvalResult {

117 public:

118 EvalResult() : Value(0) {}

119 EvalResult(uint64_t Value) : Value(Value) {}

120 EvalResult(std::string ErrorMsg)

121 : Value(0), ErrorMsg(std::move(ErrorMsg)) {}

122 uint64_t getValue() const { return Value; }

123 bool hasError() const { return ErrorMsg != ""; }

124 const std::string &getErrorMsg() const { return ErrorMsg; }

125

126 private:

127 uint64_t Value;

128 std::string ErrorMsg;

129 };

130

131 StringRef getTokenForError(StringRef Expr) const {

132 if (Expr.empty())

133 return "";

134

135 StringRef Token, Remaining;

136 if (isalpha(Expr[0]))

137 std::tie(Token, Remaining) = parseSymbol(Expr);

138 else if (isdigit(Expr[0]))

139 std::tie(Token, Remaining) = parseNumberString(Expr);

140 else {

141 unsigned TokLen = 1;

143 TokLen = 2;

144 Token = Expr.substr(0, TokLen);

145 }

146 return Token;

147 }

148

149 EvalResult unexpectedToken(StringRef TokenStart, StringRef SubExpr,

150 StringRef ErrText) const {

151 std::string ErrorMsg("Encountered unexpected token '");

152 ErrorMsg += getTokenForError(TokenStart);

153 if (SubExpr != "") {

154 ErrorMsg += "' while parsing subexpression '";

155 ErrorMsg += SubExpr;

156 }

157 ErrorMsg += "'";

158 if (ErrText != "") {

159 ErrorMsg += " ";

160 ErrorMsg += ErrText;

161 }

162 return EvalResult(std::move(ErrorMsg));

163 }

164

165 bool handleError(StringRef Expr, const EvalResult &R) const {

166 assert(R.hasError() && "Not an error result.");

167 Checker.ErrStream << "Error evaluating expression '" << Expr

168 << "': " << R.getErrorMsg() << "\n";

169 return false;

170 }

171

172 std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const {

173 if (Expr.empty())

174 return std::make_pair(BinOpToken::Invalid, "");

175

176

178 return std::make_pair(BinOpToken::ShiftLeft, Expr.substr(2).ltrim());

180 return std::make_pair(BinOpToken::ShiftRight, Expr.substr(2).ltrim());

181

182

183 BinOpToken Op;

184 switch (Expr[0]) {

185 default:

186 return std::make_pair(BinOpToken::Invalid, Expr);

187 case '+':

188 Op = BinOpToken::Add;

189 break;

190 case '-':

191 Op = BinOpToken::Sub;

192 break;

193 case '&':

194 Op = BinOpToken::BitwiseAnd;

195 break;

196 case '|':

197 Op = BinOpToken::BitwiseOr;

198 break;

199 }

200

201 return std::make_pair(Op, Expr.substr(1).ltrim());

202 }

203

204 EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult,

205 const EvalResult &RHSResult) const {

206 switch (Op) {

207 default:

208 llvm_unreachable("Tried to evaluate unrecognized operation.");

209 case BinOpToken::Add:

210 return EvalResult(LHSResult.getValue() + RHSResult.getValue());

211 case BinOpToken::Sub:

212 return EvalResult(LHSResult.getValue() - RHSResult.getValue());

213 case BinOpToken::BitwiseAnd:

214 return EvalResult(LHSResult.getValue() & RHSResult.getValue());

215 case BinOpToken::BitwiseOr:

216 return EvalResult(LHSResult.getValue() | RHSResult.getValue());

217 case BinOpToken::ShiftLeft:

218 return EvalResult(LHSResult.getValue() << RHSResult.getValue());

219 case BinOpToken::ShiftRight:

220 return EvalResult(LHSResult.getValue() >> RHSResult.getValue());

221 }

222 }

223

224

225

226 std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const {

228 "abcdefghijklmnopqrstuvwxyz"

229 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

230 ":_.$");

231 return std::make_pair(Expr.substr(0, FirstNonSymbol),

233 }

234

235

236

237

238

239

240

241 std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const {

243 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");

244 StringRef RemainingExpr = Expr.substr(1).ltrim();

246 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);

247

248 if (!Checker.isSymbolValid(Symbol))

249 return std::make_pair(

250 EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),

251 "");

252

253

255 BinOpToken BinOp;

256 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);

257 switch (BinOp) {

258 case BinOpToken::Add: {

260 std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr);

262 break;

263 }

264 case BinOpToken::Invalid:

265 break;

266 default:

267 return std::make_pair(

268 unexpectedToken(RemainingExpr, RemainingExpr,

269 "expected '+' for offset or ',' if no offset"),

270 "");

271 }

272

274 return std::make_pair(

275 unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), "");

276 RemainingExpr = RemainingExpr.substr(1).ltrim();

277

278 EvalResult OpIdxExpr;

279 std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);

280 if (OpIdxExpr.hasError())

281 return std::make_pair(OpIdxExpr, "");

282

284 return std::make_pair(

285 unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");

286 RemainingExpr = RemainingExpr.substr(1).ltrim();

287

288 MCInst Inst;

289 uint64_t Size;

290 if (!decodeInst(Symbol, Inst, Size, Offset))

291 return std::make_pair(

292 EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),

293 "");

294

295 unsigned OpIdx = OpIdxExpr.getValue();

296

297 auto printInst = [this](StringRef Symbol, MCInst Inst,

298 raw_string_ostream &ErrMsgStream) {

299 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));

300 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());

301 if (auto E = TI.takeError()) {

302 errs() << "Error obtaining instruction printer: "

303 << toString(std::move(E)) << "\n";

304 return;

305 }

306 Inst.dump_pretty(ErrMsgStream, TI->InstPrinter.get());

307 return;

308 };

309

311 std::string ErrMsg;

312 raw_string_ostream ErrMsgStream(ErrMsg);

313 ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx)

314 << "' for instruction '" << Symbol

315 << "'. Instruction has only "

316 << format("%i", Inst.getNumOperands())

317 << " operands.\nInstruction is:\n ";

318

319 printInst(Symbol, Inst, ErrMsgStream);

320 return {EvalResult(std::move(ErrMsg)), ""};

321 }

322

323 const MCOperand &Op = Inst.getOperand(OpIdx);

324 if (Op.isImm()) {

325 std::string ErrMsg;

326 raw_string_ostream ErrMsgStream(ErrMsg);

327 ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"

328 << Symbol << "' is not an immediate.\nInstruction is:\n ";

329

330 printInst(Symbol, Inst, ErrMsgStream);

331 return {EvalResult(std::move(ErrMsg)), ""};

332 }

333

334 return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);

335 }

336

337

338

339

340

341

342

343 std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr,

344 ParseContext PCtx) const {

346 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");

347 StringRef RemainingExpr = Expr.substr(1).ltrim();

349 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);

350

351 if (!Checker.isSymbolValid(Symbol))

352 return std::make_pair(

353 EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),

354 "");

355

357 return std::make_pair(

358 unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");

359 RemainingExpr = RemainingExpr.substr(1).ltrim();

360

361 MCInst Inst;

362 uint64_t InstSize;

363 if (!decodeInst(Symbol, Inst, InstSize, 0))

364 return std::make_pair(

365 EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),

366 "");

367

368 uint64_t SymbolAddr = PCtx.IsInsideLoad

369 ? Checker.getSymbolLocalAddr(Symbol)

370 : Checker.getSymbolRemoteAddr(Symbol);

371

372

373

374 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));

376

377 uint64_t NextPC = SymbolAddr + InstSize + PCOffset;

378

379 return std::make_pair(EvalResult(NextPC), RemainingExpr);

380 }

381

382

383

384

385

386

387 std::pair<EvalResult, StringRef>

388 evalStubOrGOTAddr(StringRef Expr, ParseContext PCtx, bool IsStubAddr) const {

390 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");

391 StringRef RemainingExpr = Expr.substr(1).ltrim();

392

393

394

395 StringRef StubContainerName;

396 size_t ComaIdx = RemainingExpr.find(',');

397 StubContainerName = RemainingExpr.substr(0, ComaIdx).rtrim();

398 RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();

399

401 return std::make_pair(

402 unexpectedToken(RemainingExpr, Expr, "expected ','"), "");

403 RemainingExpr = RemainingExpr.substr(1).ltrim();

404

406 std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);

407

408

409 StringRef KindNameFilter;

411 RemainingExpr = RemainingExpr.substr(1).ltrim();

412 size_t ClosingBracket = RemainingExpr.find(")");

413 KindNameFilter = RemainingExpr.substr(0, ClosingBracket);

414 RemainingExpr = RemainingExpr.substr(ClosingBracket);

415 }

416

418 return std::make_pair(

419 unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");

420 RemainingExpr = RemainingExpr.substr(1).ltrim();

421

422 uint64_t StubAddr;

423 std::string ErrorMsg;

424 std::tie(StubAddr, ErrorMsg) =

425 Checker.getStubOrGOTAddrFor(StubContainerName, Symbol, KindNameFilter,

426 PCtx.IsInsideLoad, IsStubAddr);

427

428 if (ErrorMsg != "")

429 return std::make_pair(EvalResult(ErrorMsg), "");

430

431 return std::make_pair(EvalResult(StubAddr), RemainingExpr);

432 }

433

434 std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr,

435 ParseContext PCtx) const {

437 return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");

438 StringRef RemainingExpr = Expr.substr(1).ltrim();

439

440

441

442 StringRef FileName;

443 size_t ComaIdx = RemainingExpr.find(',');

444 FileName = RemainingExpr.substr(0, ComaIdx).rtrim();

445 RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();

446

448 return std::make_pair(

449 unexpectedToken(RemainingExpr, Expr, "expected ','"), "");

450 RemainingExpr = RemainingExpr.substr(1).ltrim();

451

453 size_t CloseParensIdx = RemainingExpr.find(')');

455 RemainingExpr = RemainingExpr.substr(CloseParensIdx).ltrim();

456

458 return std::make_pair(

459 unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");

460 RemainingExpr = RemainingExpr.substr(1).ltrim();

461

462 uint64_t StubAddr;

463 std::string ErrorMsg;

464 std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(

465 FileName, SectionName, PCtx.IsInsideLoad);

466

467 if (ErrorMsg != "")

468 return std::make_pair(EvalResult(ErrorMsg), "");

469

470 return std::make_pair(EvalResult(StubAddr), RemainingExpr);

471 }

472

473

474

475

476 std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr,

477 ParseContext PCtx) const {

479 StringRef RemainingExpr;

480 std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);

481

482

483 if (Symbol == "decode_operand")

484 return evalDecodeOperand(RemainingExpr);

485 else if (Symbol == "next_pc")

486 return evalNextPC(RemainingExpr, PCtx);

487 else if (Symbol == "stub_addr")

488 return evalStubOrGOTAddr(RemainingExpr, PCtx, true);

489 else if (Symbol == "got_addr")

490 return evalStubOrGOTAddr(RemainingExpr, PCtx, false);

491 else if (Symbol == "section_addr")

492 return evalSectionAddr(RemainingExpr, PCtx);

493

494 if (!Checker.isSymbolValid(Symbol)) {

495 std::string ErrMsg("No known address for symbol '");

497 ErrMsg += "'";

498 if (Symbol.starts_with("L"))

499 ErrMsg += " (this appears to be an assembler local label - "

500 " perhaps drop the 'L'?)";

501

502 return std::make_pair(EvalResult(ErrMsg), "");

503 }

504

505

506

507

508 uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)

509 : Checker.getSymbolRemoteAddr(Symbol);

510

511

512 return std::make_pair(EvalResult(Value), RemainingExpr);

513 }

514

515

516

517 std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const {

520 FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2);

522 FirstNonDigit = Expr.size();

523 } else {

526 FirstNonDigit = Expr.size();

527 }

528 return std::make_pair(Expr.substr(0, FirstNonDigit),

529 Expr.substr(FirstNonDigit));

530 }

531

532

533

534

535 std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const {

536 StringRef ValueStr;

537 StringRef RemainingExpr;

538 std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);

539

540 if (ValueStr.empty() || !isdigit(ValueStr[0]))

541 return std::make_pair(

542 unexpectedToken(RemainingExpr, RemainingExpr, "expected number"), "");

545 return std::make_pair(EvalResult(Value), RemainingExpr);

546 }

547

548

549

550

551 std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr,

552 ParseContext PCtx) const {

553 assert(Expr.starts_with("(") && "Not a parenthesized expression");

554 EvalResult SubExprResult;

555 StringRef RemainingExpr;

556 std::tie(SubExprResult, RemainingExpr) =

557 evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim(), PCtx), PCtx);

558 if (SubExprResult.hasError())

559 return std::make_pair(SubExprResult, "");

561 return std::make_pair(

562 unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");

563 RemainingExpr = RemainingExpr.substr(1).ltrim();

564 return std::make_pair(SubExprResult, RemainingExpr);

565 }

566

567

568

569

570

571 std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const {

573 StringRef RemainingExpr = Expr.substr(1).ltrim();

574

575

577 return std::make_pair(EvalResult("Expected '{' following '*'."), "");

578 RemainingExpr = RemainingExpr.substr(1).ltrim();

579 EvalResult ReadSizeExpr;

580 std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);

581 if (ReadSizeExpr.hasError())

582 return std::make_pair(ReadSizeExpr, RemainingExpr);

583 uint64_t ReadSize = ReadSizeExpr.getValue();

584 if (ReadSize < 1 || ReadSize > 8)

585 return std::make_pair(EvalResult("Invalid size for dereference."), "");

587 return std::make_pair(EvalResult("Missing '}' for dereference."), "");

588 RemainingExpr = RemainingExpr.substr(1).ltrim();

589

590

591 ParseContext LoadCtx(true);

592 EvalResult LoadAddrExprResult;

593 std::tie(LoadAddrExprResult, RemainingExpr) =

594 evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);

595

596 if (LoadAddrExprResult.hasError())

597 return std::make_pair(LoadAddrExprResult, "");

598

599 uint64_t LoadAddr = LoadAddrExprResult.getValue();

600

601

602

603 if (LoadAddr == 0)

604 return std::make_pair(0, RemainingExpr);

605

606 return std::make_pair(

607 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),

608 RemainingExpr);

609 }

610

611

612

613

614

615

616

617

618 std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr,

619 ParseContext PCtx) const {

620 EvalResult SubExprResult;

621 StringRef RemainingExpr;

622

623 if (Expr.empty())

624 return std::make_pair(EvalResult("Unexpected end of expression"), "");

625

626 if (Expr[0] == '(')

627 std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);

628 else if (Expr[0] == '*')

629 std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);

630 else if (isalpha(Expr[0]) || Expr[0] == '_')

631 std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);

632 else if (isdigit(Expr[0]))

633 std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);

634 else

635 return std::make_pair(

636 unexpectedToken(Expr, Expr,

637 "expected '(', '*', identifier, or number"), "");

638

639 if (SubExprResult.hasError())

640 return std::make_pair(SubExprResult, RemainingExpr);

641

642

644 std::tie(SubExprResult, RemainingExpr) =

645 evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));

646

647 return std::make_pair(SubExprResult, RemainingExpr);

648 }

649

650

651

652

653

654

655

656

657 std::pair<EvalResult, StringRef>

658 evalSliceExpr(const std::pair<EvalResult, StringRef> &Ctx) const {

659 EvalResult SubExprResult;

660 StringRef RemainingExpr;

661 std::tie(SubExprResult, RemainingExpr) = Ctx;

662

664 RemainingExpr = RemainingExpr.substr(1).ltrim();

665

666 EvalResult HighBitExpr;

667 std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);

668

669 if (HighBitExpr.hasError())

670 return std::make_pair(HighBitExpr, RemainingExpr);

671

673 return std::make_pair(

674 unexpectedToken(RemainingExpr, RemainingExpr, "expected ':'"), "");

675 RemainingExpr = RemainingExpr.substr(1).ltrim();

676

677 EvalResult LowBitExpr;

678 std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);

679

680 if (LowBitExpr.hasError())

681 return std::make_pair(LowBitExpr, RemainingExpr);

682

684 return std::make_pair(

685 unexpectedToken(RemainingExpr, RemainingExpr, "expected ']'"), "");

686 RemainingExpr = RemainingExpr.substr(1).ltrim();

687

688 unsigned HighBit = HighBitExpr.getValue();

689 unsigned LowBit = LowBitExpr.getValue();

690 uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;

691 uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;

692 return std::make_pair(EvalResult(SlicedValue), RemainingExpr);

693 }

694

695

696

697

698

699

700

701 std::pair<EvalResult, StringRef>

702 evalComplexExpr(const std::pair<EvalResult, StringRef> &LHSAndRemaining,

703 ParseContext PCtx) const {

704 EvalResult LHSResult;

705 StringRef RemainingExpr;

706 std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;

707

708

709

710 if (LHSResult.hasError() || RemainingExpr == "")

711 return std::make_pair(LHSResult, RemainingExpr);

712

713

714 BinOpToken BinOp;

715 std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);

716

717

718 if (BinOp == BinOpToken::Invalid)

719 return std::make_pair(LHSResult, RemainingExpr);

720

721

722 EvalResult RHSResult;

723 std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);

724

725

726 if (RHSResult.hasError())

727 return std::make_pair(RHSResult, RemainingExpr);

728

729

730

731 EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));

732

733 return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);

734 }

735

736 bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size,

737 int64_t Offset) const {

738 auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));

739 auto TI = getTargetInfo(TT, Checker.getCPU(), Checker.getFeatures());

740

741 if (auto E = TI.takeError()) {

742 errs() << "Error obtaining disassembler: " << toString(std::move(E))

743 << "\n";

744 return false;

745 }

746

747 StringRef SymbolMem = Checker.getSymbolContent(Symbol);

750

752 TI->Disassembler->getInstruction(Inst, Size, SymbolBytes, 0, nulls());

753

755 }

756

757 Expected getTargetInfo(const Triple &TT, const StringRef &CPU,

758 const SubtargetFeatures &TF) const {

759 std::string ErrorStr;

761 if (!TheTarget)

763 "': " + ErrorStr,

765

766 std::unique_ptr STI(

768 if (!STI)

770 TT.str(),

772

774 if (MRI)

776 "for " +

777 TT.str(),

779

780 MCTargetOptions MCOptions;

781 std::unique_ptr MAI(

783 if (!MAI)

785 TT.str(),

787

788 auto Ctx = std::make_unique(Triple(TT.str()), MAI.get(),

789 MRI.get(), STI.get());

790

791 std::unique_ptr Disassembler(

793 if (!Disassembler)

795 TT.str(),

797

798 std::unique_ptr MII(TheTarget->createMCInstrInfo());

799 if (!MII)

801 TT.str(),

803

804 std::unique_ptr InstPrinter(

806 if (!InstPrinter)

808 "Unable to create instruction printer for" + TT.str(),

810

811 return TargetInfo({TheTarget, std::move(STI), std::move(MRI),

812 std::move(MAI), std::move(Ctx), std::move(Disassembler),

813 std::move(MII), std::move(InstPrinter)});

814 }

815};

819 IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,

820 GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,

823 : IsSymbolValid(std::move(IsSymbolValid)),

824 GetSymbolInfo(std::move(GetSymbolInfo)),

825 GetSectionInfo(std::move(GetSectionInfo)),

826 GetStubInfo(std::move(GetStubInfo)), GetGOTInfo(std::move(GetGOTInfo)),

827 Endianness(Endianness), TT(std::move(TT)), CPU(std::move(CPU)),

828 TF(std::move(TF)), ErrStream(ErrStream) {}

831 CheckExpr = CheckExpr.trim();

832 LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr

833 << "'...\n");

835 bool Result = P.evaluate(CheckExpr);

836 (void)Result;

837 LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "

838 << (Result ? "passed" : "FAILED") << ".\n");

839 return Result;

840}

844 bool DidAllTestsPass = true;

845 unsigned NumRules = 0;

846

847 std::string CheckExpr;

849

850

852 ++LineStart;

853

854 while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') {

855 const char *LineEnd = LineStart;

856 while (LineEnd != MemBuf->getBufferEnd() && *LineEnd != '\r' &&

857 *LineEnd != '\n')

858 ++LineEnd;

859

860 StringRef Line(LineStart, LineEnd - LineStart);

861 if (Line.starts_with(RulePrefix))

862 CheckExpr += Line.substr(RulePrefix.size()).str();

863

864

865 if (!CheckExpr.empty()) {

866

867 if (CheckExpr.back() != '\\') {

868 DidAllTestsPass &= check(CheckExpr);

869 CheckExpr.clear();

870 ++NumRules;

871 } else

872 CheckExpr.pop_back();

873 }

874

875

876 LineStart = LineEnd;

878 ++LineStart;

879 }

880 return DidAllTestsPass && (NumRules != 0);

881}

901uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {

1045 return Impl->check(CheckExpr);

1046}

1050 return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);

1051}

1055 bool LocalAddress) {

1056 return Impl->getSectionAddr(FileName, SectionName, LocalAddress);

1057}