56 if (
F.hasFnAttribute(
"safeseh"))
61 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA =
false;
77 bool forceEmitPersonality =
81 shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
85 shouldEmitLSDA = shouldEmitPersonality &&
91 bool HasOutlinedChildren =
93 shouldEmitLSDA = HasOutlinedChildren;
94 shouldEmitPersonality =
false;
105 MCSymbol *HandlerTypeParentFrameOffset =
111 HandlerTypeParentFrameOffset,
116 if (shouldEmitMoves || shouldEmitPersonality)
119 if (shouldEmitPersonality) {
129 if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
143 if (shouldEmitPersonality || shouldEmitLSDA) {
146 if (shouldEmitMoves || shouldEmitPersonality) {
161 emitCSpecificHandlerTable();
163 emitExceptHandlerTable(MF);
165 emitCXXFrameHandler3Table(MF);
219 void WinException::emitCSpecificHandlerTable() {
229 LandingPads.
reserve(PadInfos.size());
230 for (
const auto &LP : PadInfos)
244 unsigned NumEntries = 0;
245 for (
const CallSiteEntry &
CSE : CallSites) {
248 NumEntries +=
CSE.LPad->SEHHandlers.size();
258 for (
const CallSiteEntry &
CSE : CallSites) {
269 create32bitRef(
CSE.BeginLabel ?
CSE.BeginLabel : EHFuncBeginSym);
278 End = create32bitRef(EHFuncEndSym);
306 void WinException::emitCXXFrameHandler3Table(
const MachineFunction *MF) {
316 if (shouldEmitPersonality) {
318 Twine(
"$cppxdata$", ParentLinkageName));
319 OS.EmitValue(create32bitRef(FuncInfoXData), 4);
321 extendIP2StateTable(MF, ParentF, FuncInfo);
333 emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
337 MCSymbol *TryBlockMapXData =
nullptr;
341 Twine(
"$stateUnwindMap$", ParentLinkageName));
344 Twine(
"$tryMap$", ParentLinkageName));
347 Twine(
"$ip2state$", ParentLinkageName));
364 OS.EmitValueToAlignment(4);
365 OS.EmitLabel(FuncInfoXData);
366 OS.EmitIntValue(0x19930522, 4);
367 OS.EmitIntValue(FuncInfo.
UnwindMap.size(), 4);
368 OS.EmitValue(create32bitRef(UnwindMapXData), 4);
370 OS.EmitValue(create32bitRef(TryBlockMapXData), 4);
372 OS.EmitValue(create32bitRef(IPToStateXData), 4);
375 OS.EmitIntValue(0, 4);
376 OS.EmitIntValue(1, 4);
382 if (UnwindMapXData) {
383 OS.EmitLabel(UnwindMapXData);
385 OS.EmitIntValue(UME.
ToState, 4);
386 OS.EmitValue(create32bitRef(UME.
Cleanup), 4);
397 if (TryBlockMapXData) {
398 OS.EmitLabel(TryBlockMapXData);
400 for (
size_t I = 0, E = FuncInfo.
TryBlockMap.size();
I != E; ++
I) {
402 MCSymbol *HandlerMapXData =
nullptr;
409 .concat(ParentLinkageName));
419 OS.EmitIntValue(TBME.
TryLow, 4);
420 OS.EmitIntValue(TBME.
TryHigh, 4);
421 OS.EmitIntValue(CatchHigh, 4);
423 OS.EmitValue(create32bitRef(HandlerMapXData), 4);
426 for (
size_t I = 0, E = FuncInfo.
TryBlockMap.size();
I != E; ++
I) {
428 MCSymbol *HandlerMapXData = HandlerMaps[
I];
429 if (!HandlerMapXData)
438 OS.EmitLabel(HandlerMapXData);
443 const MCExpr *FrameAllocOffsetRef =
nullptr;
457 OS.EmitValue(FrameAllocOffsetRef, 4);
458 OS.EmitValue(create32bitRef(HT.
Handler), 4);
460 if (shouldEmitPersonality) {
466 OS.EmitValue(ParentFrameOffsetRef, 4);
476 if (IPToStateXData) {
477 OS.EmitLabel(IPToStateXData);
479 OS.EmitValue(create32bitRef(IPStatePair.first), 4);
480 OS.EmitIntValue(IPStatePair.second, 4);
494 LandingPads.
reserve(PadInfos.size());
495 for (
const auto &LP : PadInfos)
506 bool SawPotentiallyThrowing =
false;
508 int LastEHState = -2;
516 FuncInfo.
IPToStateList.push_back(std::make_pair(LastLabel, -1));
523 for (
const auto &MBB : *MF) {
524 for (
const auto &
MI : MBB) {
525 if (!
MI.isEHLabel()) {
532 MCSymbol *BeginLabel =
MI.getOperand(0).getMCSymbol();
533 if (BeginLabel == LastLabel)
534 SawPotentiallyThrowing =
false;
538 if (L == PadMap.end())
542 const PadRange &
P = L->second;
544 assert(BeginLabel == LandingPad->
BeginLabels[P.RangeIndex] &&
545 "Inconsistent landing pad map!");
548 if (SawPotentiallyThrowing && LastEHState != -1) {
549 FuncInfo.
IPToStateList.push_back(std::make_pair(LastLabel, -1));
550 SawPotentiallyThrowing =
false;
556 std::make_pair(BeginLabel, LandingPad->
WinEHState));
558 LastLabel = LandingPad->
EndLabels[P.RangeIndex];
563 void WinException::emitEHRegistrationOffsetLabel(
const WinEHFuncInfo &FuncInfo,
570 "no EH reg node localescape index");
575 const MCExpr *RegistrationOffsetSymRef =
577 Asm->
OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef);
589 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
600 if (PerName ==
"_except_handler4") {
625 LPads.
reserve((PadInfos.size()));
628 std::sort(LPads.
begin(), LPads.
end(),
644 int EnclosingLevel = BaseState;
645 assert(CurState +
int(LPInfo->SEHHandlers.size()) - 1 ==
646 LPInfo->WinEHState &&
647 "gaps in the SEH scope table");
648 for (
auto I = LPInfo->SEHHandlers.rbegin(), E = LPInfo->SEHHandlers.rend();
653 assert(F &&
"cannot catch all in 32-bit SEH without filter function");
654 const MCExpr *FilterOrNull =
656 const MCExpr *ExceptOrFinally = create32bitRef(
664 EnclosingLevel = CurState;
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
SmallVector< WinEHHandlerType, 1 > HandlerArray
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol * getSymbol(const GlobalValue *GV) const
DenseMap< MCSymbol *, PadRange > RangeMapType
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
A Module instance is used to store all the information related to an LLVM module. ...
WinEHFuncInfo & getWinEHFuncInfo(const Function *F)
const DataLayout & getDataLayout() const
Return information about data layout.
MCContext & OutContext
This is the context for the output file that we are streaming.
const Function * FilterOrFinally
MCSymbol * getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx)
Gets a symbol that will be defined to the final stack offset of a local variable after codegen...
bool callToNoUnwindFunction(const MachineInstr *MI)
Return `true' if this is a call to a function marked `nounwind'.
MCSymbol * getOrCreateParentFrameOffsetSymbol(StringRef FuncName)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
void reserve(size_type N)
StringRef getName() const
Return a constant reference to the value's name.
MachineModuleInfo * MMI
Collected machine module information.
BlockAddress - The address of a basic block.
void endModule() override
Emit all exception information that should come after the content.
Emits exception handling directives.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
SmallVector< MCSymbol *, 1 > EndLabels
SmallVector< SEHHandler, 1 > SEHHandlers
separate const offset from Split GEPs to a variadic base and a constant offset for better CSE
Base class for the full range of assembler expressions which are needed for parsing.
const Module * getModule() const
Represent a reference to a symbol from inside an expression.
int EHRegNodeEscapeIndex
localescape index of the 32-bit EH registration node.
void emitExceptionTable()
Emit landing pads and actions.
LandingPadInfo - This structure is used to retain landing pad info for the current function...
Mangler * Mang
Name-mangler for global names.
void computeCallSiteTable(SmallVectorImpl< CallSiteEntry > &CallSites, const SmallVectorImpl< const LandingPadInfo * > &LPs, const SmallVectorImpl< unsigned > &FirstActions)
Compute the call-site table.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
int UnwindHelpFrameOffset
Streaming machine code generation interface.
Constant * stripPointerCasts()
MCSymbol * CurrentFnSym
The symbol for the current function.
const MCAsmInfo * MAI
Target Asm Printer information.
SmallVector< MCSymbol *, 1 > BeginLabels
WinException(AsmPrinter *A)
TargetMachine & TM
Target machine description.
bool hasPersonalityFn() const
Get the personality function associated with this function.
This class is intended to be used as a driving class for all asm writers.
void endFunction(const MachineFunction *) override
Gather and emit post-function exception information.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
DenseMap< const Function *, int > CatchHandlerParentFrameObjOffset
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
AsmPrinter * Asm
Target of directive emission.
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
DenseMap< const Function *, int > CatchHandlerMaxState
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
unsigned getLSDAEncoding() const
MCSymbol * getOrCreateLSDASymbol(StringRef FuncName)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
unsigned getPersonalityEncoding() const
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
GlobalVariable * TypeDescriptor
const Function * getWinEHParent(const Function *F) const
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Constant * getPersonalityFn() const
const std::vector< LandingPadInfo > & getLandingPads() const
getLandingPads - Return a reference to the landing pad info for the current function.
MCSymbol * getFunctionBegin() const
void computePadMap(const SmallVectorImpl< const LandingPadInfo * > &LandingPads, RangeMapType &PadMap)
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
MCSymbol * getFunctionEnd() const
unsigned NumIPToStateFuncsVisited
static MCSection * getXDataSection(const MCSymbol *Function, MCContext &Context)
void EmitValue(const MCExpr *Value, unsigned Size, const SMLoc &Loc=SMLoc())
void TidyLandingPads(DenseMap< MCSymbol *, uintptr_t > *LPMap=nullptr)
TidyLandingPads - Remap landing pad labels and remove any deleted landing pads.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
SmallVector< std::pair< MCSymbol *, int >, 4 > IPToStateList
LLVM Value Representation.
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, MachineModuleInfo *MMI) const
const BlockAddress * RecoverBA
StringRef - Represent a constant reference to a string, i.e.
DenseMap< const Function *, int > HandlerBaseState
bool isNoOpWithoutInvoke(EHPersonality Pers)
Return true if this personality may be safely removed if there are no invoke instructions remaining i...
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
bool isMSVCEHPersonality(EHPersonality Pers)
Returns true if this is an MSVC personality function.
SmallVector< WinEHUnwindMapEntry, 4 > UnwindMap
bool usesWindowsCFI() const