1*9880d681SAndroid Build Coastguard Worker //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file contains support for writing DWARF exception info into asm files. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #include "DwarfException.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h" 30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h" 31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetFrameLowering.h" 33*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h" 34*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h" 35*9880d681SAndroid Build Coastguard Worker using namespace llvm; 36*9880d681SAndroid Build Coastguard Worker ARMException(AsmPrinter * A)37*9880d681SAndroid Build Coastguard WorkerARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} 38*9880d681SAndroid Build Coastguard Worker ~ARMException()39*9880d681SAndroid Build Coastguard WorkerARMException::~ARMException() {} 40*9880d681SAndroid Build Coastguard Worker getTargetStreamer()41*9880d681SAndroid Build Coastguard WorkerARMTargetStreamer &ARMException::getTargetStreamer() { 42*9880d681SAndroid Build Coastguard Worker MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer(); 43*9880d681SAndroid Build Coastguard Worker return static_cast<ARMTargetStreamer &>(TS); 44*9880d681SAndroid Build Coastguard Worker } 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker /// endModule - Emit all exception information that should come after the 47*9880d681SAndroid Build Coastguard Worker /// content. endModule()48*9880d681SAndroid Build Coastguard Workervoid ARMException::endModule() { 49*9880d681SAndroid Build Coastguard Worker if (shouldEmitCFI) 50*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitCFISections(false, true); 51*9880d681SAndroid Build Coastguard Worker } 52*9880d681SAndroid Build Coastguard Worker beginFunction(const MachineFunction * MF)53*9880d681SAndroid Build Coastguard Workervoid ARMException::beginFunction(const MachineFunction *MF) { 54*9880d681SAndroid Build Coastguard Worker if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 55*9880d681SAndroid Build Coastguard Worker getTargetStreamer().emitFnStart(); 56*9880d681SAndroid Build Coastguard Worker // See if we need call frame info. 57*9880d681SAndroid Build Coastguard Worker AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); 58*9880d681SAndroid Build Coastguard Worker assert(MoveType != AsmPrinter::CFI_M_EH && 59*9880d681SAndroid Build Coastguard Worker "non-EH CFI not yet supported in prologue with EHABI lowering"); 60*9880d681SAndroid Build Coastguard Worker if (MoveType == AsmPrinter::CFI_M_Debug) { 61*9880d681SAndroid Build Coastguard Worker shouldEmitCFI = true; 62*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitCFIStartProc(false); 63*9880d681SAndroid Build Coastguard Worker } 64*9880d681SAndroid Build Coastguard Worker } 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker /// endFunction - Gather and emit post-function exception information. 67*9880d681SAndroid Build Coastguard Worker /// endFunction(const MachineFunction * MF)68*9880d681SAndroid Build Coastguard Workervoid ARMException::endFunction(const MachineFunction *MF) { 69*9880d681SAndroid Build Coastguard Worker ARMTargetStreamer &ATS = getTargetStreamer(); 70*9880d681SAndroid Build Coastguard Worker const Function *F = MF->getFunction(); 71*9880d681SAndroid Build Coastguard Worker const Function *Per = nullptr; 72*9880d681SAndroid Build Coastguard Worker if (F->hasPersonalityFn()) 73*9880d681SAndroid Build Coastguard Worker Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); 74*9880d681SAndroid Build Coastguard Worker bool forceEmitPersonality = 75*9880d681SAndroid Build Coastguard Worker F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && 76*9880d681SAndroid Build Coastguard Worker F->needsUnwindTableEntry(); 77*9880d681SAndroid Build Coastguard Worker bool shouldEmitPersonality = forceEmitPersonality || 78*9880d681SAndroid Build Coastguard Worker !MMI->getLandingPads().empty(); 79*9880d681SAndroid Build Coastguard Worker if (!Asm->MF->getFunction()->needsUnwindTableEntry() && 80*9880d681SAndroid Build Coastguard Worker !shouldEmitPersonality) 81*9880d681SAndroid Build Coastguard Worker ATS.emitCantUnwind(); 82*9880d681SAndroid Build Coastguard Worker else if (shouldEmitPersonality) { 83*9880d681SAndroid Build Coastguard Worker // Emit references to personality. 84*9880d681SAndroid Build Coastguard Worker if (Per) { 85*9880d681SAndroid Build Coastguard Worker MCSymbol *PerSym = Asm->getSymbol(Per); 86*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global); 87*9880d681SAndroid Build Coastguard Worker ATS.emitPersonality(PerSym); 88*9880d681SAndroid Build Coastguard Worker } 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker // Emit .handlerdata directive. 91*9880d681SAndroid Build Coastguard Worker ATS.emitHandlerData(); 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker // Emit actual exception table 94*9880d681SAndroid Build Coastguard Worker emitExceptionTable(); 95*9880d681SAndroid Build Coastguard Worker } 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 98*9880d681SAndroid Build Coastguard Worker ATS.emitFnEnd(); 99*9880d681SAndroid Build Coastguard Worker } 100*9880d681SAndroid Build Coastguard Worker emitTypeInfos(unsigned TTypeEncoding)101*9880d681SAndroid Build Coastguard Workervoid ARMException::emitTypeInfos(unsigned TTypeEncoding) { 102*9880d681SAndroid Build Coastguard Worker const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos(); 103*9880d681SAndroid Build Coastguard Worker const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker int Entry = 0; 108*9880d681SAndroid Build Coastguard Worker // Emit the Catch TypeInfos. 109*9880d681SAndroid Build Coastguard Worker if (VerboseAsm && !TypeInfos.empty()) { 110*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); 111*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddBlankLine(); 112*9880d681SAndroid Build Coastguard Worker Entry = TypeInfos.size(); 113*9880d681SAndroid Build Coastguard Worker } 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker for (const GlobalValue *GV : reverse(TypeInfos)) { 116*9880d681SAndroid Build Coastguard Worker if (VerboseAsm) 117*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--)); 118*9880d681SAndroid Build Coastguard Worker Asm->EmitTTypeReference(GV, TTypeEncoding); 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker // Emit the Exception Specifications. 122*9880d681SAndroid Build Coastguard Worker if (VerboseAsm && !FilterIds.empty()) { 123*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); 124*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddBlankLine(); 125*9880d681SAndroid Build Coastguard Worker Entry = 0; 126*9880d681SAndroid Build Coastguard Worker } 127*9880d681SAndroid Build Coastguard Worker for (std::vector<unsigned>::const_iterator 128*9880d681SAndroid Build Coastguard Worker I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 129*9880d681SAndroid Build Coastguard Worker unsigned TypeID = *I; 130*9880d681SAndroid Build Coastguard Worker if (VerboseAsm) { 131*9880d681SAndroid Build Coastguard Worker --Entry; 132*9880d681SAndroid Build Coastguard Worker if (TypeID != 0) 133*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry)); 134*9880d681SAndroid Build Coastguard Worker } 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]), 137*9880d681SAndroid Build Coastguard Worker TTypeEncoding); 138*9880d681SAndroid Build Coastguard Worker } 139*9880d681SAndroid Build Coastguard Worker } 140