13b0f4066SDimitry Andric //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===// 23b0f4066SDimitry Andric // 33b0f4066SDimitry Andric // The LLVM Compiler Infrastructure 43b0f4066SDimitry Andric // 53b0f4066SDimitry Andric // This file is distributed under the University of Illinois Open Source 63b0f4066SDimitry Andric // License. See LICENSE.TXT for details. 73b0f4066SDimitry Andric // 83b0f4066SDimitry Andric //===----------------------------------------------------------------------===// 93b0f4066SDimitry Andric // 103b0f4066SDimitry Andric // This file contains support for writing DWARF exception info into asm files. 113b0f4066SDimitry Andric // 123b0f4066SDimitry Andric //===----------------------------------------------------------------------===// 133b0f4066SDimitry Andric 143b0f4066SDimitry Andric #include "DwarfException.h" 15139f7f9bSDimitry Andric #include "llvm/ADT/Twine.h" 163b0f4066SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 173b0f4066SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 18139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h" 1991bc56edSDimitry Andric #include "llvm/IR/Mangler.h" 20139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 213b0f4066SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 223b0f4066SDimitry Andric #include "llvm/MC/MCExpr.h" 233b0f4066SDimitry Andric #include "llvm/MC/MCSection.h" 243b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h" 253b0f4066SDimitry Andric #include "llvm/MC/MCSymbol.h" 263b0f4066SDimitry Andric #include "llvm/Support/FormattedStream.h" 27139f7f9bSDimitry Andric #include "llvm/Target/TargetOptions.h" 283b0f4066SDimitry Andric using namespace llvm; 293b0f4066SDimitry Andric ARMException(AsmPrinter * A)30ff0cc061SDimitry AndricARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} 313b0f4066SDimitry Andric ~ARMException()323b0f4066SDimitry AndricARMException::~ARMException() {} 333b0f4066SDimitry Andric getTargetStreamer()34f785676fSDimitry AndricARMTargetStreamer &ARMException::getTargetStreamer() { 35ff0cc061SDimitry Andric MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer(); 36f785676fSDimitry Andric return static_cast<ARMTargetStreamer &>(TS); 37f785676fSDimitry Andric } 38f785676fSDimitry Andric beginFunction(const MachineFunction * MF)3991bc56edSDimitry Andricvoid ARMException::beginFunction(const MachineFunction *MF) { 4091bc56edSDimitry Andric if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 41f785676fSDimitry Andric getTargetStreamer().emitFnStart(); 4291bc56edSDimitry Andric // See if we need call frame info. 4391bc56edSDimitry Andric AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); 4491bc56edSDimitry Andric assert(MoveType != AsmPrinter::CFI_M_EH && 4591bc56edSDimitry Andric "non-EH CFI not yet supported in prologue with EHABI lowering"); 46d88c1a5aSDimitry Andric 4791bc56edSDimitry Andric if (MoveType == AsmPrinter::CFI_M_Debug) { 48d88c1a5aSDimitry Andric if (!hasEmittedCFISections) { 4995ec533aSDimitry Andric if (Asm->needsOnlyDebugCFIMoves()) 50d88c1a5aSDimitry Andric Asm->OutStreamer->EmitCFISections(false, true); 51d88c1a5aSDimitry Andric hasEmittedCFISections = true; 52d88c1a5aSDimitry Andric } 53d88c1a5aSDimitry Andric 5491bc56edSDimitry Andric shouldEmitCFI = true; 55ff0cc061SDimitry Andric Asm->OutStreamer->EmitCFIStartProc(false); 5691bc56edSDimitry Andric } 573b0f4066SDimitry Andric } 583b0f4066SDimitry Andric 5991bc56edSDimitry Andric /// endFunction - Gather and emit post-function exception information. 603b0f4066SDimitry Andric /// endFunction(const MachineFunction * MF)61ff0cc061SDimitry Andricvoid ARMException::endFunction(const MachineFunction *MF) { 62f785676fSDimitry Andric ARMTargetStreamer &ATS = getTargetStreamer(); 632cab237bSDimitry Andric const Function &F = MF->getFunction(); 64875ed548SDimitry Andric const Function *Per = nullptr; 652cab237bSDimitry Andric if (F.hasPersonalityFn()) 662cab237bSDimitry Andric Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); 67875ed548SDimitry Andric bool forceEmitPersonality = 682cab237bSDimitry Andric F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && 692cab237bSDimitry Andric F.needsUnwindTableEntry(); 70875ed548SDimitry Andric bool shouldEmitPersonality = forceEmitPersonality || 71d88c1a5aSDimitry Andric !MF->getLandingPads().empty(); 722cab237bSDimitry Andric if (!Asm->MF->getFunction().needsUnwindTableEntry() && 73875ed548SDimitry Andric !shouldEmitPersonality) 74f785676fSDimitry Andric ATS.emitCantUnwind(); 75875ed548SDimitry Andric else if (shouldEmitPersonality) { 763b0f4066SDimitry Andric // Emit references to personality. 77875ed548SDimitry Andric if (Per) { 78875ed548SDimitry Andric MCSymbol *PerSym = Asm->getSymbol(Per); 79ff0cc061SDimitry Andric Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global); 80f785676fSDimitry Andric ATS.emitPersonality(PerSym); 813b0f4066SDimitry Andric } 823b0f4066SDimitry Andric 83139f7f9bSDimitry Andric // Emit .handlerdata directive. 84f785676fSDimitry Andric ATS.emitHandlerData(); 853b0f4066SDimitry Andric 863b0f4066SDimitry Andric // Emit actual exception table 8791bc56edSDimitry Andric emitExceptionTable(); 88dff0c46cSDimitry Andric } 893b0f4066SDimitry Andric 9091bc56edSDimitry Andric if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 91f785676fSDimitry Andric ATS.emitFnEnd(); 923b0f4066SDimitry Andric } 93139f7f9bSDimitry Andric emitTypeInfos(unsigned TTypeEncoding,MCSymbol * TTBaseLabel)94*4ba319b5SDimitry Andricvoid ARMException::emitTypeInfos(unsigned TTypeEncoding, 95*4ba319b5SDimitry Andric MCSymbol *TTBaseLabel) { 96d88c1a5aSDimitry Andric const MachineFunction *MF = Asm->MF; 97d88c1a5aSDimitry Andric const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos(); 98d88c1a5aSDimitry Andric const std::vector<unsigned> &FilterIds = MF->getFilterIds(); 99139f7f9bSDimitry Andric 100ff0cc061SDimitry Andric bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); 101139f7f9bSDimitry Andric 102139f7f9bSDimitry Andric int Entry = 0; 103139f7f9bSDimitry Andric // Emit the Catch TypeInfos. 104139f7f9bSDimitry Andric if (VerboseAsm && !TypeInfos.empty()) { 105ff0cc061SDimitry Andric Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); 106ff0cc061SDimitry Andric Asm->OutStreamer->AddBlankLine(); 107139f7f9bSDimitry Andric Entry = TypeInfos.size(); 108139f7f9bSDimitry Andric } 109139f7f9bSDimitry Andric 1107d523365SDimitry Andric for (const GlobalValue *GV : reverse(TypeInfos)) { 111139f7f9bSDimitry Andric if (VerboseAsm) 112ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--)); 113139f7f9bSDimitry Andric Asm->EmitTTypeReference(GV, TTypeEncoding); 114139f7f9bSDimitry Andric } 115139f7f9bSDimitry Andric 116*4ba319b5SDimitry Andric Asm->OutStreamer->EmitLabel(TTBaseLabel); 117*4ba319b5SDimitry Andric 118139f7f9bSDimitry Andric // Emit the Exception Specifications. 119139f7f9bSDimitry Andric if (VerboseAsm && !FilterIds.empty()) { 120ff0cc061SDimitry Andric Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); 121ff0cc061SDimitry Andric Asm->OutStreamer->AddBlankLine(); 122139f7f9bSDimitry Andric Entry = 0; 123139f7f9bSDimitry Andric } 124139f7f9bSDimitry Andric for (std::vector<unsigned>::const_iterator 125139f7f9bSDimitry Andric I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 126139f7f9bSDimitry Andric unsigned TypeID = *I; 127139f7f9bSDimitry Andric if (VerboseAsm) { 128139f7f9bSDimitry Andric --Entry; 129139f7f9bSDimitry Andric if (TypeID != 0) 130ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry)); 131139f7f9bSDimitry Andric } 132139f7f9bSDimitry Andric 13391bc56edSDimitry Andric Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]), 134139f7f9bSDimitry Andric TTypeEncoding); 135139f7f9bSDimitry Andric } 136139f7f9bSDimitry Andric } 137