1221337Sdim//===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===// 2221337Sdim// 3221337Sdim// The LLVM Compiler Infrastructure 4221337Sdim// 5221337Sdim// This file is distributed under the University of Illinois Open Source 6221337Sdim// License. See LICENSE.TXT for details. 7221337Sdim// 8221337Sdim//===----------------------------------------------------------------------===// 9221337Sdim// 10221337Sdim// This file contains support for writing DWARF exception info into asm files. 11221337Sdim// 12221337Sdim//===----------------------------------------------------------------------===// 13221337Sdim 14221337Sdim#include "DwarfException.h" 15249423Sdim#include "llvm/ADT/SmallString.h" 16249423Sdim#include "llvm/ADT/StringExtras.h" 17249423Sdim#include "llvm/ADT/Twine.h" 18221337Sdim#include "llvm/CodeGen/AsmPrinter.h" 19221337Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 20221337Sdim#include "llvm/CodeGen/MachineFunction.h" 21249423Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 22249423Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/IR/Module.h" 24221337Sdim#include "llvm/MC/MCAsmInfo.h" 25221337Sdim#include "llvm/MC/MCContext.h" 26221337Sdim#include "llvm/MC/MCExpr.h" 27221337Sdim#include "llvm/MC/MCSection.h" 28221337Sdim#include "llvm/MC/MCStreamer.h" 29221337Sdim#include "llvm/MC/MCSymbol.h" 30249423Sdim#include "llvm/Support/CommandLine.h" 31249423Sdim#include "llvm/Support/Dwarf.h" 32249423Sdim#include "llvm/Support/FormattedStream.h" 33221337Sdim#include "llvm/Target/Mangler.h" 34221337Sdim#include "llvm/Target/TargetFrameLowering.h" 35221337Sdim#include "llvm/Target/TargetOptions.h" 36221337Sdim#include "llvm/Target/TargetRegisterInfo.h" 37221337Sdimusing namespace llvm; 38221337Sdim 39249423Sdimstatic cl::opt<bool> 40234353SdimEnableARMEHABIDescriptors("arm-enable-ehabi-descriptors", cl::Hidden, 41234353Sdim cl::desc("Generate ARM EHABI tables with unwinding descriptors"), 42234353Sdim cl::init(false)); 43234353Sdim 44234353Sdim 45221337SdimARMException::ARMException(AsmPrinter *A) 46239462Sdim : DwarfException(A) {} 47221337Sdim 48221337SdimARMException::~ARMException() {} 49221337Sdim 50263508SdimARMTargetStreamer &ARMException::getTargetStreamer() { 51263508Sdim MCTargetStreamer &TS = Asm->OutStreamer.getTargetStreamer(); 52263508Sdim return static_cast<ARMTargetStreamer &>(TS); 53263508Sdim} 54263508Sdim 55221337Sdimvoid ARMException::EndModule() { 56221337Sdim} 57221337Sdim 58221337Sdim/// BeginFunction - Gather pre-function exception information. Assumes it's 59221337Sdim/// being emitted immediately after the function entry point. 60221337Sdimvoid ARMException::BeginFunction(const MachineFunction *MF) { 61263508Sdim getTargetStreamer().emitFnStart(); 62223017Sdim if (Asm->MF->getFunction()->needsUnwindTableEntry()) 63221337Sdim Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin", 64221337Sdim Asm->getFunctionNumber())); 65221337Sdim} 66221337Sdim 67221337Sdim/// EndFunction - Gather and emit post-function exception information. 68221337Sdim/// 69221337Sdimvoid ARMException::EndFunction() { 70263508Sdim ARMTargetStreamer &ATS = getTargetStreamer(); 71223017Sdim if (!Asm->MF->getFunction()->needsUnwindTableEntry()) 72263508Sdim ATS.emitCantUnwind(); 73221337Sdim else { 74221337Sdim Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", 75221337Sdim Asm->getFunctionNumber())); 76221337Sdim 77234353Sdim if (EnableARMEHABIDescriptors) { 78234353Sdim // Map all labels and get rid of any dead landing pads. 79234353Sdim MMI->TidyLandingPads(); 80221337Sdim 81249423Sdim if (!MMI->getLandingPads().empty()) { 82249423Sdim // Emit references to personality. 83249423Sdim if (const Function * Personality = 84249423Sdim MMI->getPersonalities()[MMI->getPersonalityIndex()]) { 85263508Sdim MCSymbol *PerSym = Asm->getSymbol(Personality); 86249423Sdim Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global); 87263508Sdim ATS.emitPersonality(PerSym); 88249423Sdim } 89221337Sdim 90249423Sdim // Emit .handlerdata directive. 91263508Sdim ATS.emitHandlerData(); 92249423Sdim 93249423Sdim // Emit actual exception table 94249423Sdim EmitExceptionTable(); 95249423Sdim } 96234353Sdim } 97221337Sdim } 98221337Sdim 99263508Sdim ATS.emitFnEnd(); 100221337Sdim} 101249423Sdim 102249423Sdimvoid ARMException::EmitTypeInfos(unsigned TTypeEncoding) { 103249423Sdim const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 104249423Sdim const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 105249423Sdim 106249423Sdim bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); 107249423Sdim 108249423Sdim int Entry = 0; 109249423Sdim // Emit the Catch TypeInfos. 110249423Sdim if (VerboseAsm && !TypeInfos.empty()) { 111249423Sdim Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); 112249423Sdim Asm->OutStreamer.AddBlankLine(); 113249423Sdim Entry = TypeInfos.size(); 114249423Sdim } 115249423Sdim 116249423Sdim for (std::vector<const GlobalVariable *>::const_reverse_iterator 117249423Sdim I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 118249423Sdim const GlobalVariable *GV = *I; 119249423Sdim if (VerboseAsm) 120249423Sdim Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); 121249423Sdim Asm->EmitTTypeReference(GV, TTypeEncoding); 122249423Sdim } 123249423Sdim 124249423Sdim // Emit the Exception Specifications. 125249423Sdim if (VerboseAsm && !FilterIds.empty()) { 126249423Sdim Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); 127249423Sdim Asm->OutStreamer.AddBlankLine(); 128249423Sdim Entry = 0; 129249423Sdim } 130249423Sdim for (std::vector<unsigned>::const_iterator 131249423Sdim I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 132249423Sdim unsigned TypeID = *I; 133249423Sdim if (VerboseAsm) { 134249423Sdim --Entry; 135249423Sdim if (TypeID != 0) 136249423Sdim Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry)); 137249423Sdim } 138249423Sdim 139249423Sdim Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]), 140249423Sdim TTypeEncoding); 141249423Sdim } 142249423Sdim} 143