1218885Sdim//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file contains support for writing DWARF exception info into asm files. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "DwarfException.h" 15249423Sdim#include "llvm/ADT/SmallString.h" 16249423Sdim#include "llvm/ADT/StringExtras.h" 17249423Sdim#include "llvm/ADT/Twine.h" 18218885Sdim#include "llvm/CodeGen/AsmPrinter.h" 19218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 20218885Sdim#include "llvm/CodeGen/MachineFunction.h" 21249423Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 22249423Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/IR/Module.h" 24218885Sdim#include "llvm/MC/MCAsmInfo.h" 25218885Sdim#include "llvm/MC/MCContext.h" 26218885Sdim#include "llvm/MC/MCExpr.h" 27218885Sdim#include "llvm/MC/MCSection.h" 28218885Sdim#include "llvm/MC/MCStreamer.h" 29218885Sdim#include "llvm/MC/MCSymbol.h" 30249423Sdim#include "llvm/MC/MachineLocation.h" 31249423Sdim#include "llvm/Support/Dwarf.h" 32249423Sdim#include "llvm/Support/ErrorHandling.h" 33249423Sdim#include "llvm/Support/FormattedStream.h" 34218885Sdim#include "llvm/Target/Mangler.h" 35218885Sdim#include "llvm/Target/TargetFrameLowering.h" 36218885Sdim#include "llvm/Target/TargetLoweringObjectFile.h" 37218885Sdim#include "llvm/Target/TargetMachine.h" 38218885Sdim#include "llvm/Target/TargetOptions.h" 39218885Sdim#include "llvm/Target/TargetRegisterInfo.h" 40218885Sdimusing namespace llvm; 41218885Sdim 42218885SdimDwarfCFIException::DwarfCFIException(AsmPrinter *A) 43218885Sdim : DwarfException(A), 44223017Sdim shouldEmitPersonality(false), shouldEmitLSDA(false), shouldEmitMoves(false), 45223017Sdim moveTypeModule(AsmPrinter::CFI_M_None) {} 46218885Sdim 47218885SdimDwarfCFIException::~DwarfCFIException() {} 48218885Sdim 49218885Sdim/// EndModule - Emit all exception information that should come after the 50218885Sdim/// content. 51218885Sdimvoid DwarfCFIException::EndModule() { 52223017Sdim if (moveTypeModule == AsmPrinter::CFI_M_Debug) 53223017Sdim Asm->OutStreamer.EmitCFISections(false, true); 54223017Sdim 55218885Sdim if (!Asm->MAI->isExceptionHandlingDwarf()) 56218885Sdim return; 57218885Sdim 58221345Sdim const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 59218885Sdim 60218885Sdim unsigned PerEncoding = TLOF.getPersonalityEncoding(); 61218885Sdim 62221345Sdim if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel) 63221345Sdim return; 64218885Sdim 65218885Sdim // Emit references to all used personality functions 66221345Sdim bool AtLeastOne = false; 67218885Sdim const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 68218885Sdim for (size_t i = 0, e = Personalities.size(); i != e; ++i) { 69221345Sdim if (!Personalities[i]) 70221345Sdim continue; 71263508Sdim MCSymbol *Sym = Asm->getSymbol(Personalities[i]); 72221345Sdim TLOF.emitPersonalityValue(Asm->OutStreamer, Asm->TM, Sym); 73221345Sdim AtLeastOne = true; 74218885Sdim } 75221345Sdim 76221345Sdim if (AtLeastOne && !TLOF.isFunctionEHFrameSymbolPrivate()) { 77221345Sdim // This is a temporary hack to keep sections in the same order they 78221345Sdim // were before. This lets us produce bit identical outputs while 79221345Sdim // transitioning to CFI. 80226633Sdim Asm->OutStreamer.SwitchSection( 81226633Sdim const_cast<TargetLoweringObjectFile&>(TLOF).getEHFrameSection()); 82221345Sdim } 83218885Sdim} 84218885Sdim 85218885Sdim/// BeginFunction - Gather pre-function exception information. Assumes it's 86218885Sdim/// being emitted immediately after the function entry point. 87218885Sdimvoid DwarfCFIException::BeginFunction(const MachineFunction *MF) { 88221345Sdim shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; 89218885Sdim 90218885Sdim // If any landing pads survive, we need an EH table. 91221345Sdim bool hasLandingPads = !MMI->getLandingPads().empty(); 92218885Sdim 93218885Sdim // See if we need frame move info. 94223017Sdim AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); 95223017Sdim if (MoveType == AsmPrinter::CFI_M_EH || 96223017Sdim (MoveType == AsmPrinter::CFI_M_Debug && 97223017Sdim moveTypeModule == AsmPrinter::CFI_M_None)) 98223017Sdim moveTypeModule = MoveType; 99218885Sdim 100223017Sdim shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None; 101223017Sdim 102221345Sdim const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 103221345Sdim unsigned PerEncoding = TLOF.getPersonalityEncoding(); 104221345Sdim const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()]; 105218885Sdim 106221345Sdim shouldEmitPersonality = hasLandingPads && 107221345Sdim PerEncoding != dwarf::DW_EH_PE_omit && Per; 108218885Sdim 109221345Sdim unsigned LSDAEncoding = TLOF.getLSDAEncoding(); 110221345Sdim shouldEmitLSDA = shouldEmitPersonality && 111221345Sdim LSDAEncoding != dwarf::DW_EH_PE_omit; 112218885Sdim 113221345Sdim if (!shouldEmitPersonality && !shouldEmitMoves) 114221345Sdim return; 115218885Sdim 116221345Sdim Asm->OutStreamer.EmitCFIStartProc(); 117221345Sdim 118221345Sdim // Indicate personality routine, if any. 119221345Sdim if (!shouldEmitPersonality) 120218885Sdim return; 121218885Sdim 122221345Sdim const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(Per, Asm->Mang, MMI); 123221345Sdim Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding); 124218885Sdim 125249423Sdim Asm->OutStreamer.EmitDebugLabel 126249423Sdim (Asm->GetTempSymbol("eh_func_begin", 127249423Sdim Asm->getFunctionNumber())); 128221345Sdim 129218885Sdim // Provide LSDA information. 130221345Sdim if (!shouldEmitLSDA) 131221345Sdim return; 132218885Sdim 133221345Sdim Asm->OutStreamer.EmitCFILsda(Asm->GetTempSymbol("exception", 134221345Sdim Asm->getFunctionNumber()), 135221345Sdim LSDAEncoding); 136218885Sdim} 137218885Sdim 138218885Sdim/// EndFunction - Gather and emit post-function exception information. 139218885Sdim/// 140218885Sdimvoid DwarfCFIException::EndFunction() { 141221345Sdim if (!shouldEmitPersonality && !shouldEmitMoves) 142221345Sdim return; 143218885Sdim 144221345Sdim Asm->OutStreamer.EmitCFIEndProc(); 145218885Sdim 146234353Sdim if (!shouldEmitPersonality) 147234353Sdim return; 148234353Sdim 149218885Sdim Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", 150218885Sdim Asm->getFunctionNumber())); 151218885Sdim 152218885Sdim // Map all labels and get rid of any dead landing pads. 153218885Sdim MMI->TidyLandingPads(); 154218885Sdim 155234353Sdim EmitExceptionTable(); 156218885Sdim} 157