DwarfException.cpp revision 426c2bf5cdd2173e4a33aea8cb92cf684a724f4b
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// 1028275fdf02885587156da5cb20388b22d5b96557Bill 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" 166d7337896f1bcdfbdee90c9c33371c2a373f422aChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 17eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineModuleInfo.h" 18eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineFrameInfo.h" 19fc4da0cea8a0f6c9c1483b92c2dffda217c0ba24David Greene#include "llvm/CodeGen/MachineFunction.h" 208c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCAsmInfo.h" 218c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCContext.h" 228c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCExpr.h" 2343e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling#include "llvm/MC/MCSection.h" 246c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 257a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner#include "llvm/MC/MCSymbol.h" 2645111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h" 273574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow#include "llvm/DataLayout.h" 2816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 29d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 309d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner#include "llvm/Target/TargetMachine.h" 31eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetOptions.h" 32d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetRegisterInfo.h" 336c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/Support/Dwarf.h" 345e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper#include "llvm/Support/ErrorHandling.h" 350ad9c911f5b7737ae199d703279984138553de9dChris Lattner#include "llvm/Support/FormattedStream.h" 36c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 37eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/ADT/StringExtras.h" 381f8075d7d232dd0c7b0caa81ed3ce426a13f5a66Bill Wendling#include "llvm/ADT/Twine.h" 39eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm; 40eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 4175f50725c1d7f86ee545337b155b4feac66627f6Chris LattnerDwarfException::DwarfException(AsmPrinter *A) 42d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov : Asm(A), MMI(Asm->MMI) {} 43bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 445f017e8086c4481da7f5ead2e1d66159e1cc9255Bill WendlingDwarfException::~DwarfException() {} 45bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 46eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// SharedTypeIds - How many leading type ids two landing pads have in common. 47eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 48eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *R) { 49eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 50eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 51eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 52eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Count = 0; 53eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 54eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (; Count != MinSize; ++Count) 55eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[Count] != RIds[Count]) 56eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 57eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 58eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 59eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 60eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 61eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// PadLT - Order landing pads lexicographically by type id. 62eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 63eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 64eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 65eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 66eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 67eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != MinSize; ++i) 68eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[i] != RIds[i]) 69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LIds[i] < RIds[i]; 70eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 71eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LSize < RSize; 72eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 73eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 74d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// ComputeActionsTable - Compute the actions table and gather the first action 75d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// index for each landing pad site. 76ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingunsigned DwarfException:: 77ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 78ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<ActionEntry> &Actions, 79ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<unsigned> &FirstActions) { 80a583c55864e83e470333b7be878280b10e175a6eBill Wendling 81a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The action table follows the call-site table in the LSDA. The individual 82a583c55864e83e470333b7be878280b10e175a6eBill Wendling // records are of two types: 83a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 84a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Catch clause 85a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Exception specification 86a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 87a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The two record kinds have the same format, with only small differences. 88a583c55864e83e470333b7be878280b10e175a6eBill Wendling // They are distinguished by the "switch value" field: Catch clauses 89a583c55864e83e470333b7be878280b10e175a6eBill Wendling // (TypeInfos) have strictly positive switch values, and exception 90a583c55864e83e470333b7be878280b10e175a6eBill Wendling // specifications (FilterIds) have strictly negative switch values. Value 0 91a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates a catch-all clause. 92a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 935e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // Negative type IDs index into FilterIds. Positive type IDs index into 945e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // TypeInfos. The value written for a positive type ID is just the type ID 955e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // itself. For a negative type ID, however, the value written is the 96eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // (negative) byte offset of the corresponding FilterIds entry. The byte 975e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // offset is usually equal to the type ID (because the FilterIds entries are 985e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // written using a variable width encoding, which outputs one byte per entry 995e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // as long as the value written is not too large) but can differ. This kind 1005e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // of complication does not occur for positive type IDs because type infos are 101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // output using a fixed width encoding. FilterOffsets[i] holds the byte 102eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset corresponding to FilterIds[i]. 103409914b773ffd53d53d214394d5636a76f673186Bill Wendling 104409914b773ffd53d53d214394d5636a76f673186Bill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 105eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<int, 16> FilterOffsets; 106eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.reserve(FilterIds.size()); 107eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int Offset = -1; 108409914b773ffd53d53d214394d5636a76f673186Bill Wendling 109409914b773ffd53d53d214394d5636a76f673186Bill Wendling for (std::vector<unsigned>::const_iterator 110409914b773ffd53d53d214394d5636a76f673186Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 111eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.push_back(Offset); 112af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner Offset -= MCAsmInfo::getULEB128Size(*I); 113eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 114eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 115eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.reserve(LandingPads.size()); 116eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 117eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int FirstAction = 0; 118eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeActions = 0; 1195e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *PrevLPI = 0; 120409914b773ffd53d53d214394d5636a76f673186Bill Wendling 1215cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 1225e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 1235e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *LPI = *I; 1245e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const std::vector<int> &TypeIds = LPI->TypeIds; 1259be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 126eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSiteActions = 0; 127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared < TypeIds.size()) { 129eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAction = 0; 1300a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling unsigned PrevAction = (unsigned)-1; 131eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 132eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared) { 1339be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SizePrevIds = PrevLPI->TypeIds.size(); 134eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(Actions.size()); 1350a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 1360a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling SizeAction = 1370a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) + 1380a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 140eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = NumShared; j != SizePrevIds; ++j) { 1410a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); 142eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction -= 1430a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 1440a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling SizeAction += -Actions[PrevAction].NextAction; 1450a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions[PrevAction].Previous; 146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 149eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions. 1505e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 1515e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling int TypeID = TypeIds[J]; 1525e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 153eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 154af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); 155eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 156eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 157af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); 158eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSiteActions += SizeAction; 159eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 160a583c55864e83e470333b7be878280b10e175a6eBill Wendling ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 161eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Actions.push_back(Action); 1620a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 163eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 164eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 165eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Record the first action of the landing pad site. 166eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 167eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } // else identical - re-use previous FirstAction 168eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 169a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Information used when created the call-site table. The action record 170a583c55864e83e470333b7be878280b10e175a6eBill Wendling // field of the call site record is the offset of the first associated 171a583c55864e83e470333b7be878280b10e175a6eBill Wendling // action record, relative to the start of the actions table. This value is 1720a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling // biased by 1 (1 indicating the start of the actions table), and 0 173a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates that there are no actions. 174eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.push_back(FirstAction); 175eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 176eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute this sites contribution to size. 177eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeActions += SizeSiteActions; 1785e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 1795e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling PrevLPI = LPI; 180eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 181eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1825e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling return SizeActions; 1835e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling} 1845e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 185ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// CallToNoUnwindFunction - Return `true' if this is a call to a function 186ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// marked `nounwind'. Return `false' otherwise. 187ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendlingbool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) { 1885a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng assert(MI->isCall() && "This should be a call instruction!"); 189ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 190ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool MarkedNoUnwind = false; 191ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool SawFunc = false; 192ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 193ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 194ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling const MachineOperand &MO = MI->getOperand(I); 195ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 196cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!MO.isGlobal()) continue; 197d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 19846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Function *F = dyn_cast<Function>(MO.getGlobal()); 199cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (F == 0) continue; 200cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 201cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (SawFunc) { 202cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Be conservative. If we have more than one function operand for this 203cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // call, then we can't make the assumption that it's the callee and 204cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // not a parameter to the call. 205d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 206cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // FIXME: Determine if there's a way to say that `F' is the callee or 207cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // parameter. 208cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = false; 209cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner break; 210ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 211cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 212cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = F->doesNotThrow(); 213cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner SawFunc = true; 214ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 215ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 216ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling return MarkedNoUnwind; 217ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling} 218ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 219ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 220a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// has a try-range containing the call, a non-zero landing pad, and an 221ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// appropriate action. The entry for an ordinary call has a try-range 222ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// containing the call and zero for the landing pad and the action. Calls 223ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// marked 'nounwind' have no entry and must not be contained in the try-range 224ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// of any entry - they form gaps in the table. Entries must be ordered by 225ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// try-range address. 226ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException:: 227ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 228ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const RangeMapType &PadMap, 229ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 230ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<unsigned> &FirstActions) { 231eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The end label of the previous invoke or nounwind try-range. 2321611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *LastLabel = 0; 233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 234eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether there is a potentially throwing instruction (currently this means 235eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // an ordinary call) between the end of the previous try-range and now. 236eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool SawPotentiallyThrowing = false; 237eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 2385cff487665097d971067cbede1598e249f673182Bill Wendling // Whether the last CallSite entry was for an invoke. 239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool PreviousIsInvoke = false; 240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 241eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Visit all instructions in order of address. 24284ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); 243eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling I != E; ++I) { 244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MI != E; ++MI) { 246eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MI->isLabel()) { 2475a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (MI->isCall()) 248ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI); 249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 252eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // End of the previous try-range? 2530397ada8ae1d1bc71037d8cd4a855d3ff04acbbbChris Lattner MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); 254eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (BeginLabel == LastLabel) 255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing = false; 256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 257eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Beginning of a new try-range? 25881cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin RangeMapType::const_iterator L = PadMap.find(BeginLabel); 259eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (L == PadMap.end()) 260eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Nope, it was just some random label. 261eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 262eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 263a583c55864e83e470333b7be878280b10e175a6eBill Wendling const PadRange &P = L->second; 264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Inconsistent landing pad map!"); 267eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 268a583c55864e83e470333b7be878280b10e175a6eBill Wendling // For Dwarf exception handling (SjLj handling doesn't use this). If some 269a583c55864e83e470333b7be878280b10e175a6eBill Wendling // instruction between the previous try-range and this one may throw, 270a583c55864e83e470333b7be878280b10e175a6eBill Wendling // create a call-site entry with no landing pad for the region between the 271a583c55864e83e470333b7be878280b10e175a6eBill Wendling // try-ranges. 2723965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 273a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 }; 274eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 276eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 277eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 278eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LastLabel = LandingPad->EndLabels[P.RangeIndex]; 279eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && LastLabel && "Invalid landing pad!"); 280eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 281cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!LandingPad->LandingPadLabel) { 282cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Create a gap. 283cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner PreviousIsInvoke = false; 284cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner } else { 285eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This try-range is for an invoke. 286a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { 287a583c55864e83e470333b7be878280b10e175a6eBill Wendling BeginLabel, 288a583c55864e83e470333b7be878280b10e175a6eBill Wendling LastLabel, 289a583c55864e83e470333b7be878280b10e175a6eBill Wendling LandingPad->LandingPadLabel, 290a583c55864e83e470333b7be878280b10e175a6eBill Wendling FirstActions[P.PadIndex] 291a583c55864e83e470333b7be878280b10e175a6eBill Wendling }; 292eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 29333668c0f1a7e374d4c3c53df34efbdf570e0987bJim Grosbach // Try to merge with the previous call-site. SJLJ doesn't do this 2943965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (PreviousIsInvoke && Asm->MAI->isExceptionHandlingDwarf()) { 295eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &Prev = CallSites.back(); 296eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 297eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Extend the range of the previous entry. 298eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Prev.EndLabel = Site.EndLabel; 299eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 300eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 301eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 302eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 303eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Otherwise, create a new call-site. 3043965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (Asm->MAI->isExceptionHandlingDwarf()) 305ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.push_back(Site); 306ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach else { 307ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // SjLj EH must maintain the call sites in the order assigned 308ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // to them by the SjLjPrepare pass. 309ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel); 310ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach if (CallSites.size() < SiteNo) 311ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.resize(SiteNo); 312ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites[SiteNo - 1] = Site; 313ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach } 314eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = true; 315eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 316eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 317eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 318eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 319eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and the end of the 320eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // function may throw, create a call-site entry with no landing pad for the 321eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // region following the try-range. 3223965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 323a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, 0, 0, 0 }; 324eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 325eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 326ade025c65c12503aba161a4fa399fd97414abaffBill Wendling} 327ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 3280dafca90761097230f02e655fdd541f59b888315Bill Wendling/// EmitExceptionTable - Emit landing pads and actions. 3290dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 3300dafca90761097230f02e655fdd541f59b888315Bill Wendling/// The general organization of the table is complex, but the basic concepts are 3310dafca90761097230f02e655fdd541f59b888315Bill Wendling/// easy. First there is a header which describes the location and organization 3320dafca90761097230f02e655fdd541f59b888315Bill Wendling/// of the three components that follow. 333dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher/// 3340dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 1. The landing pad site information describes the range of code covered by 3350dafca90761097230f02e655fdd541f59b888315Bill Wendling/// the try. In our case it's an accumulation of the ranges covered by the 3360dafca90761097230f02e655fdd541f59b888315Bill Wendling/// invokes in the try. There is also a reference to the landing pad that 3370dafca90761097230f02e655fdd541f59b888315Bill Wendling/// handles the exception once processed. Finally an index into the actions 3380dafca90761097230f02e655fdd541f59b888315Bill Wendling/// table. 339a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 2. The action table, in our case, is composed of pairs of type IDs and next 3400dafca90761097230f02e655fdd541f59b888315Bill Wendling/// action offset. Starting with the action index from the landing pad 341a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// site, each type ID is checked for a match to the current exception. If 3420dafca90761097230f02e655fdd541f59b888315Bill Wendling/// it matches then the exception and type id are passed on to the landing 3430dafca90761097230f02e655fdd541f59b888315Bill Wendling/// pad. Otherwise the next action is looked up. This chain is terminated 34428275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// with a next action of zero. If no type id is found then the frame is 3450dafca90761097230f02e655fdd541f59b888315Bill Wendling/// unwound and handling continues. 346a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 3. Type ID table contains references to all the C++ typeinfo for all 34728275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// catches in the function. This tables is reverse indexed base 1. 348ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException::EmitExceptionTable() { 34946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 350ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 351ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 352ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 353ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Sort the landing pads in order of their type ids. This is used to fold 354ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // duplicate actions. 355ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<const LandingPadInfo *, 64> LandingPads; 356ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.reserve(PadInfos.size()); 357ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 358ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 359ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.push_back(&PadInfos[i]); 360ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 361ade025c65c12503aba161a4fa399fd97414abaffBill Wendling std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 362ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 363ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the actions table and gather the first action index for each 364ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // landing pad site. 365ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<ActionEntry, 32> Actions; 366ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<unsigned, 64> FirstActions; 3670a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions); 368ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 369ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Invokes and nounwind calls have entries in PadMap (due to being bracketed 370ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // by try-range labels when lowered). Ordinary calls do not, so appropriate 37128275fdf02885587156da5cb20388b22d5b96557Bill Wendling // try-ranges for them need be deduced when using DWARF exception handling. 372ade025c65c12503aba161a4fa399fd97414abaffBill Wendling RangeMapType PadMap; 373ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 374ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const LandingPadInfo *LandingPad = LandingPads[i]; 375ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 3761611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; 377ade025c65c12503aba161a4fa399fd97414abaffBill Wendling assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 378ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadRange P = { i, j }; 379ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadMap[BeginLabel] = P; 380ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 381ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 382ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 383ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the call-site table. 384ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<CallSiteEntry, 64> CallSites; 3858b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 386eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 387eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Final tallies. 388eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 389eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Call sites. 39084ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; 391d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 392d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 3933dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned CallSiteTableLength; 394d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 3953dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength = 0; 3969be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner else { 3979be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4 3989be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4 3999be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4 400d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov CallSiteTableLength = 4019be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); 4029be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner } 403d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 4041b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 4053dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action); 406d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 4073dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength += MCAsmInfo::getULEB128Size(i); 4081b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 409d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 410eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Type infos. 411d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 4129184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov unsigned TTypeEncoding; 413a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned TypeFormatSize; 414eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 41543e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling if (!HaveTTData) { 41628275fdf02885587156da5cb20388b22d5b96557Bill Wendling // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say 41728275fdf02885587156da5cb20388b22d5b96557Bill Wendling // that we're omitting that bit. 4189184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = dwarf::DW_EH_PE_omit; 41984ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner // dwarf::DW_EH_PE_absptr 420426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth TypeFormatSize = Asm->getDataLayout().getPointerSize(); 42181c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner } else { 422ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Okay, we have actual filters or typeinfos to emit. As such, we need to 423ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // pick a type encoding for them. We're about to emit a list of pointers to 424ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // typeinfo objects at the end of the LSDA. However, unless we're in static 425ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // mode, this reference will require a relocation by the dynamic linker. 42646b754c76bd6a720dd1dd3be248cb93a4e25d3e5Chris Lattner // 427ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Because of this, we have a couple of options: 428d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 429ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 1) If we are in -static mode, we can always use an absolute reference 430ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // from the LSDA, because the static linker will resolve it. 431d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 432ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 2) Otherwise, if the LSDA section is writable, we can output the direct 433ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // reference to the typeinfo and allow the dynamic linker to relocate 434ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // it. Since it is in a writable section, the dynamic linker won't 435ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // have a problem. 436d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 437ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 438ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we need to use some form of indirection. For example, on Darwin, 439ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we can output a statically-relocatable reference to a dyld stub. The 440ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // offset to the stub is constant, but the contents are in a section 441ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // that is updated by the dynamic linker. This is easy enough, but we 442ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // need to tell the personality function of the unwinder to indirect 443ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // through the dyld stub. 444ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 44543e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling // FIXME: When (3) is actually implemented, we'll have to emit the stubs 446ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // somewhere. This predicate should be moved to a shared location that is 447ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // in target-independent code. 448ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 4499184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); 450d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding); 451fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling } 452fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling 453fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling // Begin the exception table. 454ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // Sometimes we want not to emit the data into separate section (e.g. ARM 455ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // EHABI). In this case LSDASection will be NULL. 456d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov if (LSDASection) 457d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov Asm->OutStreamer.SwitchSection(LSDASection); 458059ea138a6e4180de0d70390f7147dac66614517Chris Lattner Asm->EmitAlignment(2); 45943e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling 4603dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA. 461d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov MCSymbol *GCCETSym = 462974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+ 46384ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Twine(Asm->getFunctionNumber())); 464974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner Asm->OutStreamer.EmitLabel(GCCETSym); 46584ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception", 46684ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->getFunctionNumber())); 4673dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling 468974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner if (IsSJLJ) 469c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_", 470c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Asm->getFunctionNumber())); 4713dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling 4723dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA header. 473ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); 474ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(TTypeEncoding, "@TType"); 475a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 476a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // The type infos need to be aligned. GCC does this by inserting padding just 477a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // before the type infos. However, this changes the size of the exception 478a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table, so you need to take this into account when you output the exception 479a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table size. However, the size is output using a variable length encoding. 480a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // So by increasing the size by inserting padding, you may increase the number 481a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // of bytes used for writing the size. If it increases, say by one byte, then 482a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // you now need to output one less byte of padding to get the type infos 4833dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // aligned. However this decreases the size of the exception table. This 484a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // changes the value you have to output for the exception table size. Due to 485a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // the variable length encoding, the number of bytes used for writing the 486a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // length may decrease. If so, you then have to increase the amount of 487a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // padding. And so on. If you look carefully at the GCC code you will see that 488a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // it indeed does this in a loop, going on and on until the values stabilize. 489a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // We chose another solution: don't output padding inside the table like GCC 490a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // does, instead output it before the table. 491a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; 4923dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned CallSiteTableLengthSize = 4933dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling MCAsmInfo::getULEB128Size(CallSiteTableLength); 4943dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TTypeBaseOffset = 4953dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // Call site format 4963dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLengthSize + // Call site table length size 4973dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength + // Call site table length 4983dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeActions + // Actions size 4993dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeTypes; 5003dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset); 5013dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TotalSize = 5023dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // LPStart format 5033dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // TType format 5043dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size 5053dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling TTypeBaseOffset; // TType base offset 506a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeAlign = (4 - TotalSize) & 3; 507a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 50886f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling if (HaveTTData) { 5096507eca124883c90cc300c1ff344f79a8b4181a5Bill Wendling // Account for any extra padding that will be added to the call site table 510f7e90ae2057adcf6fa4b023110611084f28fd6c1Bill Wendling // length. 5117e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); 5121869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling SizeAlign = 0; 51386f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling } 514b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling 5158fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); 5168fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 51728275fdf02885587156da5cb20388b22d5b96557Bill Wendling // SjLj Exception handling 518d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) { 519ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 5201869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 5211869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 5227e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 5231b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 5241b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // Emit the landing pad site information. 5258b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach unsigned idx = 0; 5268b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5278b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 5288b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const CallSiteEntry &S = *I; 529a583c55864e83e470333b7be878280b10e175a6eBill Wendling 530f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the landing pad, counted in 16-byte bundles relative to the 531f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // @LPStart address. 5320c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (VerboseAsm) { 53347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Call Site " + Twine(idx) + " <<"); 53447b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" On exception at call site "+Twine(idx)); 535f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 536f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitULEB128(idx); 5370c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling 538f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the first associated action record, relative to the start of 539f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table. This value is biased by 1 (1 indicates the start of 540f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table), and 0 indicates that there are no actions. 541f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 5420c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (S.Action == 0) 5430c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling Asm->OutStreamer.AddComment(" Action: cleanup"); 5440c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling else 54547b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Action: " + 54647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine((S.Action - 1) / 2 + 1)); 5470c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling } 5480c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling Asm->EmitULEB128(S.Action); 5491b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 5501b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 5511b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // DWARF Exception handling 5523965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov assert(Asm->MAI->isExceptionHandlingDwarf()); 5531b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 554a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The call-site table is a list of all call sites that may throw an 555a583c55864e83e470333b7be878280b10e175a6eBill Wendling // exception (including C++ 'throw' statements) in the procedure 556a583c55864e83e470333b7be878280b10e175a6eBill Wendling // fragment. It immediately follows the LSDA header. Each entry indicates, 557a583c55864e83e470333b7be878280b10e175a6eBill Wendling // for a given call, the first corresponding action record and corresponding 558a583c55864e83e470333b7be878280b10e175a6eBill Wendling // landing pad. 559a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 560a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The table begins with the number of bytes, stored as an LEB128 561a583c55864e83e470333b7be878280b10e175a6eBill Wendling // compressed, unsigned integer. The records immediately follow the record 562a583c55864e83e470333b7be878280b10e175a6eBill Wendling // count. They are sorted in increasing call-site address. Each record 563a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates: 564a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 565a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the call-site. 566a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the landing pad. 567a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The first action record for that call site. 568a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 569a583c55864e83e470333b7be878280b10e175a6eBill Wendling // A missing entry in the call-site table indicates that a call is not 57028275fdf02885587156da5cb20388b22d5b96557Bill Wendling // supposed to throw. 571a583c55864e83e470333b7be878280b10e175a6eBill Wendling 572a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the landing pad call site table. 573ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 5741869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 5751869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 5767e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 577eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 5788fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned Entry = 0; 5791b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5805cff487665097d971067cbede1598e249f673182Bill Wendling I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 5811b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach const CallSiteEntry &S = *I; 582d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 583c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner MCSymbol *EHFuncBeginSym = 58484ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); 585d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5861611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *BeginLabel = S.BeginLabel; 5871611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner if (BeginLabel == 0) 5881611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner BeginLabel = EHFuncBeginSym; 5891611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *EndLabel = S.EndLabel; 5901611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner if (EndLabel == 0) 59184ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); 592d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5938fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 594a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the call site relative to the previous call site, counted in 595a583c55864e83e470333b7be878280b10e175a6eBill Wendling // number of 16-byte bundles. The first call site is counted relative to 596a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the start of the procedure fragment. 597f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 59847b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Call Site " + Twine(++Entry) + " <<"); 599f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); 600f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 601f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(Twine(" Call between ") + 602f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin BeginLabel->getName() + " and " + 603f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin EndLabel->getName()); 604a64371828e27dcc30d38e7246dda0f35c1dfde40Chris Lattner Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); 605eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 606a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the landing pad, counted in 16-byte bundles relative to the 607a583c55864e83e470333b7be878280b10e175a6eBill Wendling // @LPStart address. 608f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (!S.PadLabel) { 609f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 610f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(" has no landing pad"); 611bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 612f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } else { 613f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 614f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(Twine(" jumps to ") + 615f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin S.PadLabel->getName()); 616f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4); 617f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 618eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 619a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the first associated action record, relative to the start of 620a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table. This value is biased by 1 (1 indicates the start of 621a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table), and 0 indicates that there are no actions. 622f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 623f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (S.Action == 0) 624f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(" On action: cleanup"); 625f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin else 62647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" On action: " + 62747b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine((S.Action - 1) / 2 + 1)); 628f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 6298fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(S.Action); 6301b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 631eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 632eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 633a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Action Table. 6348fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling int Entry = 0; 6355cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<ActionEntry>::const_iterator 6365cff487665097d971067cbede1598e249f673182Bill Wendling I = Actions.begin(), E = Actions.end(); I != E; ++I) { 6375cff487665097d971067cbede1598e249f673182Bill Wendling const ActionEntry &Action = *I; 6388fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 6398fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 6408fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling // Emit comments that decode the action table. 64147b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Action Record " + Twine(++Entry) + " <<"); 642f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 643f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin 644f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Type Filter 645f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 646f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Used by the runtime to match the type of the thrown exception to the 647f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // type of the catch clauses or the types in the exception specification. 648f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 64942e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands if (Action.ValueForTypeID > 0) 65047b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Catch TypeInfo " + 65147b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine(Action.ValueForTypeID)); 65242e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else if (Action.ValueForTypeID < 0) 65347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Filter TypeInfo " + 65447b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine(Action.ValueForTypeID)); 65542e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else 65642e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands Asm->OutStreamer.AddComment(" Cleanup"); 657f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 658f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitSLEB128(Action.ValueForTypeID); 6598fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 660f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Action Record 661f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 662f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Self-relative signed displacement in bytes of the next action record, 663f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // or 0 if there is no next action record. 664f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 6658fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (Action.NextAction == 0) { 6668fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(" No further actions"); 6678fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } else { 6688fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned NextAction = Entry + (Action.NextAction + 1) / 2; 66947b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Continue to action "+Twine(NextAction)); 6708fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6718fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6728fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitSLEB128(Action.NextAction); 673eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 674eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 67548dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Catch TypeInfos. 6768fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !TypeInfos.empty()) { 6778fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); 678233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner Asm->OutStreamer.AddBlankLine(); 6798fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = TypeInfos.size(); 680233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 6818fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 68246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman for (std::vector<const GlobalVariable *>::const_reverse_iterator 68301c69374b508bad0ee71cd3c49414a325238e29aBill Wendling I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 684fb7634f1c7a804829fc55e3711ba62c8ade818d0Bill Wendling const GlobalVariable *GV = *I; 6858fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) 68647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); 68790e4af7b9d479a6766924cfa375474a870fe4a0dChris Lattner if (GV) 688d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner Asm->EmitReference(GV, TTypeEncoding); 68990e4af7b9d479a6766924cfa375474a870fe4a0dChris Lattner else 690d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding), 691d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner 0); 692eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 693eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 69448dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Exception Specifications. 6958fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !FilterIds.empty()) { 6968fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); 697233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner Asm->OutStreamer.AddBlankLine(); 6988fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = 0; 699233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 7005cff487665097d971067cbede1598e249f673182Bill Wendling for (std::vector<unsigned>::const_iterator 7015cff487665097d971067cbede1598e249f673182Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 7025cff487665097d971067cbede1598e249f673182Bill Wendling unsigned TypeID = *I; 7038fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 7048fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling --Entry; 7058fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (TypeID != 0) 70647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry)); 7078fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 7088fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 7098fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(TypeID); 710eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 711eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 712059ea138a6e4180de0d70390f7147dac66614517Chris Lattner Asm->EmitAlignment(2); 713eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 714eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 715eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndModule - Emit all exception information that should come after the 716eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// content. 717eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndModule() { 7185e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 719eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 720eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 72128275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// BeginFunction - Gather pre-function exception information. Assumes it's 72228275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// being emitted immediately after the function entry point. 723eec791afb127ed634ed5d1cdd2e6c47b3b70174cChris Lattnervoid DwarfException::BeginFunction(const MachineFunction *MF) { 7245e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 725eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 726eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 727eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndFunction - Gather and emit post-function exception information. 728eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 729eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndFunction() { 7305e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 731eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 732