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);

41}

42

44

45

46

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

53

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

55

57 for (const MCSymbol *S : EHContTargets) {

58 OS.emitCOFFSymbolIndex(S);

59 }

60 }

61}

62

64 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;

65

66

69

71

73

76

78 const Function *PerFn = nullptr;

79 if (F.hasPersonalityFn()) {

80 PerFn = dyn_cast(F.getPersonalityFn()->stripPointerCasts());

82 }

83

84 bool forceEmitPersonality = F.hasPersonalityFn() &&

86 F.needsUnwindTableEntry();

87

88 shouldEmitPersonality =

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

91

93 shouldEmitLSDA = shouldEmitPersonality &&

95

96

97

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))

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) {

141

142

146

147

148

150 emitCSpecificHandlerTable(MF);

152 emitExceptHandlerTable(MF);

154 emitCXXFrameHandler3Table(MF);

156 emitCLRExceptionTable(MF);

157 else

159

161 }

162

164

165 EHContTargets.insert(EHContTargets.end(), MF->getCatchretTargets().begin(),

167 }

168}

169

170

173 if (MBB)

174 return nullptr;

175

177

178

179

187 FuncLinkageName + "@4HA");

188}

189

192 CurrentFuncletEntry = &MBB;

193

195

196 if (Sym) {

198

199

205

206

207

209 &F);

210

211

213 }

214

215

216 if (shouldEmitMoves || shouldEmitPersonality) {

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

219 }

220

221 if (shouldEmitPersonality) {

223 const Function *PerFn = nullptr;

224

225

226 if (F.hasPersonalityFn())

227 PerFn = dyn_cast(F.getPersonalityFn()->stripPointerCasts());

228 const MCSymbol *PersHandlerSym =

230

231

232

233

234

235

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

238 }

239}

240

242 if (isAArch64 && CurrentFuncletEntry &&

243 (shouldEmitMoves || shouldEmitPersonality)) {

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

246 }

247 endFuncletImpl();

248}

249

250void WinException::endFuncletImpl() {

251

252 if (!CurrentFuncletEntry)

253 return;

254

256 if (shouldEmitMoves || shouldEmitPersonality) {

259 if (F.hasPersonalityFn())

261

264

266

267

268

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

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

275

277

278

279

280 emitCSpecificHandlerTable(MF);

281 } else if (shouldEmitPersonality || shouldEmitLSDA) {

282

284

285

286

287 } else {

288

289

290

291 }

292

293

294

295

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

298 }

299

300

301 CurrentFuncletEntry = nullptr;

302}

303

311}

312

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

314 if (!GV)

317}

318

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

322}

323

324const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {

328}

329

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

331 const MCSymbol *OffsetFrom) {

335}

336

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

338 const MCSymbol *OffsetFrom) {

342}

343

344int WinException::getFrameIndexOffset(int FrameIndex,

351 true);

356 return Offset.getFixed();

357 }

358

359

360

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

366 return Offset.getFixed();

367}

368

369namespace {

370

371

372const int NullState = -1;

373

374struct InvokeStateChange {

375

376

377 const MCSymbol *PreviousEndLabel;

378

379

380

381 const MCSymbol *NewStartLabel;

382

383

384

385 int NewState;

386};

387

388

389

390

391

392

393

394

395

396class InvokeStateChangeIterator {

397 InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,

401 int BaseState)

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

403 LastStateChange.PreviousEndLabel = nullptr;

404 LastStateChange.NewStartLabel = nullptr;

405 LastStateChange.NewState = BaseState;

406 scan();

407 }

408

409public:

413

414

416 auto BlockBegin = Begin->begin();

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

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

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

421 }

422

423

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

425 assert(BaseState == O.BaseState);

426

427 if (MFI != O.MFI)

428 return false;

429

430 if (MBBI != O.MBBI)

431 return false;

432

433

434

435

436 return CurrentEndLabel == O.CurrentEndLabel;

437 }

438

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

441 }

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

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

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

445

446private:

447 InvokeStateChangeIterator &scan();

448

450 const MCSymbol *CurrentEndLabel = nullptr;

454 InvokeStateChange LastStateChange;

455 bool VisitingInvoke = false;

456 int BaseState;

457};

458

459}

460

461InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {

462 bool IsNewBlock = false;

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

464 if (IsNewBlock)

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

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

470

471

472

473 LastStateChange.PreviousEndLabel = CurrentEndLabel;

474 LastStateChange.NewStartLabel = nullptr;

475 LastStateChange.NewState = BaseState;

476 CurrentEndLabel = nullptr;

477

479 return *this;

480 }

481

482

483 if (MI.isEHLabel())

484 continue;

486 if (Label == CurrentEndLabel) {

487 VisitingInvoke = false;

488 continue;

489 }

491

493 continue;

494 auto &StateAndEnd = InvokeMapIter->second;

495 int NewState = StateAndEnd.first;

496

497

498 VisitingInvoke = true;

499 if (NewState == LastStateChange.NewState) {

500

501

502 CurrentEndLabel = StateAndEnd.second;

503 continue;

504 }

505

506 LastStateChange.PreviousEndLabel = CurrentEndLabel;

507 LastStateChange.NewStartLabel = Label;

508 LastStateChange.NewState = NewState;

509

510 CurrentEndLabel = StateAndEnd.second;

511

513 return *this;

514 }

515 }

516

517 if (LastStateChange.NewState != BaseState) {

518

519 LastStateChange.PreviousEndLabel = CurrentEndLabel;

520 LastStateChange.NewStartLabel = nullptr;

521 LastStateChange.NewState = BaseState;

522

523 assert(CurrentEndLabel != nullptr);

524 return *this;

525 }

526

527 CurrentEndLabel = nullptr;

528 return *this;

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

555

556

557

558

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

563

564 bool VerboseAsm = OS.isVerboseAsm();

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

566 if (VerboseAsm)

567 OS.AddComment(Comment);

568 };

569

570 if (!isAArch64) {

571

572

575 MCSymbol *ParentFrameOffset =

577 const MCExpr *MCOffset =

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

580 }

581

582

583

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

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

591 AddComment("Number of call sites");

592 OS.emitValue(EntryCount, 4);

593

594 OS.emitLabel(TableBegin);

595

596

597

598

599

600

601

602

603 const MCSymbol *LastStartLabel = nullptr;

604 int LastEHState = -1;

605

606

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

610 ++Stop;

611 for (const auto &StateChange :

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

613

614

615 if (LastEHState != -1)

616 emitSEHActionsForRange(FuncInfo, LastStartLabel,

617 StateChange.PreviousEndLabel, LastEHState);

618 LastStartLabel = StateChange.NewStartLabel;

619 LastEHState = StateChange.NewState;

620 }

621

622 OS.emitLabel(TableEnd);

623}

624

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

627 const MCSymbol *EndLabel, int State) {

630 bool VerboseAsm = OS.isVerboseAsm();

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

632 if (VerboseAsm)

633 OS.AddComment(Comment);

634 };

635

636 assert(BeginLabel && EndLabel);

637 while (State != -1) {

639 const MCExpr *FilterOrFinally;

640 const MCExpr *ExceptOrNull;

641 auto *Handler = cast<MachineBasicBlock *>(UME.Handler);

645 } else {

646

647

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

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

651 }

652

653 AddComment("LabelStart");

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

655 AddComment("LabelEnd");

656 OS.emitValue(getLabelPlusOne(EndLabel), 4);

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

658 : "CatchAll");

659 OS.emitValue(FilterOrFinally, 4);

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

661 OS.emitValue(ExceptOrNull, 4);

662

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

665 }

666}

667

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

672

674

676 MCSymbol *FuncInfoXData = nullptr;

677 if (shouldEmitPersonality) {

678

679

680 FuncInfoXData =

682 computeIP2StateTable(MF, FuncInfo, IPToStateTable);

683 } else {

685 }

686

687 int UnwindHelpOffset = 0;

688

689

690

691

694 UnwindHelpOffset =

696

697 MCSymbol *UnwindMapXData = nullptr;

698 MCSymbol *TryBlockMapXData = nullptr;

699 MCSymbol *IPToStateXData = nullptr;

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

704 TryBlockMapXData =

706 if (!IPToStateTable.empty())

707 IPToStateXData =

709

710 bool VerboseAsm = OS.isVerboseAsm();

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

712 if (VerboseAsm)

713 OS.AddComment(Comment);

714 };

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731 OS.emitValueToAlignment(Align(4));

732 OS.emitLabel(FuncInfoXData);

733

734 AddComment("MagicNumber");

735 OS.emitInt32(0x19930522);

736

737 AddComment("MaxState");

739

740 AddComment("UnwindMap");

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

742

743 AddComment("NumTryBlocks");

745

746 AddComment("TryBlockMap");

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

748

749 AddComment("IPMapEntries");

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

751

752 AddComment("IPToStateXData");

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

754

757 AddComment("UnwindHelp");

758 OS.emitInt32(UnwindHelpOffset);

759 }

760

761 AddComment("ESTypeList");

762 OS.emitInt32(0);

763

764 AddComment("EHFlags");

766 OS.emitInt32(0);

767 } else {

768 OS.emitInt32(1);

769 }

770

771

772

773

774

775 if (UnwindMapXData) {

776 OS.emitLabel(UnwindMapXData);

779 Asm, dyn_cast_if_present<MachineBasicBlock *>(UME.Cleanup));

780 AddComment("ToState");

782

783 AddComment("Action");

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

785 }

786 }

787

788

789

790

791

792

793

794

795 if (TryBlockMapXData) {

796 OS.emitLabel(TryBlockMapXData);

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

800

801 MCSymbol *HandlerMapXData = nullptr;

803 HandlerMapXData =

807 .concat(FuncLinkageName));

808 HandlerMaps.push_back(HandlerMapXData);

809

810

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

815 "bad trymap interval");

816

817 AddComment("TryLow");

819

820 AddComment("TryHigh");

822

823 AddComment("CatchHigh");

825

826 AddComment("NumCatches");

828

829 AddComment("HandlerArray");

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

831 }

832

833

834 unsigned ParentFrameOffset = 0;

835 if (shouldEmitPersonality) {

838 }

839

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

842 MCSymbol *HandlerMapXData = HandlerMaps[I];

843 if (!HandlerMapXData)

844 continue;

845

846

847

848

849

850

851

852 OS.emitLabel(HandlerMapXData);

854

855

856

857 const MCExpr *FrameAllocOffsetRef = nullptr;

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

862 } else {

864 }

865

867 Asm, dyn_cast_if_present<MachineBasicBlock *>(HT.Handler));

868

869 AddComment("Adjectives");

871

872 AddComment("Type");

874

875 AddComment("CatchObjOffset");

876 OS.emitValue(FrameAllocOffsetRef, 4);

877

878 AddComment("Handler");

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

880

881 if (shouldEmitPersonality) {

882 AddComment("ParentFrameOffset");

883 OS.emitInt32(ParentFrameOffset);

884 }

885 }

886 }

887 }

888

889

890

891

892

893 if (IPToStateXData) {

894 OS.emitLabel(IPToStateXData);

895 for (auto &IPStatePair : IPToStateTable) {

896 AddComment("IP");

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

898 AddComment("ToState");

899 OS.emitInt32(IPStatePair.second);

900 }

901 }

902}

903

904void WinException::computeIP2StateTable(

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

907

909 FuncletEnd = MF->begin(),

911 FuncletStart != End; FuncletStart = FuncletEnd) {

912

913 while (++FuncletEnd != End) {

914 if (FuncletEnd->isEHFuncletEntry()) {

915 break;

916 }

917 }

918

919

920

921

922 if (FuncletStart->isCleanupFuncletEntry())

923 continue;

924

926 int BaseState;

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

928 BaseState = NullState;

930 } else {

931 auto *FuncletPad =

932 cast(FuncletStart->getBasicBlock()->getFirstNonPHI());

936 }

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

938 IPToStateTable.push_back(

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

940

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

942 FuncInfo, FuncletStart, FuncletEnd, BaseState)) {

943

944

945

946

947 const MCSymbol *ChangeLabel = StateChange.NewStartLabel;

948 if (!ChangeLabel)

949 ChangeLabel = StateChange.PreviousEndLabel;

950

951

952

953

954

955 const MCExpr *LabelExpression = (isAArch64 || isThumb)

956 ? getLabel(ChangeLabel)

957 : getLabelPlusOne(ChangeLabel);

958 IPToStateTable.push_back(

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

960

961 }

962 }

963}

964

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

967

968

969

970

971

972

973

974

975

978 if (FI != INT_MAX) {

981 }

982

984 MCSymbol *ParentFrameOffset =

988}

989

990

991

992

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

997

998 bool VerboseAsm = OS.isVerboseAsm();

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

1000 if (VerboseAsm)

1001 OS.AddComment(Comment);

1002 };

1003

1005 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);

1006

1007

1009 OS.emitValueToAlignment(Align(4));

1010 OS.emitLabel(LSDALabel);

1011

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

1013 StringRef PerName = Per->getName();

1014 int BaseState = -1;

1015 if (PerName == "_except_handler4") {

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038 int GSCookieOffset = -2;

1044 GSCookieOffset =

1046 }

1047

1048

1049

1050 int EHCookieOffset = 9999;

1055 EHCookieOffset =

1057 }

1058

1059 AddComment("GSCookieOffset");

1060 OS.emitInt32(GSCookieOffset);

1061 AddComment("GSCookieXOROffset");

1062 OS.emitInt32(0);

1063 AddComment("EHCookieOffset");

1064 OS.emitInt32(EHCookieOffset);

1065 AddComment("EHCookieXOROffset");

1066 OS.emitInt32(0);

1067 BaseState = -2;

1068 }

1069

1072 auto *Handler = cast<MachineBasicBlock *>(UME.Handler);

1073 const MCSymbol *ExceptOrFinally =

1075

1076

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

1078 AddComment("ToState");

1079 OS.emitInt32(ToState);

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

1081 OS.emitValue(create32bitRef(UME.Filter), 4);

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

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

1084 }

1085}

1086

1088 int Rank = 0;

1089 while (State != -1) {

1090 ++Rank;

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

1092 }

1093 return Rank;

1094}

1095

1099

1100 while (LeftRank < RightRank) {

1102 --RightRank;

1103 }

1104

1105 while (RightRank < LeftRank) {

1107 --LeftRank;

1108 }

1109

1113 }

1114

1115 return Left;

1116}

1117

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

1119

1120

1121

1126

1127

1128 struct ClrClause {

1129 const MCSymbol *StartLabel;

1130 const MCSymbol *EndLabel;

1131 int State;

1132 int EnclosingState;

1133 };

1135

1136

1137

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

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

1143 cast<MachineBasicBlock *>(FuncInfo.ClrEHUnwindMap[State].Handler);

1144 HandlerStates[HandlerBlock] = State;

1145

1146

1147

1149 "ill-formed state numbering");

1150 }

1151

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

1153

1154

1155

1156 OS.emitInt32(0xffffffff);

1157

1158 OS.emitInt32(NumStates);

1159

1160

1161

1162

1163

1164

1165

1166

1167

1168

1169

1170

1171

1172

1173

1174

1176

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

1179

1180

1182 FuncletEnd = MF->begin(),

1184 FuncletStart != End; FuncletStart = FuncletEnd) {

1185 int FuncletState = HandlerStates[&*FuncletStart];

1186

1187 MCSymbol *EndSymbol = FuncEndSym;

1188 while (++FuncletEnd != End) {

1189 if (FuncletEnd->isEHFuncletEntry()) {

1191 break;

1192 }

1193 }

1194

1195

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

1197 if (FuncletState != NullState) {

1198

1199 EndSymbolMap[FuncletState] = EndSymbol;

1200 }

1201

1202

1203

1204 const MCSymbol *CurrentStartLabel = nullptr;

1205 int CurrentState = NullState;

1207 for (const auto &StateChange :

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

1209

1210 int StillPendingState =

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

1212 while (CurrentState != StillPendingState) {

1213 assert(CurrentState != NullState &&

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

1215

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

1217 CurrentState, FuncletState});

1218

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

1220

1221

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

1223 CurrentStartLabel = HandlerStack.pop_back_val().first;

1224 }

1225

1226 if (StateChange.NewState != CurrentState) {

1227

1228

1229

1230 for (int EnteredState = StateChange.NewState;

1231 EnteredState != CurrentState;

1232 EnteredState =

1233 FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {

1234 int &MinEnclosingState = MinClauseMap[EnteredState];

1235 if (FuncletState < MinEnclosingState)

1236 MinEnclosingState = FuncletState;

1237 }

1238

1239

1240 HandlerStack.emplace_back(CurrentStartLabel, CurrentState);

1241 CurrentStartLabel = StateChange.NewStartLabel;

1242 CurrentState = StateChange.NewState;

1243 }

1244 }

1246 }

1247

1248

1249 OS.emitInt32(Clauses.size());

1250 for (ClrClause &Clause : Clauses) {

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

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299 const MCExpr *ClauseBegin =

1300 getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);

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

1302

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

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

1309

1311 switch (Entry.HandlerType) {

1313

1314 break;

1317 break;

1320 break;

1323 break;

1324 }

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

1326

1327

1330 }

1331 OS.emitInt32(Flags);

1332

1333

1334 OS.emitValue(ClauseBegin, 4);

1335 OS.emitValue(ClauseEnd, 4);

1336

1337

1338 OS.emitValue(HandlerBegin, 4);

1339 OS.emitValue(HandlerEnd, 4);

1340

1341

1343 OS.emitInt32(Entry.TypeToken);

1344 }

1345}

MachineBasicBlock MachineBasicBlock::iterator MBBI

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

This file contains constants used for implementing Dwarf debug support.

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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

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

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

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

Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.

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

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

MCSymbol * getSymbol(const GlobalValue *GV) const

TargetMachine & TM

Target machine description.

MCSymbol * getFunctionBegin() const

const MCAsmInfo * MAI

Target Asm Printer information.

MachineFunction * MF

The current machine function.

MCSymbol * CurrentFnSym

The symbol for the current function.

void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const

Emit an alignment directive to the specified power of two boundary.

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.

MCSymbol * getFunctionEnd() const

Emits exception handling directives.

AsmPrinter * Asm

Target of directive emission.

MCSymbol * emitExceptionTable()

Emit landing pads and actions.

MachineModuleInfo * MMI

Collected machine module information.

static bool callToNoUnwindFunction(const MachineInstr *MI)

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

static StringRef dropLLVMManglingEscape(StringRef Name)

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

bool usesWindowsCFI() const

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

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 const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

const MCObjectFileInfo * getObjectFileInfo() const

MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

MCSymbol * getOrCreateParentFrameOffsetSymbol(const Twine &FuncName)

MCSymbol * getOrCreateLSDASymbol(const Twine &FuncName)

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.

MCSection * getGEHContSection() const

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

Streaming machine code generation interface.

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

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

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

bool isEHFuncletEntry() const

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

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

Align getAlignment() const

Return alignment of the basic block.

bool isCleanupFuncletEntry() const

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

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

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.

MCContext & getContext() const

Align getAlignment() const

getAlignment - Return the alignment of the function.

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 std::vector< MCSymbol * > & getCatchretTargets() const

Returns a reference to a list of symbols that we have catchrets.

const MachineBasicBlock & front() const

bool hasEHFunclets() const

BasicBlockListType::const_iterator const_iterator

Representation of each machine instruction.

const Module * getModule() const

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

Metadata * getModuleFlag(StringRef Key) const

Return the corresponding value if Key appears in module flags, otherwise return null.

Wrapper class representing virtual and physical registers.

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)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StackOffset holds a fixed and a scalable offset in bytes.

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.

Information about stack frame layout on the target.

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...

Register getStackPointerRegisterToSaveRestore() const

If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...

unsigned getLSDAEncoding() const

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

unsigned getPersonalityEncoding() const

const Triple & getTargetTriple() const

virtual const TargetFrameLowering * getFrameLowering() const

virtual const TargetLowering * getTargetLowering() const

bool isThumb() const

Tests whether the target is Thumb (little and big endian).

bool isAArch64() const

Tests whether the target is AArch64 (little and big endian).

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

LLVM Value Representation.

StringRef getName() const

Return a constant reference to the value's name.

void endFunction(const MachineFunction *) override

Gather and emit post-function exception information.

void markFunctionEnd() override

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

Emit target-specific EH funclet machinery.

void endModule() override

Emit all exception information that should come after the content.

WinException(AsmPrinter *A)

void endFunclet() override

void beginFunction(const MachineFunction *MF) override

Gather pre-function exception information.

A range adaptor for a pair of iterators.

@ 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.

APInt operator*(APInt a, uint64_t RHS)

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

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

Convenience function for iterating over sub-ranges.

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...

EHPersonality classifyEHPersonality(const Value *Pers)

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

This struct is a compact representation of a valid (non-zero power of two) alignment.

Similar to CxxUnwindMapEntry, but supports SEH filters.

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

union llvm::WinEHHandlerType::@253 CatchObj

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

GlobalVariable * TypeDescriptor

SmallVector< WinEHHandlerType, 1 > HandlerArray