LLVM API Documentation
00001 //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains support for writing DWARF exception info into asm files. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "DwarfException.h" 00015 #include "llvm/ADT/SmallString.h" 00016 #include "llvm/ADT/StringExtras.h" 00017 #include "llvm/ADT/Twine.h" 00018 #include "llvm/CodeGen/AsmPrinter.h" 00019 #include "llvm/CodeGen/MachineFrameInfo.h" 00020 #include "llvm/CodeGen/MachineFunction.h" 00021 #include "llvm/CodeGen/MachineModuleInfo.h" 00022 #include "llvm/IR/DataLayout.h" 00023 #include "llvm/IR/Mangler.h" 00024 #include "llvm/IR/Module.h" 00025 #include "llvm/MC/MCAsmInfo.h" 00026 #include "llvm/MC/MCContext.h" 00027 #include "llvm/MC/MCExpr.h" 00028 #include "llvm/MC/MCSection.h" 00029 #include "llvm/MC/MCStreamer.h" 00030 #include "llvm/MC/MCSymbol.h" 00031 #include "llvm/MC/MachineLocation.h" 00032 #include "llvm/Support/Dwarf.h" 00033 #include "llvm/Support/ErrorHandling.h" 00034 #include "llvm/Support/FormattedStream.h" 00035 #include "llvm/Target/TargetFrameLowering.h" 00036 #include "llvm/Target/TargetLoweringObjectFile.h" 00037 #include "llvm/Target/TargetMachine.h" 00038 #include "llvm/Target/TargetOptions.h" 00039 #include "llvm/Target/TargetRegisterInfo.h" 00040 using namespace llvm; 00041 00042 DwarfCFIException::DwarfCFIException(AsmPrinter *A) 00043 : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false), 00044 shouldEmitMoves(false), moveTypeModule(AsmPrinter::CFI_M_None) {} 00045 00046 DwarfCFIException::~DwarfCFIException() {} 00047 00048 /// endModule - Emit all exception information that should come after the 00049 /// content. 00050 void DwarfCFIException::endModule() { 00051 if (moveTypeModule == AsmPrinter::CFI_M_Debug) 00052 Asm->OutStreamer.EmitCFISections(false, true); 00053 00054 if (!Asm->MAI->isExceptionHandlingDwarf()) 00055 return; 00056 00057 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 00058 00059 unsigned PerEncoding = TLOF.getPersonalityEncoding(); 00060 00061 if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect) 00062 return; 00063 00064 // Emit references to all used personality functions 00065 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 00066 for (size_t i = 0, e = Personalities.size(); i != e; ++i) { 00067 if (!Personalities[i]) 00068 continue; 00069 MCSymbol *Sym = Asm->getSymbol(Personalities[i]); 00070 TLOF.emitPersonalityValue(Asm->OutStreamer, Asm->TM, Sym); 00071 } 00072 } 00073 00074 /// beginFunction - Gather pre-function exception information. Assumes it's 00075 /// being emitted immediately after the function entry point. 00076 void DwarfCFIException::beginFunction(const MachineFunction *MF) { 00077 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; 00078 00079 // If any landing pads survive, we need an EH table. 00080 bool hasLandingPads = !MMI->getLandingPads().empty(); 00081 00082 // See if we need frame move info. 00083 AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); 00084 if (MoveType == AsmPrinter::CFI_M_EH || 00085 (MoveType == AsmPrinter::CFI_M_Debug && 00086 moveTypeModule == AsmPrinter::CFI_M_None)) 00087 moveTypeModule = MoveType; 00088 00089 shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None; 00090 00091 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 00092 unsigned PerEncoding = TLOF.getPersonalityEncoding(); 00093 const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()]; 00094 00095 shouldEmitPersonality = hasLandingPads && 00096 PerEncoding != dwarf::DW_EH_PE_omit && Per; 00097 00098 unsigned LSDAEncoding = TLOF.getLSDAEncoding(); 00099 shouldEmitLSDA = shouldEmitPersonality && 00100 LSDAEncoding != dwarf::DW_EH_PE_omit; 00101 00102 if (!shouldEmitPersonality && !shouldEmitMoves) 00103 return; 00104 00105 Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false); 00106 00107 // Indicate personality routine, if any. 00108 if (!shouldEmitPersonality) 00109 return; 00110 00111 const MCSymbol *Sym = 00112 TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); 00113 Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding); 00114 00115 MCSymbol *EHBegin = 00116 Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); 00117 if (Asm->MAI->useAssignmentForEHBegin()) { 00118 MCContext &Ctx = Asm->OutContext; 00119 MCSymbol *CurPos = Ctx.CreateTempSymbol(); 00120 Asm->OutStreamer.EmitLabel(CurPos); 00121 Asm->OutStreamer.EmitAssignment(EHBegin, 00122 MCSymbolRefExpr::Create(CurPos, Ctx)); 00123 } else { 00124 Asm->OutStreamer.EmitLabel(EHBegin); 00125 } 00126 00127 // Provide LSDA information. 00128 if (!shouldEmitLSDA) 00129 return; 00130 00131 Asm->OutStreamer.EmitCFILsda(Asm->GetTempSymbol("exception", 00132 Asm->getFunctionNumber()), 00133 LSDAEncoding); 00134 } 00135 00136 /// endFunction - Gather and emit post-function exception information. 00137 /// 00138 void DwarfCFIException::endFunction(const MachineFunction *) { 00139 if (!shouldEmitPersonality && !shouldEmitMoves) 00140 return; 00141 00142 Asm->OutStreamer.EmitCFIEndProc(); 00143 00144 if (!shouldEmitPersonality) 00145 return; 00146 00147 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", 00148 Asm->getFunctionNumber())); 00149 00150 // Map all labels and get rid of any dead landing pads. 00151 MMI->TidyLandingPads(); 00152 00153 emitExceptionTable(); 00154 }