DwarfException.cpp revision 0bb61c56bcad7a738d50f705b5966be446ef06c1
1eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 2eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 3eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// The LLVM Compiler Infrastructure 4eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 5eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// This file is distributed under the University of Illinois Open Source 6eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// License. See LICENSE.TXT for details. 7eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 8eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===// 9eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 10639217cb6a3948800c71c39503f8def4873a535eBill Wendling// This file contains support for writing dwarf exception info into asm files. 11eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 12eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===// 13eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 14eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "DwarfException.h" 15eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Module.h" 16eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineModuleInfo.h" 17eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineFrameInfo.h" 18fc4da0cea8a0f6c9c1483b92c2dffda217c0ba24David Greene#include "llvm/CodeGen/MachineFunction.h" 19eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineLocation.h" 206c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 21af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 22eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetData.h" 23eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetFrameInfo.h" 24d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 259b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling#include "llvm/Target/TargetLowering.h" 26eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetOptions.h" 27d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetRegisterInfo.h" 286c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/Support/Dwarf.h" 296c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/Support/Timer.h" 306c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/Support/raw_ostream.h" 31eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/ADT/StringExtras.h" 32eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm; 33eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 34eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingstatic TimerGroup &getDwarfTimerGroup() { 35eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling static TimerGroup DwarfTimerGroup("Dwarf Exception"); 36eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return DwarfTimerGroup; 37eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 38eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 39bc0d23afae781c45f92865c1c27bed0ce51fe545Bill WendlingDwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, 40af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner const MCAsmInfo *T) 41bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), 42bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling shouldEmitTableModule(false), shouldEmitMovesModule(false), 43bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling ExceptionTimer(0) { 44dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher if (TimePassesIsEnabled) 45bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling ExceptionTimer = new Timer("Dwarf Exception Writer", 46bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling getDwarfTimerGroup()); 47bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling} 48bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 49bc0d23afae781c45f92865c1c27bed0ce51fe545Bill WendlingDwarfException::~DwarfException() { 50bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling delete ExceptionTimer; 51bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling} 52bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 537ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling/// EmitCIE - Emit a Common Information Entry (CIE). This holds information that 547ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling/// is shared among many Frame Description Entries. There is at least one CIE 557ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling/// in every non-empty .debug_frame section. 567ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendlingvoid DwarfException::EmitCIE(const Function *Personality, unsigned Index) { 57eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Size and sign of stack growth. 58eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int stackGrowth = 59eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->TM.getFrameInfo()->getStackGrowthDirection() == 60eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetFrameInfo::StackGrowsUp ? 61eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TD->getPointerSize() : -TD->getPointerSize(); 62eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 63eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Begin eh frame section. 646c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); 65eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 6633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->is_EHSymbolPrivate()) 6733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPrivateGlobalPrefix(); 68eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "EH_frame" << Index << ":\n"; 70eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("section_eh_frame", Index); 71eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 72eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Define base labels. 73eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common", Index); 74eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 75eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Define the eh frame length. 76eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_frame_common_end", Index, 77eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "eh_frame_common_begin", Index, true); 78eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Length of Common Information Entry"); 79eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 80eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH frame header. 81eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common_begin", Index); 82eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt32((int)0); 83eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Identifier Tag"); 849b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 85eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_CIE_VERSION); 86eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Version"); 87eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 88eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The personality presence indicates that language specific information will 89eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // show up in the eh frame. 90eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitString(Personality ? "zPLR" : "zR"); 91eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Augmentation"); 92eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 93eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Round out reader. 94eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(1); 95eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Code Alignment Factor"); 969b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 97eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(stackGrowth); 98eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Data Alignment Factor"); 999b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 100eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); 101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Return Address Column"); 102eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1039b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling unsigned Encoding = 0; 1049b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 1054bda11fbdafc1d4fa97b7539bdf5a0f62ecfc280Bill Wendling // If there is a personality, we need to indicate the function's location. 106eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Personality) { 107eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(7); 108eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation Size"); 109eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 11033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getNeedsIndirectEncoding()) { 1119b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | 1129b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling dwarf::DW_EH_PE_indirect; 1139b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EmitInt8(Encoding); 1149b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EOL("Personality", Encoding); 115eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 1169b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; 1179b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EmitInt8(Encoding); 1189b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EOL("Personality", Encoding); 119eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 120eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 121eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintRelDirective(true); 12233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPersonalityPrefix(); 123eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); 12433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPersonalitySuffix(); 12533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (strcmp(MAI->getPersonalitySuffix(), "+4@GOTPCREL")) 12633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << "-" << MAI->getPCSymbol(); 127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Personality"); 128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1299b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Encoding = Asm->TM.getTargetLowering()->getPreferredLSDADataFormat(); 1309b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EmitInt8(Encoding); 1319b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EOL("LSDA Encoding", Encoding); 132eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1339b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat(); 1349b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EmitInt8(Encoding); 1359b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EOL("FDE Encoding", Encoding); 136eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 137eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(1); 138eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation Size"); 139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1409b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat(); 1419b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EmitInt8(Encoding); 1429b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling Asm->EOL("FDE Encoding", Encoding); 143eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 144eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 145eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Indicate locations of general callee saved registers in frame. 146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling std::vector<MachineMove> Moves; 147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling RI->getInitialFrameState(Moves); 148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitFrameMoves(NULL, 0, Moves, true); 149eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 150eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // On Darwin the linker honors the alignment of eh_frame, which means it must 151eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get 152eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // holes which confuse readers of eh_frame. 153eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 154eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 0, 0, false); 155eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common_end", Index); 156eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 157eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL(); 158eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 159eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1607ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling/// EmitFDE - Emit the Frame Description Entry (FDE) for the function. 1617ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendlingvoid DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { 162dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && 163eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Should not emit 'available externally' functions at all"); 164eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1653e0f60be46cb5363d4375f26a5e27d1dcd9867fbChris Lattner const Function *TheFunc = EHFrameInfo.function; 1669b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling bool is4Byte = TD->getPointerSize() == sizeof(int32_t); 167dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher 1686c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); 169dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher 170eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Externally visible entry into the functions eh frame info. If the 171eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // corresponding function is static, this should not be externally visible. 1723e0f60be46cb5363d4375f26a5e27d1dcd9867fbChris Lattner if (!TheFunc->hasLocalLinkage()) 17333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (const char *GlobalEHDirective = MAI->getGlobalEHDirective()) 174eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; 175eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 176eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If corresponding function is weak definition, this should be too. 17733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective()) 17833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; 179eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 180eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If there are no calls then you can't unwind. This may mean we can omit the 181eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH Frame, but some environments do not handle weak absolute symbols. If 182eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // UnwindTablesMandatory is set we cannot do this optimization; the unwind 183eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // info is to be available for non-EH uses. 1843e0f60be46cb5363d4375f26a5e27d1dcd9867fbChris Lattner if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory && 1853e0f60be46cb5363d4375f26a5e27d1dcd9867fbChris Lattner (!TheFunc->isWeakForLinker() || 18633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner !MAI->getWeakDefDirective() || 18733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner MAI->getSupportsWeakOmittedEHFrame())) { 188eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << EHFrameInfo.FnName << " = 0\n"; 189eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This name has no connection to the function, so it might get 190eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // dead-stripped when the function is not, erroneously. Prohibit 191eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // dead-stripping unconditionally. 19233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (const char *UsedDirective = MAI->getUsedDirective()) 193eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 194eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 195eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << EHFrameInfo.FnName << ":\n"; 196eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 197eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH frame header. 198eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_frame_end", EHFrameInfo.Number, 199eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "eh_frame_begin", EHFrameInfo.Number, true); 200eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Length of Frame Information Entry"); 201eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 202eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_begin", EHFrameInfo.Number); 203eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 204a4ff5e48fc6a4718d3a2af8654cfc06a17310aedChris Lattner EmitSectionOffset("eh_frame_begin", "eh_frame_common", 205a4ff5e48fc6a4718d3a2af8654cfc06a17310aedChris Lattner EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, 206a4ff5e48fc6a4718d3a2af8654cfc06a17310aedChris Lattner true, true, false); 207eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 208eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE CIE offset"); 209eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 2109b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling EmitReference("eh_func_begin", EHFrameInfo.Number, true, is4Byte); 211eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE initial location"); 2129b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 213eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_func_end", EHFrameInfo.Number, 2149b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling "eh_func_begin", EHFrameInfo.Number, is4Byte); 215eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE address range"); 216eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 217eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If there is a personality and landing pads then point to the language 218eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // specific data area in the exception table. 219d44fff7849034fc17d6a0e9f9926542865bb7881Eric Christopher if (MMI->getPersonalities()[0] != NULL) { 2206fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher Asm->EmitULEB128Bytes(is4Byte ? 4 : 8); 221eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation size"); 222eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 2239b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling if (EHFrameInfo.hasLandingPads) { 2246fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher EmitReference("exception", EHFrameInfo.Number, true, false); 2259b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling } else { 2266fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher if (is4Byte) 2276fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher Asm->EmitInt32((int)0); 2286fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher else 2296fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher Asm->EmitInt64((int)0); 2306fefcebc4f92b944664b7b26042bc21e57aefe43Eric Christopher } 231eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Language Specific Data Area"); 232eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(0); 234eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation size"); 235eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 236eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 237eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Indicate locations of function specific callee saved registers in frame. 238dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true); 240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 241eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // On Darwin the linker honors the alignment of eh_frame, which means it 242eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you 243eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // get holes which confuse readers of eh_frame. 244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 0, 0, false); 246eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_end", EHFrameInfo.Number); 247eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 248eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If the function is marked used, this table should be also. We cannot 249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // make the mark unconditional in this case, since retaining the table also 250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // retains the function in this case, and there is code around that depends 251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // on unused functions (calling undefined externals) being dead-stripped to 252eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // link correctly. Yes, there really is. 253401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner if (MMI->isUsedFunction(EHFrameInfo.function)) 25433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (const char *UsedDirective = MAI->getUsedDirective()) 255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 2574bda11fbdafc1d4fa97b7539bdf5a0f62ecfc280Bill Wendling 2584bda11fbdafc1d4fa97b7539bdf5a0f62ecfc280Bill Wendling Asm->EOL(); 259eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 260eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 261eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// SharedTypeIds - How many leading type ids two landing pads have in common. 262eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 263eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *R) { 264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 267eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Count = 0; 268eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 269eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (; Count != MinSize; ++Count) 270eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[Count] != RIds[Count]) 271eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 272eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 273eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 274eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 276eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// PadLT - Order landing pads lexicographically by type id. 277eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 278eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 279eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 280eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 281eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 282eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != MinSize; ++i) 283eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[i] != RIds[i]) 284eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LIds[i] < RIds[i]; 285eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 286eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LSize < RSize; 287eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 288eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 289d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// ComputeActionsTable - Compute the actions table and gather the first action 290d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// index for each landing pad site. 291ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingunsigned DwarfException:: 292ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 293ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<ActionEntry> &Actions, 294ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<unsigned> &FirstActions) { 295a583c55864e83e470333b7be878280b10e175a6eBill Wendling 296a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The action table follows the call-site table in the LSDA. The individual 297a583c55864e83e470333b7be878280b10e175a6eBill Wendling // records are of two types: 298a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 299a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Catch clause 300a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Exception specification 301a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 302a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The two record kinds have the same format, with only small differences. 303a583c55864e83e470333b7be878280b10e175a6eBill Wendling // They are distinguished by the "switch value" field: Catch clauses 304a583c55864e83e470333b7be878280b10e175a6eBill Wendling // (TypeInfos) have strictly positive switch values, and exception 305a583c55864e83e470333b7be878280b10e175a6eBill Wendling // specifications (FilterIds) have strictly negative switch values. Value 0 306a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates a catch-all clause. 307a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 3085e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // Negative type IDs index into FilterIds. Positive type IDs index into 3095e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // TypeInfos. The value written for a positive type ID is just the type ID 3105e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // itself. For a negative type ID, however, the value written is the 311eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // (negative) byte offset of the corresponding FilterIds entry. The byte 3125e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // offset is usually equal to the type ID (because the FilterIds entries are 3135e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // written using a variable width encoding, which outputs one byte per entry 3145e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // as long as the value written is not too large) but can differ. This kind 3155e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // of complication does not occur for positive type IDs because type infos are 316eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // output using a fixed width encoding. FilterOffsets[i] holds the byte 317eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset corresponding to FilterIds[i]. 318409914b773ffd53d53d214394d5636a76f673186Bill Wendling 319409914b773ffd53d53d214394d5636a76f673186Bill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 320eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<int, 16> FilterOffsets; 321eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.reserve(FilterIds.size()); 322eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int Offset = -1; 323409914b773ffd53d53d214394d5636a76f673186Bill Wendling 324409914b773ffd53d53d214394d5636a76f673186Bill Wendling for (std::vector<unsigned>::const_iterator 325409914b773ffd53d53d214394d5636a76f673186Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 326eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.push_back(Offset); 327af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner Offset -= MCAsmInfo::getULEB128Size(*I); 328eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 329eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 330eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.reserve(LandingPads.size()); 331eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 332eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int FirstAction = 0; 333eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeActions = 0; 3345e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *PrevLPI = 0; 335409914b773ffd53d53d214394d5636a76f673186Bill Wendling 3365cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 3375e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 3385e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *LPI = *I; 3395e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const std::vector<int> &TypeIds = LPI->TypeIds; 3405e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 341eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSiteActions = 0; 342eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 343eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared < TypeIds.size()) { 344eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAction = 0; 345eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ActionEntry *PrevAction = 0; 346eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 347eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared) { 3485e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const unsigned SizePrevIds = PrevLPI->TypeIds.size(); 349eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(Actions.size()); 350eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = &Actions.back(); 351af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) + 352af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 353eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 354eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = NumShared; j != SizePrevIds; ++j) { 355eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction -= 356af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 357eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction += -PrevAction->NextAction; 358eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = PrevAction->Previous; 359eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 360eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 361eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 362eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions. 3635e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 3645e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling int TypeID = TypeIds[J]; 3655e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 366eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 367af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); 368eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 369eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 370af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); 371eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSiteActions += SizeAction; 372eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 373a583c55864e83e470333b7be878280b10e175a6eBill Wendling ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 374eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Actions.push_back(Action); 375eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = &Actions.back(); 376eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 377eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 378eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Record the first action of the landing pad site. 379eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 380eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } // else identical - re-use previous FirstAction 381eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 382a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Information used when created the call-site table. The action record 383a583c55864e83e470333b7be878280b10e175a6eBill Wendling // field of the call site record is the offset of the first associated 384a583c55864e83e470333b7be878280b10e175a6eBill Wendling // action record, relative to the start of the actions table. This value is 385a583c55864e83e470333b7be878280b10e175a6eBill Wendling // biased by 1 (1 in dicating the start of the actions table), and 0 386a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates that there are no actions. 387eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.push_back(FirstAction); 388eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 389eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute this sites contribution to size. 390eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeActions += SizeSiteActions; 3915e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 3925e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling PrevLPI = LPI; 393eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 394eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 3955e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling return SizeActions; 3965e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling} 3975e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 398ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 399a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// has a try-range containing the call, a non-zero landing pad, and an 400ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// appropriate action. The entry for an ordinary call has a try-range 401ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// containing the call and zero for the landing pad and the action. Calls 402ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// marked 'nounwind' have no entry and must not be contained in the try-range 403ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// of any entry - they form gaps in the table. Entries must be ordered by 404ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// try-range address. 405ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException:: 406ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 407ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const RangeMapType &PadMap, 408ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 409ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<unsigned> &FirstActions) { 410eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The end label of the previous invoke or nounwind try-range. 411eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LastLabel = 0; 412eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 413eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether there is a potentially throwing instruction (currently this means 414eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // an ordinary call) between the end of the previous try-range and now. 415eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool SawPotentiallyThrowing = false; 416eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 4175cff487665097d971067cbede1598e249f673182Bill Wendling // Whether the last CallSite entry was for an invoke. 418eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool PreviousIsInvoke = false; 419eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 420eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Visit all instructions in order of address. 421eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 422eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling I != E; ++I) { 423eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 424eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MI != E; ++MI) { 425eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MI->isLabel()) { 426eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing |= MI->getDesc().isCall(); 427eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 428eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 429eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 430eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned BeginLabel = MI->getOperand(0).getImm(); 431eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && "Invalid label!"); 432eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 433eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // End of the previous try-range? 434eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (BeginLabel == LastLabel) 435eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing = false; 436eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 437eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Beginning of a new try-range? 438eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling RangeMapType::iterator L = PadMap.find(BeginLabel); 439eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (L == PadMap.end()) 440eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Nope, it was just some random label. 441eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 442eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 443a583c55864e83e470333b7be878280b10e175a6eBill Wendling const PadRange &P = L->second; 444eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 445eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 446eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Inconsistent landing pad map!"); 447eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 448a583c55864e83e470333b7be878280b10e175a6eBill Wendling // For Dwarf exception handling (SjLj handling doesn't use this). If some 449a583c55864e83e470333b7be878280b10e175a6eBill Wendling // instruction between the previous try-range and this one may throw, 450a583c55864e83e470333b7be878280b10e175a6eBill Wendling // create a call-site entry with no landing pad for the region between the 451a583c55864e83e470333b7be878280b10e175a6eBill Wendling // try-ranges. 4521b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach if (SawPotentiallyThrowing && 45333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { 454a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 }; 455eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 456eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 457eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 458eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 459eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LastLabel = LandingPad->EndLabels[P.RangeIndex]; 460eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && LastLabel && "Invalid landing pad!"); 461eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 462eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LandingPad->LandingPadLabel) { 463eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This try-range is for an invoke. 464a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { 465a583c55864e83e470333b7be878280b10e175a6eBill Wendling BeginLabel, 466a583c55864e83e470333b7be878280b10e175a6eBill Wendling LastLabel, 467a583c55864e83e470333b7be878280b10e175a6eBill Wendling LandingPad->LandingPadLabel, 468a583c55864e83e470333b7be878280b10e175a6eBill Wendling FirstActions[P.PadIndex] 469a583c55864e83e470333b7be878280b10e175a6eBill Wendling }; 470eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 4710bb61c56bcad7a738d50f705b5966be446ef06c1Jim Grosbach // Try to merge with the previous call-site. SJLJ doesn't do this 4720bb61c56bcad7a738d50f705b5966be446ef06c1Jim Grosbach if (PreviousIsInvoke && 4730bb61c56bcad7a738d50f705b5966be446ef06c1Jim Grosbach MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { 474eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &Prev = CallSites.back(); 475eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 476eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Extend the range of the previous entry. 477eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Prev.EndLabel = Site.EndLabel; 478eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 479eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 480eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 481eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 482eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Otherwise, create a new call-site. 483eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 484eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = true; 485eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 486eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Create a gap. 487eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 488eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 489eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 490eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 491eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 492eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and the end of the 493eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // function may throw, create a call-site entry with no landing pad for the 494eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // region following the try-range. 4951b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach if (SawPotentiallyThrowing && 49633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { 497a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, 0, 0, 0 }; 498eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 499eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 500ade025c65c12503aba161a4fa399fd97414abaffBill Wendling} 501ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 5020dafca90761097230f02e655fdd541f59b888315Bill Wendling/// EmitExceptionTable - Emit landing pads and actions. 5030dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 5040dafca90761097230f02e655fdd541f59b888315Bill Wendling/// The general organization of the table is complex, but the basic concepts are 5050dafca90761097230f02e655fdd541f59b888315Bill Wendling/// easy. First there is a header which describes the location and organization 5060dafca90761097230f02e655fdd541f59b888315Bill Wendling/// of the three components that follow. 507dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher/// 5080dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 1. The landing pad site information describes the range of code covered by 5090dafca90761097230f02e655fdd541f59b888315Bill Wendling/// the try. In our case it's an accumulation of the ranges covered by the 5100dafca90761097230f02e655fdd541f59b888315Bill Wendling/// invokes in the try. There is also a reference to the landing pad that 5110dafca90761097230f02e655fdd541f59b888315Bill Wendling/// handles the exception once processed. Finally an index into the actions 5120dafca90761097230f02e655fdd541f59b888315Bill Wendling/// table. 513a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 2. The action table, in our case, is composed of pairs of type IDs and next 5140dafca90761097230f02e655fdd541f59b888315Bill Wendling/// action offset. Starting with the action index from the landing pad 515a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// site, each type ID is checked for a match to the current exception. If 5160dafca90761097230f02e655fdd541f59b888315Bill Wendling/// it matches then the exception and type id are passed on to the landing 5170dafca90761097230f02e655fdd541f59b888315Bill Wendling/// pad. Otherwise the next action is looked up. This chain is terminated 5180dafca90761097230f02e655fdd541f59b888315Bill Wendling/// with a next action of zero. If no type id is found the the frame is 5190dafca90761097230f02e655fdd541f59b888315Bill Wendling/// unwound and handling continues. 520a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 3. Type ID table contains references to all the C++ typeinfo for all 5210dafca90761097230f02e655fdd541f59b888315Bill Wendling/// catches in the function. This tables is reversed indexed base 1. 522ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException::EmitExceptionTable() { 523ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 524ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 525ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 526ade025c65c12503aba161a4fa399fd97414abaffBill Wendling if (PadInfos.empty()) return; 527ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 528ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Sort the landing pads in order of their type ids. This is used to fold 529ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // duplicate actions. 530ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<const LandingPadInfo *, 64> LandingPads; 531ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.reserve(PadInfos.size()); 532ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 533ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 534ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.push_back(&PadInfos[i]); 535ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 536ade025c65c12503aba161a4fa399fd97414abaffBill Wendling std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 537ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 538ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the actions table and gather the first action index for each 539ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // landing pad site. 540ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<ActionEntry, 32> Actions; 541ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<unsigned, 64> FirstActions; 542ade025c65c12503aba161a4fa399fd97414abaffBill Wendling unsigned SizeActions = ComputeActionsTable(LandingPads, Actions, FirstActions); 543ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 544ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Invokes and nounwind calls have entries in PadMap (due to being bracketed 545ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // by try-range labels when lowered). Ordinary calls do not, so appropriate 5461b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // try-ranges for them need be deduced when using Dwarf exception handling. 547ade025c65c12503aba161a4fa399fd97414abaffBill Wendling RangeMapType PadMap; 548ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 549ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const LandingPadInfo *LandingPad = LandingPads[i]; 550ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 551ade025c65c12503aba161a4fa399fd97414abaffBill Wendling unsigned BeginLabel = LandingPad->BeginLabels[j]; 552ade025c65c12503aba161a4fa399fd97414abaffBill Wendling assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 553ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadRange P = { i, j }; 554ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadMap[BeginLabel] = P; 555ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 556ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 557ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 558ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the call-site table. 559ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<CallSiteEntry, 64> CallSites; 5608b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 561eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 562eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Final tallies. 563eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 564eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Call sites. 565eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 566eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 567eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 5681b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach unsigned SizeSites; 569bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach 57033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner bool HaveTTData = (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) 571bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 572bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach 573bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach 57433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 5758b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach SizeSites = 0; 5761b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else 5771b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach SizeSites = CallSites.size() * 5781b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach (SiteStartSize + SiteLengthSize + LandingPadSize); 5791b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 580af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action); 58133adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) 582af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeSites += MCAsmInfo::getULEB128Size(i); 5831b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 584eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Type infos. 585eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr 586eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; 587eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 588eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned TypeOffset = sizeof(int8_t) + // Call site format 589af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner MCAsmInfo::getULEB128Size(SizeSites) + // Call-site table length 590eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSites + SizeActions + SizeTypes; 591eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 592eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned TotalSize = sizeof(int8_t) + // LPStart format 593eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling sizeof(int8_t) + // TType format 594bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach (HaveTTData ? 595af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner MCAsmInfo::getULEB128Size(TypeOffset) : 0) + // TType base offset 596eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TypeOffset; 597eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 598eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAlign = (4 - TotalSize) & 3; 599eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 600eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Begin the exception table. 601d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 6026c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner Asm->OutStreamer.SwitchSection(LSDASection); 603eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(2, 0, 0, false); 604eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "GCC_except_table" << SubprogramCount << ":\n"; 605eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 606eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != SizeAlign; ++i) { 607eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(0); 608eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Padding"); 609c5800a809fd5e411de78ac1a4be633cd3e1d7840Bill Wendling } 610eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 611eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("exception", SubprogramCount); 61233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 6131b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach std::string SjLjName = "_lsda_"; 6141b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach SjLjName += MF->getFunction()->getName().str(); 6151b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach EmitLabel(SjLjName.c_str(), 0); 6161b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 617eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 618eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the header. 619639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_omit); 620639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("@LPStart format (DW_EH_PE_omit)"); 621b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling 622ade025c65c12503aba161a4fa399fd97414abaffBill Wendling#if 0 62381c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner if (TypeInfos.empty() && FilterIds.empty()) { 624ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // If there are no typeinfos or filters, there is nothing to emit, optimize 625ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // by specifying the "omit" encoding. 626639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_omit); 627639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("@TType format (DW_EH_PE_omit)"); 62881c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner } else { 629ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Okay, we have actual filters or typeinfos to emit. As such, we need to 630ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // pick a type encoding for them. We're about to emit a list of pointers to 631ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // typeinfo objects at the end of the LSDA. However, unless we're in static 632ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // mode, this reference will require a relocation by the dynamic linker. 63346b754c76bd6a720dd1dd3be248cb93a4e25d3e5Chris Lattner // 634ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Because of this, we have a couple of options: 635ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 1) If we are in -static mode, we can always use an absolute reference 636ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // from the LSDA, because the static linker will resolve it. 637ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 2) Otherwise, if the LSDA section is writable, we can output the direct 638ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // reference to the typeinfo and allow the dynamic linker to relocate 639ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // it. Since it is in a writable section, the dynamic linker won't 640ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // have a problem. 641ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 642ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we need to use some form of indirection. For example, on Darwin, 643ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we can output a statically-relocatable reference to a dyld stub. The 644ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // offset to the stub is constant, but the contents are in a section 645ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // that is updated by the dynamic linker. This is easy enough, but we 646ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // need to tell the personality function of the unwinder to indirect 647ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // through the dyld stub. 648ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 649ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // FIXME: When this is actually implemented, we'll have to emit the stubs 650ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // somewhere. This predicate should be moved to a shared location that is 651ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // in target-independent code. 652ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 653ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner if (LSDASection->isWritable() || 654ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner Asm->TM.getRelocationModel() == Reloc::Static) { 655639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(DW_EH_PE_absptr); 656639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("TType format (DW_EH_PE_absptr)"); 657ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner } else { 658ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); 659639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("TType format (DW_EH_PE_pcrel | DW_EH_PE_indirect" 660639217cb6a3948800c71c39503f8def4873a535eBill Wendling " | DW_EH_PE_sdata4)"); 661ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner } 662b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling Asm->EmitULEB128Bytes(TypeOffset); 663b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling Asm->EOL("TType base offset"); 664b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling } 665ade025c65c12503aba161a4fa399fd97414abaffBill Wendling#else 666bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach // For SjLj exceptions, if there is no TypeInfo, then we just explicitly 6671b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // say that we're omitting that bit. 6681b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // FIXME: does this apply to Dwarf also? The above #if 0 implies yes? 669bff392384ddb032c732c38ec78b91d7a25dcf467Jim Grosbach if (!HaveTTData) { 670639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_omit); 671639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("@TType format (DW_EH_PE_omit)"); 6721b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 673639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_absptr); 674639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("@TType format (DW_EH_PE_absptr)"); 6751b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitULEB128Bytes(TypeOffset); 676a583c55864e83e470333b7be878280b10e175a6eBill Wendling Asm->EOL("@TType base offset"); 6771b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 678ade025c65c12503aba161a4fa399fd97414abaffBill Wendling#endif 679b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling 6801b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // SjLj Exception handilng 68133adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 682639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 683639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("Call site format (DW_EH_PE_udata4)"); 6841b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitULEB128Bytes(SizeSites); 685a583c55864e83e470333b7be878280b10e175a6eBill Wendling Asm->EOL("Call site table length"); 6861b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 6871b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // Emit the landing pad site information. 6888b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach unsigned idx = 0; 6898b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 6908b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 6918b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const CallSiteEntry &S = *I; 692a583c55864e83e470333b7be878280b10e175a6eBill Wendling 693a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the landing pad, counted in 16-byte bundles relative to the 694a583c55864e83e470333b7be878280b10e175a6eBill Wendling // @LPStart address. 6958b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Asm->EmitULEB128Bytes(idx); 6961b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Landing pad"); 697a583c55864e83e470333b7be878280b10e175a6eBill Wendling 698a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the first associated action record, relative to the start of 699a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table. This value is biased by 1 (1 indicates the start of 700a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table), and 0 indicates that there are no actions. 7011b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitULEB128Bytes(S.Action); 7021b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Action"); 7031b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 7041b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 7051b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // DWARF Exception handling 70633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner assert(MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf); 7071b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 708a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The call-site table is a list of all call sites that may throw an 709a583c55864e83e470333b7be878280b10e175a6eBill Wendling // exception (including C++ 'throw' statements) in the procedure 710a583c55864e83e470333b7be878280b10e175a6eBill Wendling // fragment. It immediately follows the LSDA header. Each entry indicates, 711a583c55864e83e470333b7be878280b10e175a6eBill Wendling // for a given call, the first corresponding action record and corresponding 712a583c55864e83e470333b7be878280b10e175a6eBill Wendling // landing pad. 713a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 714a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The table begins with the number of bytes, stored as an LEB128 715a583c55864e83e470333b7be878280b10e175a6eBill Wendling // compressed, unsigned integer. The records immediately follow the record 716a583c55864e83e470333b7be878280b10e175a6eBill Wendling // count. They are sorted in increasing call-site address. Each record 717a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates: 718a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 719a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the call-site. 720a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the landing pad. 721a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The first action record for that call site. 722a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 723a583c55864e83e470333b7be878280b10e175a6eBill Wendling // A missing entry in the call-site table indicates that a call is not 724a583c55864e83e470333b7be878280b10e175a6eBill Wendling // supposed to throw. Such calls include: 725a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 726a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Calls to destructors within cleanup code. C++ semantics forbids these 727a583c55864e83e470333b7be878280b10e175a6eBill Wendling // calls to throw. 728a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Calls to intrinsic routines in the standard library which are known 729a583c55864e83e470333b7be878280b10e175a6eBill Wendling // not to throw (sin, memcpy, et al). 730a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 731a583c55864e83e470333b7be878280b10e175a6eBill Wendling // If the runtime does not find the call-site entry for a given call, it 732a583c55864e83e470333b7be878280b10e175a6eBill Wendling // will call `terminate()'. 733a583c55864e83e470333b7be878280b10e175a6eBill Wendling 734a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the landing pad call site table. 735639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 736639217cb6a3948800c71c39503f8def4873a535eBill Wendling Asm->EOL("Call site format (DW_EH_PE_udata4)"); 7371b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitULEB128Bytes(SizeSites); 738a583c55864e83e470333b7be878280b10e175a6eBill Wendling Asm->EOL("Call site table size"); 739eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 7401b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 7415cff487665097d971067cbede1598e249f673182Bill Wendling I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 7421b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach const CallSiteEntry &S = *I; 7431b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach const char *BeginTag; 7441b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach unsigned BeginNumber; 745eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 7461b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach if (!S.BeginLabel) { 7471b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach BeginTag = "eh_func_begin"; 7481b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach BeginNumber = SubprogramCount; 7491b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 7501b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach BeginTag = "label"; 7511b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach BeginNumber = S.BeginLabel; 7521b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 753eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 754a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the call site relative to the previous call site, counted in 755a583c55864e83e470333b7be878280b10e175a6eBill Wendling // number of 16-byte bundles. The first call site is counted relative to 756a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the start of the procedure fragment. 7571b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, 7581b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach true, true); 7591b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Region start"); 760eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 7611b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach if (!S.EndLabel) 7621b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, 7631b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach true); 7641b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach else 7651b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); 766eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 7671b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Region length"); 768eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 769a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the landing pad, counted in 16-byte bundles relative to the 770a583c55864e83e470333b7be878280b10e175a6eBill Wendling // @LPStart address. 7711b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach if (!S.PadLabel) 7721b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitInt32(0); 7731b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach else 7741b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, 7751b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach true, true); 776eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 7771b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Landing pad"); 778eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 779a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the first associated action record, relative to the start of 780a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table. This value is biased by 1 (1 indicates the start of 781a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table), and 0 indicates that there are no actions. 7821b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EmitULEB128Bytes(S.Action); 7831b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach Asm->EOL("Action"); 7841b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 785eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 786eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 787a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Action Table. 7885cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<ActionEntry>::const_iterator 7895cff487665097d971067cbede1598e249f673182Bill Wendling I = Actions.begin(), E = Actions.end(); I != E; ++I) { 7905cff487665097d971067cbede1598e249f673182Bill Wendling const ActionEntry &Action = *I; 791a583c55864e83e470333b7be878280b10e175a6eBill Wendling 792a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Type Filter 793a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 794a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Used by the runtime to match the type of the thrown exception to the 795a583c55864e83e470333b7be878280b10e175a6eBill Wendling // type of the catch clauses or the types in the exception specification. 796a583c55864e83e470333b7be878280b10e175a6eBill Wendling 797eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(Action.ValueForTypeID); 798eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TypeInfo index"); 799a583c55864e83e470333b7be878280b10e175a6eBill Wendling 800a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Action Record 801a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 802a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Self-relative signed displacement in bytes of the next action record, 803a583c55864e83e470333b7be878280b10e175a6eBill Wendling // or 0 if there is no next action record. 804a583c55864e83e470333b7be878280b10e175a6eBill Wendling 805eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(Action.NextAction); 806eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Next action"); 807eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 808eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 809a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Catch Clauses. The code for the catch clauses following the same 810a583c55864e83e470333b7be878280b10e175a6eBill Wendling // try is similar to a switch statement. The catch clause action record 811a583c55864e83e470333b7be878280b10e175a6eBill Wendling // informs the runtime about the type of a catch clause and about the 812a583c55864e83e470333b7be878280b10e175a6eBill Wendling // associated switch value. 813a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 814a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Action Record Fields: 815dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher // 816a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Filter Value 817a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Positive value, starting at 1. Index in the types table of the 818a583c55864e83e470333b7be878280b10e175a6eBill Wendling // __typeinfo for the catch-clause type. 1 is the first word preceding 819a583c55864e83e470333b7be878280b10e175a6eBill Wendling // TTBase, 2 is the second word, and so on. Used by the runtime to check 820a583c55864e83e470333b7be878280b10e175a6eBill Wendling // if the thrown exception type matches the catch-clause type. Back-end 821a583c55864e83e470333b7be878280b10e175a6eBill Wendling // generated switch statements check against this value. 822a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 823a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Next 824a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Signed offset, in bytes from the start of this field, to the next 825a583c55864e83e470333b7be878280b10e175a6eBill Wendling // chained action record, or zero if none. 826a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 827a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The order of the action records determined by the next field is the order 828a583c55864e83e470333b7be878280b10e175a6eBill Wendling // of the catch clauses as they appear in the source code, and must be kept in 829a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the same order. As a result, changing the order of the catch clause would 830a583c55864e83e470333b7be878280b10e175a6eBill Wendling // change the semantics of the program. 8315cff487665097d971067cbede1598e249f673182Bill Wendling for (std::vector<GlobalVariable *>::const_reverse_iterator 8325cff487665097d971067cbede1598e249f673182Bill Wendling I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 833a583c55864e83e470333b7be878280b10e175a6eBill Wendling const GlobalVariable *GV = *I; 834eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintRelDirective(); 835eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 836eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (GV) { 837eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling std::string GLN; 838eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << Asm->getGlobalLinkName(GV, GLN); 839eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 840eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "0"; 841eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 842eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 843eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TypeInfo"); 844eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 845eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 846a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Type Table. 8475cff487665097d971067cbede1598e249f673182Bill Wendling for (std::vector<unsigned>::const_iterator 8485cff487665097d971067cbede1598e249f673182Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 8495cff487665097d971067cbede1598e249f673182Bill Wendling unsigned TypeID = *I; 850eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(TypeID); 851eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Filter TypeInfo index"); 852eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 853eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 854eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(2, 0, 0, false); 855eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 856eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 857eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndModule - Emit all exception information that should come after the 858eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// content. 859eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndModule() { 86033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf) 8611b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach return; 862eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 863eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 864eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 865eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMovesModule || shouldEmitTableModule) { 866eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<Function *> Personalities = MMI->getPersonalities(); 867eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i < Personalities.size(); ++i) 8687ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling EmitCIE(Personalities[i], i); 869eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 870eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), 871eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling E = EHFrames.end(); I != E; ++I) 8727ccda0f2aadb601ce48f05c12cc153f3fcc554e6Bill Wendling EmitFDE(*I); 873eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 874eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 875eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 876eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 877eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 878eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 879eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// BeginFunction - Gather pre-function exception information. Assumes being 880eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// emitted immediately after the function entry point. 881eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::BeginFunction(MachineFunction *MF) { 882eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 883eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 884eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 885eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling this->MF = MF; 886eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTable = shouldEmitMoves = false; 887eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 88833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MMI && MAI->doesSupportExceptionHandling()) { 889eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Map all labels and get rid of any dead landing pads. 890eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->TidyLandingPads(); 891eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 892eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If any landing pads survive, we need an EH table. 893eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (MMI->getLandingPads().size()) 894eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTable = true; 895eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 896eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // See if we need frame move info. 897eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) 898eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitMoves = true; 899eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 900eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMoves || shouldEmitTable) 901eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Assumes in correct section after the entry point. 902eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_func_begin", ++SubprogramCount); 903eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 904eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 905eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTableModule |= shouldEmitTable; 906eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitMovesModule |= shouldEmitMoves; 907eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 908eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 909eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 910eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 911eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 912eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndFunction - Gather and emit post-function exception information. 913eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 914eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndFunction() { 915dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher if (TimePassesIsEnabled) 916eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 917eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 918eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMoves || shouldEmitTable) { 919eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_func_end", SubprogramCount); 920eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitExceptionTable(); 921eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 922eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Save EH frame information 923eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EHFrames.push_back( 924e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF), 925eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SubprogramCount, 926eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->getPersonalityIndex(), 927eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MF->getFrameInfo()->hasCalls(), 928eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling !MMI->getLandingPads().empty(), 929eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->getFrameMoves(), 930eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MF->getFunction())); 931eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 932eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 9339b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling MF = 0; 9349b35a09e7e5b1aa26588e3852fe00a42b4f383baBill Wendling 935dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher if (TimePassesIsEnabled) 936eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 937eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 938