1 //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains support for writing DWARF exception info into asm files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "DwarfException.h" 15 #include "llvm/Module.h" 16 #include "llvm/CodeGen/AsmPrinter.h" 17 #include "llvm/CodeGen/MachineModuleInfo.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineLocation.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCSection.h" 25 #include "llvm/MC/MCStreamer.h" 26 #include "llvm/MC/MCSymbol.h" 27 #include "llvm/Target/Mangler.h" 28 #include "llvm/Target/TargetData.h" 29 #include "llvm/Target/TargetFrameLowering.h" 30 #include "llvm/Target/TargetLoweringObjectFile.h" 31 #include "llvm/Target/TargetMachine.h" 32 #include "llvm/Target/TargetOptions.h" 33 #include "llvm/Target/TargetRegisterInfo.h" 34 #include "llvm/Support/Dwarf.h" 35 #include "llvm/Support/FormattedStream.h" 36 #include "llvm/ADT/SmallString.h" 37 #include "llvm/ADT/StringExtras.h" 38 #include "llvm/ADT/Twine.h" 39 using namespace llvm; 40 41 DwarfCFIException::DwarfCFIException(AsmPrinter *A) 42 : DwarfException(A), 43 shouldEmitTable(false), shouldEmitMoves(false), shouldEmitTableModule(false) 44 {} 45 46 DwarfCFIException::~DwarfCFIException() {} 47 48 /// EndModule - Emit all exception information that should come after the 49 /// content. 50 void DwarfCFIException::EndModule() { 51 if (!Asm->MAI->isExceptionHandlingDwarf()) 52 return; 53 54 if (!shouldEmitTableModule) 55 return; 56 57 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 58 unsigned PerEncoding = TLOF.getPersonalityEncoding(); 59 60 // Begin eh frame section. 61 Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); 62 63 // Emit references to all used personality functions 64 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 65 for (size_t i = 0, e = Personalities.size(); i != e; ++i) { 66 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("personality", i)); 67 Asm->EmitReference(Personalities[i], PerEncoding); 68 } 69 } 70 71 /// BeginFunction - Gather pre-function exception information. Assumes it's 72 /// being emitted immediately after the function entry point. 73 void DwarfCFIException::BeginFunction(const MachineFunction *MF) { 74 shouldEmitTable = shouldEmitMoves = false; 75 76 // If any landing pads survive, we need an EH table. 77 shouldEmitTable = !MMI->getLandingPads().empty(); 78 79 // See if we need frame move info. 80 shouldEmitMoves = 81 !Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory; 82 83 if (shouldEmitMoves || shouldEmitTable) 84 // Assumes in correct section after the entry point. 85 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin", 86 Asm->getFunctionNumber())); 87 88 shouldEmitTableModule |= shouldEmitTable; 89 90 if (shouldEmitMoves) { 91 const TargetFrameLowering *TFL = Asm->TM.getFrameLowering(); 92 Asm->OutStreamer.EmitCFIStartProc(); 93 94 // Indicate locations of general callee saved registers in frame. 95 std::vector<MachineMove> Moves; 96 TFL->getInitialFrameState(Moves); 97 Asm->EmitCFIFrameMoves(Moves); 98 Asm->EmitCFIFrameMoves(MMI->getFrameMoves()); 99 } 100 101 if (!shouldEmitTable) 102 return; 103 104 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 105 106 // Provide LSDA information. 107 unsigned LSDAEncoding = TLOF.getLSDAEncoding(); 108 if (LSDAEncoding != dwarf::DW_EH_PE_omit) 109 Asm->OutStreamer.EmitCFILsda(Asm->GetTempSymbol("exception", 110 Asm->getFunctionNumber()), 111 LSDAEncoding); 112 113 // Indicate personality routine, if any. 114 unsigned PerEncoding = TLOF.getPersonalityEncoding(); 115 if (PerEncoding != dwarf::DW_EH_PE_omit && 116 MMI->getPersonalities()[MMI->getPersonalityIndex()]) 117 Asm->OutStreamer.EmitCFIPersonality(Asm->GetTempSymbol("personality", 118 MMI->getPersonalityIndex()), 119 PerEncoding); 120 } 121 122 /// EndFunction - Gather and emit post-function exception information. 123 /// 124 void DwarfCFIException::EndFunction() { 125 if (!shouldEmitMoves && !shouldEmitTable) return; 126 127 if (shouldEmitMoves) 128 Asm->OutStreamer.EmitCFIEndProc(); 129 130 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", 131 Asm->getFunctionNumber())); 132 133 // Map all labels and get rid of any dead landing pads. 134 MMI->TidyLandingPads(); 135 136 if (shouldEmitTable) 137 EmitExceptionTable(); 138 } 139