LLVM: lib/CodeGen/AsmPrinter/WinException.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

33using namespace llvm;

34

36

37

38 useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);

39 isAArch64 = Asm->TM.getTargetTriple().isAArch64();

40 isThumb = Asm->TM.getTargetTriple().isThumb();

41}

42

44

45

46

48 auto &OS = *Asm->OutStreamer;

49 const Module *M = MMI->getModule();

51 if (F.hasFnAttribute("safeseh"))

52 OS.emitCOFFSafeSEH(Asm->getSymbol(&F));

53

54 if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) {

55

56 OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection());

57 for (const MCSymbol *S : EHContTargets) {

58 OS.emitCOFFSymbolIndex(S);

59 }

60 }

61}

62

64 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;

65

66

69

71

72 shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI();

73

76

78 const Function *PerFn = nullptr;

79 if (F.hasPersonalityFn()) {

82 }

83

84 bool forceEmitPersonality = F.hasPersonalityFn() &&

86 F.needsUnwindTableEntry();

87

88 shouldEmitPersonality =

89 forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&

91

93 shouldEmitLSDA = shouldEmitPersonality &&

95

96

97

98 if (Asm->MAI->usesWindowsCFI()) {

100

101

102

106 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);

107 }

108 shouldEmitLSDA = hasEHFunclets;

109 shouldEmitPersonality = false;

110 return;

111 }

112

114}

115

117 if (isAArch64 && CurrentFuncletEntry &&

118 (shouldEmitMoves || shouldEmitPersonality))

119 Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd();

120}

121

122

123

125 if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)

126 return;

127

130 if (F.hasPersonalityFn())

132

133 endFuncletImpl();

134

135

137 return;

138

139 if (shouldEmitPersonality || shouldEmitLSDA) {

140 Asm->OutStreamer->pushSection();

141

142

143 MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(

144 Asm->OutStreamer->getCurrentSectionOnly());

145 Asm->OutStreamer->switchSection(XData);

146

147

148

150 emitCSpecificHandlerTable(MF);

152 emitExceptHandlerTable(MF);

154 emitCXXFrameHandler3Table(MF);

156 emitCLRExceptionTable(MF);

157 else

159

160 Asm->OutStreamer->popSection();

161 }

162

164

166 }

167}

168

169

172 if (MBB)

173 return nullptr;

174

176

177

178

183 StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";

184 return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +

185 Twine(MBB->getNumber()) + "@?0?" +

186 FuncLinkageName + "@4HA");

187}

188

191 CurrentFuncletEntry = &MBB;

192

194

195 if (!Sym) {

197

198

199 Asm->OutStreamer->beginCOFFSymbolDef(Sym);

203 Asm->OutStreamer->endCOFFSymbolDef();

204

205

206

207 Asm->emitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),

208 &F);

209

210

211 Asm->OutStreamer->emitLabel(Sym);

212 }

213

214

215 if (shouldEmitMoves || shouldEmitPersonality) {

216 CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly();

217 Asm->OutStreamer->emitWinCFIStartProc(Sym);

218 }

219

220 if (shouldEmitPersonality) {

222 const Function *PerFn = nullptr;

223

224

225 if (F.hasPersonalityFn())

227 const MCSymbol *PersHandlerSym =

229

230

231

232

233

234

235 if (!CurrentFuncletEntry->isCleanupFuncletEntry())

236 Asm->OutStreamer->emitWinEHHandler(PersHandlerSym, true, true);

237 }

238}

239

241 if (isAArch64 && CurrentFuncletEntry &&

242 (shouldEmitMoves || shouldEmitPersonality)) {

243 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);

244 Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd();

245 }

246 endFuncletImpl();

247}

248

249void WinException::endFuncletImpl() {

250

251 if (!CurrentFuncletEntry)

252 return;

253

255 if (shouldEmitMoves || shouldEmitPersonality) {

258 if (F.hasPersonalityFn())

260

263

265

266

267

270 Twine("$cppxdata$", FuncLinkageName));

271 Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);

274

276

277

278

279 emitCSpecificHandlerTable(MF);

280 } else if (shouldEmitPersonality || shouldEmitLSDA) {

281

282 Asm->OutStreamer->emitWinEHHandlerData();

283

284

285

286 } else {

287

288

289

290 }

291

293

295 }

296

297

298

299

300 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);

301 Asm->OutStreamer->emitWinCFIEndProc();

302 }

303

304

305 CurrentFuncletEntry = nullptr;

306}

307

313}

314

315const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {

316 if (!GV)

318 return create32bitRef(Asm->getSymbol(GV));

319}

320

321const MCExpr *WinException::getLabel(const MCSymbol *Label) {

323 Asm->OutContext);

324}

325

326const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,

327 const MCSymbol *OffsetFrom) {

331}

332

333const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,

334 const MCSymbol *OffsetFrom) {

337 Asm->OutContext);

338}

339

340int WinException::getFrameIndexOffset(int FrameIndex,

342 const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();

344 if (Asm->MAI->usesWindowsCFI()) {

347 true);

349 Asm->MF->getSubtarget()

350 .getTargetLowering()

351 ->getStackPointerRegisterToSaveRestore());

352 return Offset.getFixed();

353 }

354

355

356

361 "Frame offsets with a scalable component are not supported");

362 return Offset.getFixed();

363}

364

365namespace {

366

367

368const int NullState = -1;

369

370struct InvokeStateChange {

371

372

373 const MCSymbol *PreviousEndLabel;

374

375

376

377 const MCSymbol *NewStartLabel;

378

379

380

381 int NewState;

382};

383

384

385

386

387

388

389

390

391

392class InvokeStateChangeIterator {

393 InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,

397 int BaseState)

398 : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) {

399 LastStateChange.PreviousEndLabel = nullptr;

400 LastStateChange.NewStartLabel = nullptr;

401 LastStateChange.NewState = BaseState;

402 scan();

403 }

404

405public:

409

410

411 assert(Begin != End);

412 auto BlockBegin = Begin->begin();

413 auto BlockEnd = std::prev(End)->end();

415 InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),

416 InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));

417 }

418

419

420 bool operator==(const InvokeStateChangeIterator &O) const {

421 assert(BaseState == O.BaseState);

422

423 if (MFI != O.MFI)

424 return false;

425

426 if (MBBI != O.MBBI)

427 return false;

428

429

430

431

432 return CurrentEndLabel == O.CurrentEndLabel;

433 }

434

435 bool operator!=(const InvokeStateChangeIterator &O) const {

437 }

438 InvokeStateChange &operator*() { return LastStateChange; }

439 InvokeStateChange *operator->() { return &LastStateChange; }

440 InvokeStateChangeIterator &operator++() { return scan(); }

441

442private:

443 InvokeStateChangeIterator &scan();

444

445 const WinEHFuncInfo &EHInfo;

446 const MCSymbol *CurrentEndLabel = nullptr;

450 InvokeStateChange LastStateChange;

451 bool VisitingInvoke = false;

452 int BaseState;

453};

454

455}

456

457InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {

458 bool IsNewBlock = false;

459 for (; MFI != MFE; ++MFI, IsNewBlock = true) {

460 if (IsNewBlock)

462 for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) {

464 if (!VisitingInvoke && LastStateChange.NewState != BaseState &&

466

467

468

469 LastStateChange.PreviousEndLabel = CurrentEndLabel;

470 LastStateChange.NewStartLabel = nullptr;

471 LastStateChange.NewState = BaseState;

472 CurrentEndLabel = nullptr;

473

475 return *this;

476 }

477

478

479 if (MI.isEHLabel())

480 continue;

482 if (Label == CurrentEndLabel) {

483 VisitingInvoke = false;

484 continue;

485 }

487

489 continue;

490 auto &StateAndEnd = InvokeMapIter->second;

491 int NewState = StateAndEnd.first;

492

493

494 VisitingInvoke = true;

495 if (NewState == LastStateChange.NewState) {

496

497

498 CurrentEndLabel = StateAndEnd.second;

499 continue;

500 }

501

502 LastStateChange.PreviousEndLabel = CurrentEndLabel;

503 LastStateChange.NewStartLabel = Label;

504 LastStateChange.NewState = NewState;

505

506 CurrentEndLabel = StateAndEnd.second;

507

509 return *this;

510 }

511 }

512

513 if (LastStateChange.NewState != BaseState) {

514

515 LastStateChange.PreviousEndLabel = CurrentEndLabel;

516 LastStateChange.NewStartLabel = nullptr;

517 LastStateChange.NewState = BaseState;

518

519 assert(CurrentEndLabel != nullptr);

520 return *this;

521 }

522

523 CurrentEndLabel = nullptr;

524 return *this;

525}

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {

556 auto &OS = *Asm->OutStreamer;

557 MCContext &Ctx = Asm->OutContext;

559

560 bool VerboseAsm = OS.isVerboseAsm();

561 auto AddComment = [&](const Twine &Comment) {

562 if (VerboseAsm)

563 OS.AddComment(Comment);

564 };

565

566 if (!isAArch64) {

567

568

569 StringRef FLinkageName =

571 MCSymbol *ParentFrameOffset =

573 const MCExpr *MCOffset =

575 Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);

576 }

577

578

579

581 Ctx.createTempSymbol("lsda_begin", true);

584 const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);

587 AddComment("Number of call sites");

588 OS.emitValue(EntryCount, 4);

589

590 OS.emitLabel(TableBegin);

591

592

593

594

595

596

597

598

599 const MCSymbol *LastStartLabel = nullptr;

600 int LastEHState = -1;

601

602

605 while (Stop != End && !Stop->isEHFuncletEntry())

606 ++Stop;

607 for (const auto &StateChange :

608 InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) {

609

610

611 if (LastEHState != -1)

612 emitSEHActionsForRange(FuncInfo, LastStartLabel,

613 StateChange.PreviousEndLabel, LastEHState);

614 LastStartLabel = StateChange.NewStartLabel;

615 LastEHState = StateChange.NewState;

616 }

617

618 OS.emitLabel(TableEnd);

619}

620

621void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,

623 const MCSymbol *EndLabel, int State) {

624 auto &OS = *Asm->OutStreamer;

625 MCContext &Ctx = Asm->OutContext;

626 bool VerboseAsm = OS.isVerboseAsm();

627 auto AddComment = [&](const Twine &Comment) {

628 if (VerboseAsm)

629 OS.AddComment(Comment);

630 };

631

632 assert(BeginLabel && EndLabel);

633 while (State != -1) {

634 const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];

635 const MCExpr *FilterOrFinally;

636 const MCExpr *ExceptOrNull;

641 } else {

642

643

644 FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)

645 : MCConstantExpr::create(1, Ctx);

646 ExceptOrNull = create32bitRef(Handler->getSymbol());

647 }

648

649 AddComment("LabelStart");

650 OS.emitValue(getLabel(BeginLabel), 4);

651 AddComment("LabelEnd");

652 OS.emitValue(getLabel(EndLabel), 4);

653 AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"

654 : "CatchAll");

655 OS.emitValue(FilterOrFinally, 4);

656 AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");

657 OS.emitValue(ExceptOrNull, 4);

658

659 assert(UME.ToState < State && "states should decrease");

661 }

662}

663

664void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {

666 auto &OS = *Asm->OutStreamer;

668

670

672 MCSymbol *FuncInfoXData = nullptr;

673 if (shouldEmitPersonality) {

674

675

676 FuncInfoXData =

677 Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));

678 computeIP2StateTable(MF, FuncInfo, IPToStateTable);

679 } else {

680 FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);

681 }

682

683 int UnwindHelpOffset = 0;

684

685

686

687

688 if (Asm->MAI->usesWindowsCFI() &&

690 UnwindHelpOffset =

692

693 MCSymbol *UnwindMapXData = nullptr;

694 MCSymbol *TryBlockMapXData = nullptr;

695 MCSymbol *IPToStateXData = nullptr;

697 UnwindMapXData = Asm->OutContext.getOrCreateSymbol(

698 Twine("$stateUnwindMap$", FuncLinkageName));

700 TryBlockMapXData =

701 Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));

702 if (!IPToStateTable.empty())

703 IPToStateXData =

704 Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));

705

706 bool VerboseAsm = OS.isVerboseAsm();

707 auto AddComment = [&](const Twine &Comment) {

708 if (VerboseAsm)

709 OS.AddComment(Comment);

710 };

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727 OS.emitValueToAlignment(Align(4));

728 OS.emitLabel(FuncInfoXData);

729

730 AddComment("MagicNumber");

731 OS.emitInt32(0x19930522);

732

733 AddComment("MaxState");

735

736 AddComment("UnwindMap");

737 OS.emitValue(create32bitRef(UnwindMapXData), 4);

738

739 AddComment("NumTryBlocks");

740 OS.emitInt32(FuncInfo.TryBlockMap.size());

741

742 AddComment("TryBlockMap");

743 OS.emitValue(create32bitRef(TryBlockMapXData), 4);

744

745 AddComment("IPMapEntries");

746 OS.emitInt32(IPToStateTable.size());

747

748 AddComment("IPToStateXData");

749 OS.emitValue(create32bitRef(IPToStateXData), 4);

750

751 if (Asm->MAI->usesWindowsCFI() &&

753 AddComment("UnwindHelp");

754 OS.emitInt32(UnwindHelpOffset);

755 }

756

757 AddComment("ESTypeList");

758 OS.emitInt32(0);

759

760 AddComment("EHFlags");

761 if (MMI->getModule()->getModuleFlag("eh-asynch")) {

762 OS.emitInt32(0);

763 } else {

764 OS.emitInt32(1);

765 }

766

767

768

769

770

771 if (UnwindMapXData) {

772 OS.emitLabel(UnwindMapXData);

773 for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {

776 AddComment("ToState");

777 OS.emitInt32(UME.ToState);

778

779 AddComment("Action");

780 OS.emitValue(create32bitRef(CleanupSym), 4);

781 }

782 }

783

784

785

786

787

788

789

790

791 if (TryBlockMapXData) {

792 OS.emitLabel(TryBlockMapXData);

794 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {

795 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];

796

797 MCSymbol *HandlerMapXData = nullptr;

799 HandlerMapXData =

800 Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$")

803 .concat(FuncLinkageName));

804 HandlerMaps.push_back(HandlerMapXData);

805

806

807 assert(0 <= TBME.TryLow && "bad trymap interval");

811 "bad trymap interval");

812

813 AddComment("TryLow");

814 OS.emitInt32(TBME.TryLow);

815

816 AddComment("TryHigh");

817 OS.emitInt32(TBME.TryHigh);

818

819 AddComment("CatchHigh");

821

822 AddComment("NumCatches");

824

825 AddComment("HandlerArray");

826 OS.emitValue(create32bitRef(HandlerMapXData), 4);

827 }

828

829

830 unsigned ParentFrameOffset = 0;

831 if (shouldEmitPersonality) {

834 }

835

836 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {

837 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];

838 MCSymbol *HandlerMapXData = HandlerMaps[I];

839 if (!HandlerMapXData)

840 continue;

841

842

843

844

845

846

847

848 OS.emitLabel(HandlerMapXData);

849 for (const WinEHHandlerType &HT : TBME.HandlerArray) {

850

851

852

853 const MCExpr *FrameAllocOffsetRef = nullptr;

856 assert(Offset != 0 && "Illegal offset for catch object!");

858 } else {

860 }

861

864

865 AddComment("Adjectives");

867

868 AddComment("Type");

870

871 AddComment("CatchObjOffset");

872 OS.emitValue(FrameAllocOffsetRef, 4);

873

874 AddComment("Handler");

875 OS.emitValue(create32bitRef(HandlerSym), 4);

876

877 if (shouldEmitPersonality) {

878 AddComment("ParentFrameOffset");

879 OS.emitInt32(ParentFrameOffset);

880 }

881 }

882 }

883 }

884

885

886

887

888

889 if (IPToStateXData) {

890 OS.emitLabel(IPToStateXData);

891 for (auto &IPStatePair : IPToStateTable) {

892 AddComment("IP");

893 OS.emitValue(IPStatePair.first, 4);

894 AddComment("ToState");

895 OS.emitInt32(IPStatePair.second);

896 }

897 }

898}

899

900void WinException::computeIP2StateTable(

902 SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {

903

905 FuncletEnd = MF->begin(),

906 End = MF->end();

907 FuncletStart != End; FuncletStart = FuncletEnd) {

908

909 while (++FuncletEnd != End) {

910 if (FuncletEnd->isEHFuncletEntry()) {

911 break;

912 }

913 }

914

915

916

917

918 if (FuncletStart->isCleanupFuncletEntry())

919 continue;

920

922 int BaseState;

923 if (FuncletStart == MF->begin()) {

924 BaseState = NullState;

925 StartLabel = Asm->getFunctionBegin();

926 } else {

928 FuncletStart->getBasicBlock()->getFirstNonPHIIt());

932 }

933 assert(StartLabel && "need local function start label");

934 IPToStateTable.push_back(

935 std::make_pair(create32bitRef(StartLabel), BaseState));

936

937 for (const auto &StateChange : InvokeStateChangeIterator::range(

938 FuncInfo, FuncletStart, FuncletEnd, BaseState)) {

939

940

941

942

943 const MCSymbol *ChangeLabel = StateChange.NewStartLabel;

944 if (!ChangeLabel)

945 ChangeLabel = StateChange.PreviousEndLabel;

946

947 const MCExpr *LabelExpression = getLabel(ChangeLabel);

948 IPToStateTable.push_back(

949 std::make_pair(LabelExpression, StateChange.NewState));

950

951 }

952 }

953}

954

955void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,

957

958

959

960

961

962

963

964

965

968 if (FI != INT_MAX) {

969 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();

971 }

972

973 MCContext &Ctx = Asm->OutContext;

974 MCSymbol *ParentFrameOffset =

976 Asm->OutStreamer->emitAssignment(ParentFrameOffset,

978}

979

980

981

982

983void WinException::emitExceptHandlerTable(const MachineFunction *MF) {

984 MCStreamer &OS = *Asm->OutStreamer;

987

989 auto AddComment = [&](const Twine &Comment) {

990 if (VerboseAsm)

992 };

993

995 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);

996

997

998 MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);

1001

1002 const auto *Per = cast(F.getPersonalityFn()->stripPointerCasts());

1003 StringRef PerName = Per->getName();

1004 int BaseState = -1;

1005 if (PerName == "_except_handler4") {

1006

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028 int GSCookieOffset = -2;

1029 const MachineFrameInfo &MFI = MF->getFrameInfo();

1034 GSCookieOffset =

1036 }

1037

1038

1039

1040 int EHCookieOffset = 9999;

1045 EHCookieOffset =

1047 }

1048

1049 AddComment("GSCookieOffset");

1051 AddComment("GSCookieXOROffset");

1053 AddComment("EHCookieOffset");

1055 AddComment("EHCookieXOROffset");

1057 BaseState = -2;

1058 }

1059

1061 for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {

1063 const MCSymbol *ExceptOrFinally =

1065

1066

1067 int ToState = UME.ToState == -1 ? BaseState : UME.ToState;

1068 AddComment("ToState");

1070 AddComment(UME.IsFinally ? "Null" : "FilterFunction");

1072 AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");

1073 OS.emitValue(create32bitRef(ExceptOrFinally), 4);

1074 }

1075}

1076

1078 int Rank = 0;

1079 while (State != -1) {

1080 ++Rank;

1081 State = FuncInfo.ClrEHUnwindMap[State].TryParentState;

1082 }

1083 return Rank;

1084}

1085

1089

1090 while (LeftRank < RightRank) {

1092 --RightRank;

1093 }

1094

1095 while (RightRank < LeftRank) {

1097 --LeftRank;

1098 }

1099

1103 }

1104

1105 return Left;

1106}

1107

1108void WinException::emitCLRExceptionTable(const MachineFunction *MF) {

1109

1110

1111

1112 MCStreamer &OS = *Asm->OutStreamer;

1114 MCSymbol *FuncBeginSym = Asm->getFunctionBegin();

1115 MCSymbol *FuncEndSym = Asm->getFunctionEnd();

1116

1117

1118 struct ClrClause {

1119 const MCSymbol *StartLabel;

1120 const MCSymbol *EndLabel;

1121 int State;

1122 int EnclosingState;

1123 };

1125

1126

1127

1129 assert(NumStates > 0 && "Don't need exception table!");

1130 DenseMap<const MachineBasicBlock *, int> HandlerStates;

1131 for (int State = 0; State < NumStates; ++State) {

1132 MachineBasicBlock *HandlerBlock =

1134 HandlerStates[HandlerBlock] = State;

1135

1136

1137

1139 "ill-formed state numbering");

1140 }

1141

1142 HandlerStates[&MF->front()] = NullState;

1143

1144

1145

1147

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159

1160

1161

1162

1163

1164

1166

1167 std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]);

1168 SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates);

1169

1170

1172 FuncletEnd = MF->begin(),

1173 End = MF->end();

1174 FuncletStart != End; FuncletStart = FuncletEnd) {

1175 int FuncletState = HandlerStates[&*FuncletStart];

1176

1177 MCSymbol *EndSymbol = FuncEndSym;

1178 while (++FuncletEnd != End) {

1179 if (FuncletEnd->isEHFuncletEntry()) {

1181 break;

1182 }

1183 }

1184

1185

1186 OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);

1187 if (FuncletState != NullState) {

1188

1189 EndSymbolMap[FuncletState] = EndSymbol;

1190 }

1191

1192

1193

1194 const MCSymbol *CurrentStartLabel = nullptr;

1195 int CurrentState = NullState;

1197 for (const auto &StateChange :

1198 InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {

1199

1200 int StillPendingState =

1201 getTryAncestor(FuncInfo, CurrentState, StateChange.NewState);

1202 while (CurrentState != StillPendingState) {

1203 assert(CurrentState != NullState &&

1204 "Failed to find still-pending state!");

1205

1206 Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,

1207 CurrentState, FuncletState});

1208

1209 CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState;

1210

1211

1212 if (HandlerStack.back().second == CurrentState)

1213 CurrentStartLabel = HandlerStack.pop_back_val().first;

1214 }

1215

1216 if (StateChange.NewState != CurrentState) {

1217

1218

1219

1220 for (int EnteredState = StateChange.NewState;

1221 EnteredState != CurrentState;

1222 EnteredState =

1223 FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {

1224 int &MinEnclosingState = MinClauseMap[EnteredState];

1225 if (FuncletState < MinEnclosingState)

1226 MinEnclosingState = FuncletState;

1227 }

1228

1229

1230 HandlerStack.emplace_back(CurrentStartLabel, CurrentState);

1231 CurrentStartLabel = StateChange.NewStartLabel;

1232 CurrentState = StateChange.NewState;

1233 }

1234 }

1236 }

1237

1238

1240 for (ClrClause &Clause : Clauses) {

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289 const MCExpr *ClauseBegin =

1290 getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);

1291 const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);

1292

1293 const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];

1296 const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);

1297 MCSymbol *EndSym = EndSymbolMap[Clause.State];

1298 const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);

1299

1300 uint32_t Flags = 0;

1301 switch (Entry.HandlerType) {

1303

1304 break;

1307 break;

1310 break;

1313 break;

1314 }

1315 if (Clause.EnclosingState != MinClauseMap[Clause.State]) {

1316

1317

1318 assert(Clause.EnclosingState > MinClauseMap[Clause.State]);

1320 }

1322

1323

1326

1327

1330

1331

1334 }

1335}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator MBBI

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file contains constants used for implementing Dwarf debug support.

Module.h This file contains the declarations for the Module class.

Promote Memory to Register

This file describes how to lower LLVM code to machine code.

static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right)

Definition WinException.cpp:1086

static int getTryRank(const WinEHFuncInfo &FuncInfo, int State)

Definition WinException.cpp:1077

static MCSymbol * getMCSymbolForMBB(AsmPrinter *Asm, const MachineBasicBlock *MBB)

Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.

Definition WinException.cpp:170

This class is intended to be used as a driving class for all asm writers.

MachineFunction * MF

The current machine function.

MCContext & OutContext

This is the context for the output file that we are streaming.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

static bool callToNoUnwindFunction(const MachineInstr *MI)

Return ‘true’ if this is a call to a function marked ‘nounwind’.

AsmPrinter * Asm

Target of directive emission.

MCSymbol * emitExceptionTable()

Emit landing pads and actions.

MachineModuleInfo * MMI

Collected machine module information.

EHStreamer(AsmPrinter *A)

static StringRef dropLLVMManglingEscape(StringRef Name)

If the given string begins with the GlobalValue name mangling escape character '\1',...

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

LLVM_ABI MCSymbol * getOrCreateParentFrameOffsetSymbol(const Twine &FuncName)

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

Base class for the full range of assembler expressions which are needed for parsing.

Instances of this class represent a uniqued identifier for a section in the current translation unit.

virtual bool isVerboseAsm() const

Return true if this streamer supports verbose assembly and if it is enabled.

virtual void AddComment(const Twine &T, bool EOL=true)

Add a textual comment.

void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

virtual void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0)

Emit some number of copies of Value until the byte alignment ByteAlignment is reached.

void emitInt32(uint64_t Value)

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

MachineInstrBundleIterator< const MachineInstr > const_iterator

bool isEHFuncletEntry() const

Returns true if this is the entry block of an EH funclet.

bool isCleanupFuncletEntry() const

Returns true if this is the entry block of a cleanup funclet.

int getStackProtectorIndex() const

Return the index for the stack protector object.

bool hasStackProtectorIndex() const

const WinEHFuncInfo * getWinEHFuncInfo() const

getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

const std::vector< MCSymbol * > & getEHContTargets() const

Returns a reference to a list of symbols that are targets for Windows EH Continuation Guard.

MCContext & getContext() const

Function & getFunction()

Return the LLVM function that this machine code represents.

const std::vector< LandingPadInfo > & getLandingPads() const

Return a reference to the landing pad info for the current function.

const MachineBasicBlock & front() const

bool hasEHFunclets() const

BasicBlockListType::const_iterator const_iterator

Representation of each machine instruction.

A Module instance is used to store all the information related to an LLVM module.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

int64_t getFixed() const

Returns the fixed component of the stack.

static StackOffset getFixed(int64_t Fixed)

StringRef - Represent a constant reference to a string, i.e.

virtual StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const

getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...

virtual StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const

Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...

virtual unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const

virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const

getFrameIndexReference - This method should return the base register and offset used to reference a f...

unsigned getLSDAEncoding() const

virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const

unsigned getPersonalityEncoding() const

virtual const TargetFrameLowering * getFrameLowering() const

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

void endFunction(const MachineFunction *) override

Gather and emit post-function exception information.

Definition WinException.cpp:124

void markFunctionEnd() override

Definition WinException.cpp:116

void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override

Emit target-specific EH funclet machinery.

Definition WinException.cpp:189

void endModule() override

Emit all exception information that should come after the content.

Definition WinException.cpp:47

WinException(AsmPrinter *A)

Definition WinException.cpp:35

void endFunclet() override

Definition WinException.cpp:240

void beginFunction(const MachineFunction *MF) override

Gather pre-function exception information.

Definition WinException.cpp:63

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ IMAGE_SYM_CLASS_STATIC

Static.

@ IMAGE_SYM_DTYPE_FUNCTION

A function that returns a base type.

@ SCT_COMPLEX_TYPE_SHIFT

Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

APInt operator*(APInt a, uint64_t RHS)

bool operator!=(uint64_t V1, const APInt &V2)

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)

Returns a concatenated range across two or more ranges.

bool isNoOpWithoutInvoke(EHPersonality Pers)

Return true if this personality may be safely removed if there are no invoke instructions remaining i...

LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)

See if the given exception handling personality function is one that we understand.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

int ToState

If unwinding continues through this handler, transition to the handler at this state.

MBBOrBasicBlock Handler

Holds the __except or __finally basic block.

const Function * Filter

Holds the filter expression function.

SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap

SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap

DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap

SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap

DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap

SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap

GlobalVariable * TypeDescriptor

union llvm::WinEHHandlerType::@246205307012256373115155017221207221353102114334 CatchObj

The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.

SmallVector< WinEHHandlerType, 1 > HandlerArray