1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "WinException.h" |
14 | #include "llvm/ADT/Twine.h" |
15 | #include "llvm/BinaryFormat/COFF.h" |
16 | #include "llvm/BinaryFormat/Dwarf.h" |
17 | #include "llvm/CodeGen/AsmPrinter.h" |
18 | #include "llvm/CodeGen/MachineFrameInfo.h" |
19 | #include "llvm/CodeGen/MachineFunction.h" |
20 | #include "llvm/CodeGen/MachineModuleInfo.h" |
21 | #include "llvm/CodeGen/TargetFrameLowering.h" |
22 | #include "llvm/CodeGen/TargetLowering.h" |
23 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
24 | #include "llvm/CodeGen/WinEHFuncInfo.h" |
25 | #include "llvm/IR/DataLayout.h" |
26 | #include "llvm/IR/Mangler.h" |
27 | #include "llvm/IR/Module.h" |
28 | #include "llvm/MC/MCAsmInfo.h" |
29 | #include "llvm/MC/MCContext.h" |
30 | #include "llvm/MC/MCExpr.h" |
31 | #include "llvm/MC/MCSection.h" |
32 | #include "llvm/MC/MCStreamer.h" |
33 | #include "llvm/MC/MCSymbol.h" |
34 | #include "llvm/Support/ErrorHandling.h" |
35 | #include "llvm/Support/FormattedStream.h" |
36 | #include "llvm/Target/TargetLoweringObjectFile.h" |
37 | #include "llvm/Target/TargetMachine.h" |
38 | #include "llvm/Target/TargetOptions.h" |
39 | using namespace llvm; |
40 | |
41 | WinException::WinException(AsmPrinter *A) : EHStreamer(A) { |
42 | |
43 | |
44 | useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64); |
45 | isAArch64 = Asm->TM.getTargetTriple().isAArch64(); |
46 | } |
47 | |
48 | WinException::~WinException() {} |
49 | |
50 | |
51 | |
52 | void WinException::endModule() { |
53 | auto &OS = *Asm->OutStreamer; |
54 | const Module *M = MMI->getModule(); |
55 | for (const Function &F : *M) |
56 | if (F.hasFnAttribute("safeseh")) |
57 | OS.EmitCOFFSafeSEH(Asm->getSymbol(&F)); |
58 | |
59 | if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) { |
60 | |
61 | OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection()); |
62 | for (const MCSymbol *S : EHContTargets) { |
63 | OS.EmitCOFFSymbolIndex(S); |
64 | } |
65 | } |
66 | } |
67 | |
68 | void WinException::beginFunction(const MachineFunction *MF) { |
69 | shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; |
70 | |
71 | |
72 | bool hasLandingPads = !MF->getLandingPads().empty(); |
73 | bool hasEHFunclets = MF->hasEHFunclets(); |
74 | |
75 | const Function &F = MF->getFunction(); |
76 | |
77 | shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI(); |
78 | |
79 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); |
80 | unsigned PerEncoding = TLOF.getPersonalityEncoding(); |
81 | |
82 | EHPersonality Per = EHPersonality::Unknown; |
83 | const Function *PerFn = nullptr; |
84 | if (F.hasPersonalityFn()) { |
85 | PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); |
86 | Per = classifyEHPersonality(PerFn); |
87 | } |
88 | |
89 | bool forceEmitPersonality = F.hasPersonalityFn() && |
90 | !isNoOpWithoutInvoke(Per) && |
91 | F.needsUnwindTableEntry(); |
92 | |
93 | shouldEmitPersonality = |
94 | forceEmitPersonality || ((hasLandingPads || hasEHFunclets) && |
95 | PerEncoding != dwarf::DW_EH_PE_omit && PerFn); |
96 | |
97 | unsigned LSDAEncoding = TLOF.getLSDAEncoding(); |
98 | shouldEmitLSDA = shouldEmitPersonality && |
99 | LSDAEncoding != dwarf::DW_EH_PE_omit; |
100 | |
101 | |
102 | |
103 | if (!Asm->MAI->usesWindowsCFI()) { |
104 | if (Per == EHPersonality::MSVC_X86SEH && !hasEHFunclets) { |
105 | |
106 | |
107 | |
108 | const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); |
109 | StringRef FLinkageName = |
110 | GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); |
111 | emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); |
112 | } |
113 | shouldEmitLSDA = hasEHFunclets; |
114 | shouldEmitPersonality = false; |
115 | return; |
116 | } |
117 | |
118 | beginFunclet(MF->front(), Asm->CurrentFnSym); |
119 | } |
120 | |
121 | void WinException::markFunctionEnd() { |
122 | if (isAArch64 && CurrentFuncletEntry && |
123 | (shouldEmitMoves || shouldEmitPersonality)) |
124 | Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd(); |
125 | } |
126 | |
127 | |
128 | |
129 | void WinException::endFunction(const MachineFunction *MF) { |
130 | if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA) |
| 1 | Assuming field 'shouldEmitPersonality' is true | |
|
131 | return; |
132 | |
133 | const Function &F = MF->getFunction(); |
134 | EHPersonality Per = EHPersonality::Unknown; |
135 | if (F.hasPersonalityFn()) |
| 2 | | Assuming the condition is true | |
|
| |
136 | Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts()); |
137 | |
138 | |
139 | |
140 | |
141 | if (!isFuncletEHPersonality(Per)) { |
| |
142 | MachineFunction *NonConstMF = const_cast<MachineFunction*>(MF); |
143 | NonConstMF->tidyLandingPads(); |
144 | } |
145 | |
146 | endFuncletImpl(); |
147 | |
148 | |
149 | if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets()) |
150 | return; |
151 | |
152 | if (shouldEmitPersonality || shouldEmitLSDA) { |
153 | Asm->OutStreamer->PushSection(); |
154 | |
155 | |
156 | MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection( |
157 | Asm->OutStreamer->getCurrentSectionOnly()); |
158 | Asm->OutStreamer->SwitchSection(XData); |
159 | |
160 | |
161 | |
162 | if (Per == EHPersonality::MSVC_TableSEH) |
| |
163 | emitCSpecificHandlerTable(MF); |
164 | else if (Per == EHPersonality::MSVC_X86SEH) |
| |
165 | emitExceptHandlerTable(MF); |
166 | else if (Per == EHPersonality::MSVC_CXX) |
| |
167 | emitCXXFrameHandler3Table(MF); |
168 | else if (Per == EHPersonality::CoreCLR) |
| |
169 | emitCLRExceptionTable(MF); |
| 9 | | Calling 'WinException::emitCLRExceptionTable' | |
|
170 | else |
171 | emitExceptionTable(); |
172 | |
173 | Asm->OutStreamer->PopSection(); |
174 | } |
175 | |
176 | if (!MF->getCatchretTargets().empty()) { |
177 | |
178 | EHContTargets.insert(EHContTargets.end(), MF->getCatchretTargets().begin(), |
179 | MF->getCatchretTargets().end()); |
180 | } |
181 | } |
182 | |
183 | |
184 | static MCSymbol *getMCSymbolForMBB(AsmPrinter *Asm, |
185 | const MachineBasicBlock *MBB) { |
186 | if (!MBB) |
187 | return nullptr; |
188 | |
189 | assert(MBB->isEHFuncletEntry()); |
190 | |
191 | |
192 | |
193 | const MachineFunction *MF = MBB->getParent(); |
194 | const Function &F = MF->getFunction(); |
195 | StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); |
196 | MCContext &Ctx = MF->getContext(); |
197 | StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch"; |
198 | return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" + |
199 | Twine(MBB->getNumber()) + "@?0?" + |
200 | FuncLinkageName + "@4HA"); |
201 | } |
202 | |
203 | void WinException::beginFunclet(const MachineBasicBlock &MBB, |
204 | MCSymbol *Sym) { |
205 | CurrentFuncletEntry = &MBB; |
206 | |
207 | const Function &F = Asm->MF->getFunction(); |
208 | |
209 | if (!Sym) { |
210 | Sym = getMCSymbolForMBB(Asm, &MBB); |
211 | |
212 | |
213 | Asm->OutStreamer->BeginCOFFSymbolDef(Sym); |
214 | Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); |
215 | Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION |
216 | << COFF::SCT_COMPLEX_TYPE_SHIFT); |
217 | Asm->OutStreamer->EndCOFFSymbolDef(); |
218 | |
219 | |
220 | |
221 | Asm->emitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()), |
222 | &F); |
223 | |
224 | |
225 | Asm->OutStreamer->emitLabel(Sym); |
226 | } |
227 | |
228 | |
229 | if (shouldEmitMoves || shouldEmitPersonality) { |
230 | CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly(); |
231 | Asm->OutStreamer->EmitWinCFIStartProc(Sym); |
232 | } |
233 | |
234 | if (shouldEmitPersonality) { |
235 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); |
236 | const Function *PerFn = nullptr; |
237 | |
238 | |
239 | if (F.hasPersonalityFn()) |
240 | PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); |
241 | const MCSymbol *PersHandlerSym = |
242 | TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI); |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | if (!CurrentFuncletEntry->isCleanupFuncletEntry()) |
250 | Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true); |
251 | } |
252 | } |
253 | |
254 | void WinException::endFunclet() { |
255 | if (isAArch64 && CurrentFuncletEntry && |
256 | (shouldEmitMoves || shouldEmitPersonality)) { |
257 | Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection); |
258 | Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd(); |
259 | } |
260 | endFuncletImpl(); |
261 | } |
262 | |
263 | void WinException::endFuncletImpl() { |
264 | |
265 | if (!CurrentFuncletEntry) |
266 | return; |
267 | |
268 | const MachineFunction *MF = Asm->MF; |
269 | if (shouldEmitMoves || shouldEmitPersonality) { |
270 | const Function &F = MF->getFunction(); |
271 | EHPersonality Per = EHPersonality::Unknown; |
272 | if (F.hasPersonalityFn()) |
273 | Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts()); |
274 | |
275 | if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality && |
276 | !CurrentFuncletEntry->isCleanupFuncletEntry()) { |
277 | |
278 | Asm->OutStreamer->EmitWinEHHandlerData(); |
279 | |
280 | |
281 | |
282 | StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); |
283 | MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol( |
284 | Twine("$cppxdata$", FuncLinkageName)); |
285 | Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4); |
286 | } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() && |
287 | !CurrentFuncletEntry->isEHFuncletEntry()) { |
288 | |
289 | Asm->OutStreamer->EmitWinEHHandlerData(); |
290 | |
291 | |
292 | |
293 | emitCSpecificHandlerTable(MF); |
294 | } else if (shouldEmitPersonality || shouldEmitLSDA) { |
295 | |
296 | Asm->OutStreamer->EmitWinEHHandlerData(); |
297 | |
298 | |
299 | |
300 | } else { |
301 | |
302 | |
303 | |
304 | } |
305 | |
306 | |
307 | |
308 | |
309 | Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection); |
310 | Asm->OutStreamer->EmitWinCFIEndProc(); |
311 | } |
312 | |
313 | |
314 | CurrentFuncletEntry = nullptr; |
315 | } |
316 | |
317 | const MCExpr *WinException::create32bitRef(const MCSymbol *Value) { |
318 | if (!Value) |
319 | return MCConstantExpr::create(0, Asm->OutContext); |
320 | return MCSymbolRefExpr::create(Value, useImageRel32 |
321 | ? MCSymbolRefExpr::VK_COFF_IMGREL32 |
322 | : MCSymbolRefExpr::VK_None, |
323 | Asm->OutContext); |
324 | } |
325 | |
326 | const MCExpr *WinException::create32bitRef(const GlobalValue *GV) { |
327 | if (!GV) |
328 | return MCConstantExpr::create(0, Asm->OutContext); |
329 | return create32bitRef(Asm->getSymbol(GV)); |
330 | } |
331 | |
332 | const MCExpr *WinException::getLabel(const MCSymbol *Label) { |
333 | if (isAArch64) |
334 | return MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_COFF_IMGREL32, |
335 | Asm->OutContext); |
336 | return MCBinaryExpr::createAdd(create32bitRef(Label), |
337 | MCConstantExpr::create(1, Asm->OutContext), |
338 | Asm->OutContext); |
339 | } |
340 | |
341 | const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf, |
342 | const MCSymbol *OffsetFrom) { |
343 | return MCBinaryExpr::createSub( |
344 | MCSymbolRefExpr::create(OffsetOf, Asm->OutContext), |
345 | MCSymbolRefExpr::create(OffsetFrom, Asm->OutContext), Asm->OutContext); |
346 | } |
347 | |
348 | const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf, |
349 | const MCSymbol *OffsetFrom) { |
350 | return MCBinaryExpr::createAdd(getOffset(OffsetOf, OffsetFrom), |
351 | MCConstantExpr::create(1, Asm->OutContext), |
352 | Asm->OutContext); |
353 | } |
354 | |
355 | int WinException::getFrameIndexOffset(int FrameIndex, |
356 | const WinEHFuncInfo &FuncInfo) { |
357 | const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering(); |
358 | Register UnusedReg; |
359 | if (Asm->MAI->usesWindowsCFI()) { |
360 | StackOffset Offset = |
361 | TFI.getFrameIndexReferencePreferSP(*Asm->MF, FrameIndex, UnusedReg, |
362 | true); |
363 | assert(UnusedReg == |
364 | Asm->MF->getSubtarget() |
365 | .getTargetLowering() |
366 | ->getStackPointerRegisterToSaveRestore()); |
367 | return Offset.getFixed(); |
368 | } |
369 | |
370 | |
371 | |
372 | assert(FuncInfo.EHRegNodeEndOffset != INT_MAX); |
373 | StackOffset Offset = TFI.getFrameIndexReference(*Asm->MF, FrameIndex, UnusedReg); |
374 | Offset += StackOffset::getFixed(FuncInfo.EHRegNodeEndOffset); |
375 | assert(!Offset.getScalable() && |
376 | "Frame offsets with a scalable component are not supported"); |
377 | return Offset.getFixed(); |
378 | } |
379 | |
380 | namespace { |
381 | |
382 | |
383 | const int NullState = -1; |
384 | |
385 | struct InvokeStateChange { |
386 | |
387 | |
388 | const MCSymbol *PreviousEndLabel; |
389 | |
390 | |
391 | |
392 | const MCSymbol *NewStartLabel; |
393 | |
394 | |
395 | |
396 | int NewState; |
397 | }; |
398 | |
399 | |
400 | |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | |
407 | class InvokeStateChangeIterator { |
408 | InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo, |
409 | MachineFunction::const_iterator MFI, |
410 | MachineFunction::const_iterator MFE, |
411 | MachineBasicBlock::const_iterator MBBI, |
412 | int BaseState) |
413 | : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) { |
414 | LastStateChange.PreviousEndLabel = nullptr; |
415 | LastStateChange.NewStartLabel = nullptr; |
416 | LastStateChange.NewState = BaseState; |
417 | scan(); |
418 | } |
419 | |
420 | public: |
421 | static iterator_range<InvokeStateChangeIterator> |
422 | range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin, |
423 | MachineFunction::const_iterator End, int BaseState = NullState) { |
424 | |
425 | |
426 | assert(Begin != End); |
427 | auto BlockBegin = Begin->begin(); |
428 | auto BlockEnd = std::prev(End)->end(); |
429 | return make_range( |
430 | InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState), |
431 | InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState)); |
432 | } |
433 | |
434 | |
435 | bool operator==(const InvokeStateChangeIterator &O) const { |
436 | assert(BaseState == O.BaseState); |
437 | |
438 | if (MFI != O.MFI) |
439 | return false; |
440 | |
441 | if (MBBI != O.MBBI) |
442 | return false; |
443 | |
444 | |
445 | |
446 | |
447 | return CurrentEndLabel == O.CurrentEndLabel; |
448 | } |
449 | |
450 | bool operator!=(const InvokeStateChangeIterator &O) const { |
451 | return !operator==(O); |
452 | } |
453 | InvokeStateChange &operator*() { return LastStateChange; } |
454 | InvokeStateChange *operator->() { return &LastStateChange; } |
455 | InvokeStateChangeIterator &operator++() { return scan(); } |
456 | |
457 | private: |
458 | InvokeStateChangeIterator &scan(); |
459 | |
460 | const WinEHFuncInfo &EHInfo; |
461 | const MCSymbol *CurrentEndLabel = nullptr; |
462 | MachineFunction::const_iterator MFI; |
463 | MachineFunction::const_iterator MFE; |
464 | MachineBasicBlock::const_iterator MBBI; |
465 | InvokeStateChange LastStateChange; |
466 | bool VisitingInvoke = false; |
467 | int BaseState; |
468 | }; |
469 | |
470 | } |
471 | |
472 | InvokeStateChangeIterator &InvokeStateChangeIterator::scan() { |
473 | bool IsNewBlock = false; |
474 | for (; MFI != MFE; ++MFI, IsNewBlock = true) { |
475 | if (IsNewBlock) |
476 | MBBI = MFI->begin(); |
477 | for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) { |
478 | const MachineInstr &MI = *MBBI; |
479 | if (!VisitingInvoke && LastStateChange.NewState != BaseState && |
480 | MI.isCall() && !EHStreamer::callToNoUnwindFunction(&MI)) { |
481 | |
482 | |
483 | |
484 | LastStateChange.PreviousEndLabel = CurrentEndLabel; |
485 | LastStateChange.NewStartLabel = nullptr; |
486 | LastStateChange.NewState = BaseState; |
487 | CurrentEndLabel = nullptr; |
488 | |
489 | ++MBBI; |
490 | return *this; |
491 | } |
492 | |
493 | |
494 | if (!MI.isEHLabel()) |
495 | continue; |
496 | MCSymbol *Label = MI.getOperand(0).getMCSymbol(); |
497 | if (Label == CurrentEndLabel) { |
498 | VisitingInvoke = false; |
499 | continue; |
500 | } |
501 | auto InvokeMapIter = EHInfo.LabelToStateMap.find(Label); |
502 | |
503 | if (InvokeMapIter == EHInfo.LabelToStateMap.end()) |
504 | continue; |
505 | auto &StateAndEnd = InvokeMapIter->second; |
506 | int NewState = StateAndEnd.first; |
507 | |
508 | |
509 | VisitingInvoke = true; |
510 | if (NewState == LastStateChange.NewState) { |
511 | |
512 | |
513 | CurrentEndLabel = StateAndEnd.second; |
514 | continue; |
515 | } |
516 | |
517 | LastStateChange.PreviousEndLabel = CurrentEndLabel; |
518 | LastStateChange.NewStartLabel = Label; |
519 | LastStateChange.NewState = NewState; |
520 | |
521 | CurrentEndLabel = StateAndEnd.second; |
522 | |
523 | ++MBBI; |
524 | return *this; |
525 | } |
526 | } |
527 | |
528 | if (LastStateChange.NewState != BaseState) { |
529 | |
530 | LastStateChange.PreviousEndLabel = CurrentEndLabel; |
531 | LastStateChange.NewStartLabel = nullptr; |
532 | LastStateChange.NewState = BaseState; |
533 | |
534 | assert(CurrentEndLabel != nullptr); |
535 | return *this; |
536 | } |
537 | |
538 | CurrentEndLabel = nullptr; |
539 | return *this; |
540 | } |
541 | |
542 | |
543 | |
544 | |
545 | |
546 | |
547 | |
548 | |
549 | |
550 | |
551 | |
552 | |
553 | |
554 | |
555 | |
556 | |
557 | |
558 | |
559 | |
560 | |
561 | |
562 | |
563 | |
564 | |
565 | |
566 | |
567 | |
568 | |
569 | |
570 | void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { |
571 | auto &OS = *Asm->OutStreamer; |
572 | MCContext &Ctx = Asm->OutContext; |
573 | const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); |
574 | |
575 | bool VerboseAsm = OS.isVerboseAsm(); |
576 | auto AddComment = [&](const Twine &Comment) { |
577 | if (VerboseAsm) |
578 | OS.AddComment(Comment); |
579 | }; |
580 | |
581 | if (!isAArch64) { |
582 | |
583 | |
584 | StringRef FLinkageName = |
585 | GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); |
586 | MCSymbol *ParentFrameOffset = |
587 | Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); |
588 | const MCExpr *MCOffset = |
589 | MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx); |
590 | Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset); |
591 | } |
592 | |
593 | |
594 | |
595 | MCSymbol *TableBegin = |
596 | Ctx.createTempSymbol("lsda_begin", true); |
597 | MCSymbol *TableEnd = |
598 | Ctx.createTempSymbol("lsda_end", true); |
599 | const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin); |
600 | const MCExpr *EntrySize = MCConstantExpr::create(16, Ctx); |
601 | const MCExpr *EntryCount = MCBinaryExpr::createDiv(LabelDiff, EntrySize, Ctx); |
602 | AddComment("Number of call sites"); |
603 | OS.emitValue(EntryCount, 4); |
604 | |
605 | OS.emitLabel(TableBegin); |
606 | |
607 | |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | |
614 | const MCSymbol *LastStartLabel = nullptr; |
615 | int LastEHState = -1; |
616 | |
617 | |
618 | MachineFunction::const_iterator End = MF->end(); |
619 | MachineFunction::const_iterator Stop = std::next(MF->begin()); |
620 | while (Stop != End && !Stop->isEHFuncletEntry()) |
621 | ++Stop; |
622 | for (const auto &StateChange : |
623 | InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) { |
624 | |
625 | |
626 | if (LastEHState != -1) |
627 | emitSEHActionsForRange(FuncInfo, LastStartLabel, |
628 | StateChange.PreviousEndLabel, LastEHState); |
629 | LastStartLabel = StateChange.NewStartLabel; |
630 | LastEHState = StateChange.NewState; |
631 | } |
632 | |
633 | OS.emitLabel(TableEnd); |
634 | } |
635 | |
636 | void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo, |
637 | const MCSymbol *BeginLabel, |
638 | const MCSymbol *EndLabel, int State) { |
639 | auto &OS = *Asm->OutStreamer; |
640 | MCContext &Ctx = Asm->OutContext; |
641 | bool VerboseAsm = OS.isVerboseAsm(); |
642 | auto AddComment = [&](const Twine &Comment) { |
643 | if (VerboseAsm) |
644 | OS.AddComment(Comment); |
645 | }; |
646 | |
647 | assert(BeginLabel && EndLabel); |
648 | while (State != -1) { |
649 | const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State]; |
650 | const MCExpr *FilterOrFinally; |
651 | const MCExpr *ExceptOrNull; |
652 | auto *Handler = UME.Handler.get<MachineBasicBlock *>(); |
653 | if (UME.IsFinally) { |
654 | FilterOrFinally = create32bitRef(getMCSymbolForMBB(Asm, Handler)); |
655 | ExceptOrNull = MCConstantExpr::create(0, Ctx); |
656 | } else { |
657 | |
658 | |
659 | FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter) |
660 | : MCConstantExpr::create(1, Ctx); |
661 | ExceptOrNull = create32bitRef(Handler->getSymbol()); |
662 | } |
663 | |
664 | AddComment("LabelStart"); |
665 | OS.emitValue(getLabel(BeginLabel), 4); |
666 | AddComment("LabelEnd"); |
667 | OS.emitValue(getLabel(EndLabel), 4); |
668 | AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction" |
669 | : "CatchAll"); |
670 | OS.emitValue(FilterOrFinally, 4); |
671 | AddComment(UME.IsFinally ? "Null" : "ExceptionHandler"); |
672 | OS.emitValue(ExceptOrNull, 4); |
673 | |
674 | assert(UME.ToState < State && "states should decrease"); |
675 | State = UME.ToState; |
676 | } |
677 | } |
678 | |
679 | void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { |
680 | const Function &F = MF->getFunction(); |
681 | auto &OS = *Asm->OutStreamer; |
682 | const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); |
683 | |
684 | StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); |
685 | |
686 | SmallVector<std::pair<const MCExpr *, int>, 4> IPToStateTable; |
687 | MCSymbol *FuncInfoXData = nullptr; |
688 | if (shouldEmitPersonality) { |
689 | |
690 | |
691 | FuncInfoXData = |
692 | Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName)); |
693 | computeIP2StateTable(MF, FuncInfo, IPToStateTable); |
694 | } else { |
695 | FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName); |
696 | } |
697 | |
698 | int UnwindHelpOffset = 0; |
699 | if (Asm->MAI->usesWindowsCFI()) |
700 | UnwindHelpOffset = |
701 | getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx, FuncInfo); |
702 | |
703 | MCSymbol *UnwindMapXData = nullptr; |
704 | MCSymbol *TryBlockMapXData = nullptr; |
705 | MCSymbol *IPToStateXData = nullptr; |
706 | if (!FuncInfo.CxxUnwindMap.empty()) |
707 | UnwindMapXData = Asm->OutContext.getOrCreateSymbol( |
708 | Twine("$stateUnwindMap$", FuncLinkageName)); |
709 | if (!FuncInfo.TryBlockMap.empty()) |
710 | TryBlockMapXData = |
711 | Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName)); |
712 | if (!IPToStateTable.empty()) |
713 | IPToStateXData = |
714 | Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName)); |
715 | |
716 | bool VerboseAsm = OS.isVerboseAsm(); |
717 | auto AddComment = [&](const Twine &Comment) { |
718 | if (VerboseAsm) |
719 | OS.AddComment(Comment); |
720 | }; |
721 | |
722 | |
723 | |
724 | |
725 | |
726 | |
727 | |
728 | |
729 | |
730 | |
731 | |
732 | |
733 | |
734 | |
735 | |
736 | |
737 | OS.emitValueToAlignment(4); |
738 | OS.emitLabel(FuncInfoXData); |
739 | |
740 | AddComment("MagicNumber"); |
741 | OS.emitInt32(0x19930522); |
742 | |
743 | AddComment("MaxState"); |
744 | OS.emitInt32(FuncInfo.CxxUnwindMap.size()); |
745 | |
746 | AddComment("UnwindMap"); |
747 | OS.emitValue(create32bitRef(UnwindMapXData), 4); |
748 | |
749 | AddComment("NumTryBlocks"); |
750 | OS.emitInt32(FuncInfo.TryBlockMap.size()); |
751 | |
752 | AddComment("TryBlockMap"); |
753 | OS.emitValue(create32bitRef(TryBlockMapXData), 4); |
754 | |
755 | AddComment("IPMapEntries"); |
756 | OS.emitInt32(IPToStateTable.size()); |
757 | |
758 | AddComment("IPToStateXData"); |
759 | OS.emitValue(create32bitRef(IPToStateXData), 4); |
760 | |
761 | if (Asm->MAI->usesWindowsCFI()) { |
762 | AddComment("UnwindHelp"); |
763 | OS.emitInt32(UnwindHelpOffset); |
764 | } |
765 | |
766 | AddComment("ESTypeList"); |
767 | OS.emitInt32(0); |
768 | |
769 | AddComment("EHFlags"); |
770 | OS.emitInt32(1); |
771 | |
772 | |
773 | |
774 | |
775 | |
776 | if (UnwindMapXData) { |
777 | OS.emitLabel(UnwindMapXData); |
778 | for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) { |
779 | MCSymbol *CleanupSym = |
780 | getMCSymbolForMBB(Asm, UME.Cleanup.dyn_cast<MachineBasicBlock *>()); |
781 | AddComment("ToState"); |
782 | OS.emitInt32(UME.ToState); |
783 | |
784 | AddComment("Action"); |
785 | OS.emitValue(create32bitRef(CleanupSym), 4); |
786 | } |
787 | } |
788 | |
789 | |
790 | |
791 | |
792 | |
793 | |
794 | |
795 | |
796 | if (TryBlockMapXData) { |
797 | OS.emitLabel(TryBlockMapXData); |
798 | SmallVector<MCSymbol *, 1> HandlerMaps; |
799 | for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { |
800 | const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; |
801 | |
802 | MCSymbol *HandlerMapXData = nullptr; |
803 | if (!TBME.HandlerArray.empty()) |
804 | HandlerMapXData = |
805 | Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$") |
806 | .concat(Twine(I)) |
807 | .concat("$") |
808 | .concat(FuncLinkageName)); |
809 | HandlerMaps.push_back(HandlerMapXData); |
810 | |
811 | |
812 | assert(0 <= TBME.TryLow && "bad trymap interval"); |
813 | assert(TBME.TryLow <= TBME.TryHigh && "bad trymap interval"); |
814 | assert(TBME.TryHigh < TBME.CatchHigh && "bad trymap interval"); |
815 | assert(TBME.CatchHigh < int(FuncInfo.CxxUnwindMap.size()) && |
816 | "bad trymap interval"); |
817 | |
818 | AddComment("TryLow"); |
819 | OS.emitInt32(TBME.TryLow); |
820 | |
821 | AddComment("TryHigh"); |
822 | OS.emitInt32(TBME.TryHigh); |
823 | |
824 | AddComment("CatchHigh"); |
825 | OS.emitInt32(TBME.CatchHigh); |
826 | |
827 | AddComment("NumCatches"); |
828 | OS.emitInt32(TBME.HandlerArray.size()); |
829 | |
830 | AddComment("HandlerArray"); |
831 | OS.emitValue(create32bitRef(HandlerMapXData), 4); |
832 | } |
833 | |
834 | |
835 | unsigned ParentFrameOffset = 0; |
836 | if (shouldEmitPersonality) { |
837 | const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); |
838 | ParentFrameOffset = TFI->getWinEHParentFrameOffset(*MF); |
839 | } |
840 | |
841 | for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { |
842 | const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; |
843 | MCSymbol *HandlerMapXData = HandlerMaps[I]; |
844 | if (!HandlerMapXData) |
845 | continue; |
846 | |
847 | |
848 | |
849 | |
850 | |
851 | |
852 | |
853 | OS.emitLabel(HandlerMapXData); |
854 | for (const WinEHHandlerType &HT : TBME.HandlerArray) { |
855 | |
856 | |
857 | |
858 | const MCExpr *FrameAllocOffsetRef = nullptr; |
859 | if (HT.CatchObj.FrameIndex != INT_MAX) { |
860 | int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex, FuncInfo); |
861 | assert(Offset != 0 && "Illegal offset for catch object!"); |
862 | FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext); |
863 | } else { |
864 | FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext); |
865 | } |
866 | |
867 | MCSymbol *HandlerSym = |
868 | getMCSymbolForMBB(Asm, HT.Handler.dyn_cast<MachineBasicBlock *>()); |
869 | |
870 | AddComment("Adjectives"); |
871 | OS.emitInt32(HT.Adjectives); |
872 | |
873 | AddComment("Type"); |
874 | OS.emitValue(create32bitRef(HT.TypeDescriptor), 4); |
875 | |
876 | AddComment("CatchObjOffset"); |
877 | OS.emitValue(FrameAllocOffsetRef, 4); |
878 | |
879 | AddComment("Handler"); |
880 | OS.emitValue(create32bitRef(HandlerSym), 4); |
881 | |
882 | if (shouldEmitPersonality) { |
883 | AddComment("ParentFrameOffset"); |
884 | OS.emitInt32(ParentFrameOffset); |
885 | } |
886 | } |
887 | } |
888 | } |
889 | |
890 | |
891 | |
892 | |
893 | |
894 | if (IPToStateXData) { |
895 | OS.emitLabel(IPToStateXData); |
896 | for (auto &IPStatePair : IPToStateTable) { |
897 | AddComment("IP"); |
898 | OS.emitValue(IPStatePair.first, 4); |
899 | AddComment("ToState"); |
900 | OS.emitInt32(IPStatePair.second); |
901 | } |
902 | } |
903 | } |
904 | |
905 | void WinException::computeIP2StateTable( |
906 | const MachineFunction *MF, const WinEHFuncInfo &FuncInfo, |
907 | SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) { |
908 | |
909 | for (MachineFunction::const_iterator FuncletStart = MF->begin(), |
910 | FuncletEnd = MF->begin(), |
911 | End = MF->end(); |
912 | FuncletStart != End; FuncletStart = FuncletEnd) { |
913 | |
914 | while (++FuncletEnd != End) { |
915 | if (FuncletEnd->isEHFuncletEntry()) { |
916 | break; |
917 | } |
918 | } |
919 | |
920 | |
921 | |
922 | |
923 | if (FuncletStart->isCleanupFuncletEntry()) |
924 | continue; |
925 | |
926 | MCSymbol *StartLabel; |
927 | int BaseState; |
928 | if (FuncletStart == MF->begin()) { |
929 | BaseState = NullState; |
930 | StartLabel = Asm->getFunctionBegin(); |
931 | } else { |
932 | auto *FuncletPad = |
933 | cast<FuncletPadInst>(FuncletStart->getBasicBlock()->getFirstNonPHI()); |
934 | assert(FuncInfo.FuncletBaseStateMap.count(FuncletPad) != 0); |
935 | BaseState = FuncInfo.FuncletBaseStateMap.find(FuncletPad)->second; |
936 | StartLabel = getMCSymbolForMBB(Asm, &*FuncletStart); |
937 | } |
938 | assert(StartLabel && "need local function start label"); |
939 | IPToStateTable.push_back( |
940 | std::make_pair(create32bitRef(StartLabel), BaseState)); |
941 | |
942 | for (const auto &StateChange : InvokeStateChangeIterator::range( |
943 | FuncInfo, FuncletStart, FuncletEnd, BaseState)) { |
944 | |
945 | |
946 | |
947 | |
948 | const MCSymbol *ChangeLabel = StateChange.NewStartLabel; |
949 | if (!ChangeLabel) |
950 | ChangeLabel = StateChange.PreviousEndLabel; |
951 | |
952 | IPToStateTable.push_back( |
953 | std::make_pair(getLabel(ChangeLabel), StateChange.NewState)); |
954 | |
955 | } |
956 | } |
957 | } |
958 | |
959 | void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, |
960 | StringRef FLinkageName) { |
961 | |
962 | |
963 | |
964 | |
965 | |
966 | |
967 | |
968 | |
969 | |
970 | int64_t Offset = 0; |
971 | int FI = FuncInfo.EHRegNodeFrameIndex; |
972 | if (FI != INT_MAX) { |
973 | const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); |
974 | Offset = TFI->getNonLocalFrameIndexReference(*Asm->MF, FI).getFixed(); |
975 | } |
976 | |
977 | MCContext &Ctx = Asm->OutContext; |
978 | MCSymbol *ParentFrameOffset = |
979 | Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); |
980 | Asm->OutStreamer->emitAssignment(ParentFrameOffset, |
981 | MCConstantExpr::create(Offset, Ctx)); |
982 | } |
983 | |
984 | |
985 | |
986 | |
987 | void WinException::emitExceptHandlerTable(const MachineFunction *MF) { |
988 | MCStreamer &OS = *Asm->OutStreamer; |
989 | const Function &F = MF->getFunction(); |
990 | StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); |
991 | |
992 | bool VerboseAsm = OS.isVerboseAsm(); |
993 | auto AddComment = [&](const Twine &Comment) { |
994 | if (VerboseAsm) |
995 | OS.AddComment(Comment); |
996 | }; |
997 | |
998 | const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); |
999 | emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); |
1000 | |
1001 | |
1002 | MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName); |
1003 | OS.emitValueToAlignment(4); |
1004 | OS.emitLabel(LSDALabel); |
1005 | |
1006 | const auto *Per = cast<Function>(F.getPersonalityFn()->stripPointerCasts()); |
1007 | StringRef PerName = Per->getName(); |
1008 | int BaseState = -1; |
1009 | if (PerName == "_except_handler4") { |
1010 | |
1011 | |
1012 | |
1013 | |
1014 | |
1015 | |
1016 | |
1017 | |
1018 | |
1019 | |
1020 | |
1021 | |
1022 | |
1023 | |
1024 | |
1025 | |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | |
1031 | |
1032 | int GSCookieOffset = -2; |
1033 | const MachineFrameInfo &MFI = MF->getFrameInfo(); |
1034 | if (MFI.hasStackProtectorIndex()) { |
1035 | Register UnusedReg; |
1036 | const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); |
1037 | int SSPIdx = MFI.getStackProtectorIndex(); |
1038 | GSCookieOffset = |
1039 | TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg).getFixed(); |
1040 | } |
1041 | |
1042 | |
1043 | |
1044 | int EHCookieOffset = 9999; |
1045 | if (FuncInfo.EHGuardFrameIndex != INT_MAX) { |
1046 | Register UnusedReg; |
1047 | const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); |
1048 | int EHGuardIdx = FuncInfo.EHGuardFrameIndex; |
1049 | EHCookieOffset = |
1050 | TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg).getFixed(); |
1051 | } |
1052 | |
1053 | AddComment("GSCookieOffset"); |
1054 | OS.emitInt32(GSCookieOffset); |
1055 | AddComment("GSCookieXOROffset"); |
1056 | OS.emitInt32(0); |
1057 | AddComment("EHCookieOffset"); |
1058 | OS.emitInt32(EHCookieOffset); |
1059 | AddComment("EHCookieXOROffset"); |
1060 | OS.emitInt32(0); |
1061 | BaseState = -2; |
1062 | } |
1063 | |
1064 | assert(!FuncInfo.SEHUnwindMap.empty()); |
1065 | for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) { |
1066 | auto *Handler = UME.Handler.get<MachineBasicBlock *>(); |
1067 | const MCSymbol *ExceptOrFinally = |
1068 | UME.IsFinally ? getMCSymbolForMBB(Asm, Handler) : Handler->getSymbol(); |
1069 | |
1070 | |
1071 | int ToState = UME.ToState == -1 ? BaseState : UME.ToState; |
1072 | AddComment("ToState"); |
1073 | OS.emitInt32(ToState); |
1074 | AddComment(UME.IsFinally ? "Null" : "FilterFunction"); |
1075 | OS.emitValue(create32bitRef(UME.Filter), 4); |
1076 | AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler"); |
1077 | OS.emitValue(create32bitRef(ExceptOrFinally), 4); |
1078 | } |
1079 | } |
1080 | |
1081 | static int getTryRank(const WinEHFuncInfo &FuncInfo, int State) { |
1082 | int Rank = 0; |
1083 | while (State != -1) { |
1084 | ++Rank; |
1085 | State = FuncInfo.ClrEHUnwindMap[State].TryParentState; |
1086 | } |
1087 | return Rank; |
1088 | } |
1089 | |
1090 | static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) { |
1091 | int LeftRank = getTryRank(FuncInfo, Left); |
1092 | int RightRank = getTryRank(FuncInfo, Right); |
1093 | |
1094 | while (LeftRank < RightRank) { |
1095 | Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState; |
1096 | --RightRank; |
1097 | } |
1098 | |
1099 | while (RightRank < LeftRank) { |
1100 | Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState; |
1101 | --LeftRank; |
1102 | } |
1103 | |
1104 | while (Left != Right) { |
1105 | Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState; |
1106 | Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState; |
1107 | } |
1108 | |
1109 | return Left; |
1110 | } |
1111 | |
1112 | void WinException::emitCLRExceptionTable(const MachineFunction *MF) { |
1113 | |
1114 | |
1115 | |
1116 | MCStreamer &OS = *Asm->OutStreamer; |
1117 | const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); |
1118 | MCSymbol *FuncBeginSym = Asm->getFunctionBegin(); |
1119 | MCSymbol *FuncEndSym = Asm->getFunctionEnd(); |
1120 | |
1121 | |
1122 | struct ClrClause { |
1123 | const MCSymbol *StartLabel; |
1124 | const MCSymbol *EndLabel; |
1125 | int State; |
1126 | int EnclosingState; |
1127 | }; |
1128 | SmallVector<ClrClause, 8> Clauses; |
1129 | |
1130 | |
1131 | |
1132 | int NumStates = FuncInfo.ClrEHUnwindMap.size(); |
1133 | assert(NumStates > 0 && "Don't need exception table!"); |
1134 | DenseMap<const MachineBasicBlock *, int> HandlerStates; |
1135 | for (int State = 0; State < NumStates; ++State) { |
| 10 | | Assuming 'State' is >= 'NumStates' | |
|
| 11 | | Loop condition is false. Execution continues on line 1146 | |
|
1136 | MachineBasicBlock *HandlerBlock = |
1137 | FuncInfo.ClrEHUnwindMap[State].Handler.get<MachineBasicBlock *>(); |
1138 | HandlerStates[HandlerBlock] = State; |
1139 | |
1140 | |
1141 | |
1142 | assert(FuncInfo.ClrEHUnwindMap[State].HandlerParentState < State && |
1143 | "ill-formed state numbering"); |
1144 | } |
1145 | |
1146 | HandlerStates[&MF->front()] = NullState; |
1147 | |
1148 | |
1149 | |
1150 | OS.emitInt32(0xffffffff); |
1151 | |
1152 | OS.emitInt32(NumStates); |
1153 | |
1154 | |
1155 | |
1156 | |
1157 | |
1158 | |
1159 | |
1160 | |
1161 | |
1162 | |
1163 | |
1164 | |
1165 | |
1166 | |
1167 | |
1168 | |
1169 | SmallVector<std::pair<const MCSymbol *, int>, 4> HandlerStack; |
1170 | |
1171 | std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]); |
| |
1172 | SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates); |
1173 | |
1174 | |
1175 | for (MachineFunction::const_iterator FuncletStart = MF->begin(), |
| 13 | | Loop condition is false. Execution continues on line 1243 | |
|
1176 | FuncletEnd = MF->begin(), |
1177 | End = MF->end(); |
1178 | FuncletStart != End; FuncletStart = FuncletEnd) { |
1179 | int FuncletState = HandlerStates[&*FuncletStart]; |
1180 | |
1181 | MCSymbol *EndSymbol = FuncEndSym; |
1182 | while (++FuncletEnd != End) { |
1183 | if (FuncletEnd->isEHFuncletEntry()) { |
1184 | EndSymbol = getMCSymbolForMBB(Asm, &*FuncletEnd); |
1185 | break; |
1186 | } |
1187 | } |
1188 | |
1189 | |
1190 | OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4); |
1191 | if (FuncletState != NullState) { |
1192 | |
1193 | EndSymbolMap[FuncletState] = EndSymbol; |
1194 | } |
1195 | |
1196 | |
1197 | |
1198 | const MCSymbol *CurrentStartLabel = nullptr; |
1199 | int CurrentState = NullState; |
1200 | assert(HandlerStack.empty()); |
1201 | for (const auto &StateChange : |
1202 | InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) { |
1203 | |
1204 | int StillPendingState = |
1205 | getTryAncestor(FuncInfo, CurrentState, StateChange.NewState); |
1206 | while (CurrentState != StillPendingState) { |
1207 | assert(CurrentState != NullState && |
1208 | "Failed to find still-pending state!"); |
1209 | |
1210 | Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel, |
1211 | CurrentState, FuncletState}); |
1212 | |
1213 | CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState; |
1214 | |
1215 | |
1216 | if (HandlerStack.back().second == CurrentState) |
1217 | CurrentStartLabel = HandlerStack.pop_back_val().first; |
1218 | } |
1219 | |
1220 | if (StateChange.NewState != CurrentState) { |
1221 | |
1222 | |
1223 | |
1224 | for (int EnteredState = StateChange.NewState; |
1225 | EnteredState != CurrentState; |
1226 | EnteredState = |
1227 | FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) { |
1228 | int &MinEnclosingState = MinClauseMap[EnteredState]; |
1229 | if (FuncletState < MinEnclosingState) |
1230 | MinEnclosingState = FuncletState; |
1231 | } |
1232 | |
1233 | |
1234 | HandlerStack.emplace_back(CurrentStartLabel, CurrentState); |
1235 | CurrentStartLabel = StateChange.NewStartLabel; |
1236 | CurrentState = StateChange.NewState; |
1237 | } |
1238 | } |
1239 | assert(HandlerStack.empty()); |
1240 | } |
1241 | |
1242 | |
1243 | OS.emitInt32(Clauses.size()); |
1244 | for (ClrClause &Clause : Clauses) { |
| 14 | | Assuming '__begin1' is not equal to '__end1' | |
|
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 | |
1290 | |
1291 | |
1292 | |
1293 | const MCExpr *ClauseBegin = |
1294 | getOffsetPlusOne(Clause.StartLabel, FuncBeginSym); |
1295 | const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym); |
1296 | |
1297 | const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State]; |
1298 | MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>(); |
1299 | MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock); |
1300 | const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym); |
1301 | MCSymbol *EndSym = EndSymbolMap[Clause.State]; |
| 15 | | Use of zero-allocated memory |
|
1302 | const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym); |
1303 | |
1304 | uint32_t Flags = 0; |
1305 | switch (Entry.HandlerType) { |
1306 | case ClrHandlerType::Catch: |
1307 | |
1308 | break; |
1309 | case ClrHandlerType::Filter: |
1310 | Flags |= 1; |
1311 | break; |
1312 | case ClrHandlerType::Finally: |
1313 | Flags |= 2; |
1314 | break; |
1315 | case ClrHandlerType::Fault: |
1316 | Flags |= 4; |
1317 | break; |
1318 | } |
1319 | if (Clause.EnclosingState != MinClauseMap[Clause.State]) { |
1320 | |
1321 | |
1322 | assert(Clause.EnclosingState > MinClauseMap[Clause.State]); |
1323 | Flags |= 8; |
1324 | } |
1325 | OS.emitInt32(Flags); |
1326 | |
1327 | |
1328 | OS.emitValue(ClauseBegin, 4); |
1329 | OS.emitValue(ClauseEnd, 4); |
1330 | |
1331 | |
1332 | OS.emitValue(HandlerBegin, 4); |
1333 | OS.emitValue(HandlerEnd, 4); |
1334 | |
1335 | |
1336 | assert(Entry.HandlerType != ClrHandlerType::Filter && "NYI: filters"); |
1337 | OS.emitInt32(Entry.TypeToken); |
1338 | } |
1339 | } |