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" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h" 186d7337896f1bcdfbdee90c9c33371c2a373f422aChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 19eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineFrameInfo.h" 20fc4da0cea8a0f6c9c1483b92c2dffda217c0ba24David Greene#include "llvm/CodeGen/MachineFunction.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineModuleInfo.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 248c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCAsmInfo.h" 258c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCContext.h" 268c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCExpr.h" 2743e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling#include "llvm/MC/MCSection.h" 286c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 297a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner#include "llvm/MC/MCSymbol.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Dwarf.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h" 32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/FormattedStream.h" 3345111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h" 3416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 35d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 36eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetOptions.h" 37d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetRegisterInfo.h" 38eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm; 39eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 4075f50725c1d7f86ee545337b155b4feac66627f6Chris LattnerDwarfException::DwarfException(AsmPrinter *A) 41d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov : Asm(A), MMI(Asm->MMI) {} 42bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 435f017e8086c4481da7f5ead2e1d66159e1cc9255Bill WendlingDwarfException::~DwarfException() {} 44bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 45eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// SharedTypeIds - How many leading type ids two landing pads have in common. 46eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 47eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *R) { 48eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 49eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 50eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 51eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Count = 0; 52eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 53eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (; Count != MinSize; ++Count) 54eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[Count] != RIds[Count]) 55eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 56eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 57eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 58eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 59eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 60eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// PadLT - Order landing pads lexicographically by type id. 61eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 62eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 63eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 64eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 65eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 66eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != MinSize; ++i) 67eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[i] != RIds[i]) 68eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LIds[i] < RIds[i]; 69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 70eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LSize < RSize; 71eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 72eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 73d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// ComputeActionsTable - Compute the actions table and gather the first action 74d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// index for each landing pad site. 75ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingunsigned DwarfException:: 76ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 77ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<ActionEntry> &Actions, 78ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<unsigned> &FirstActions) { 79a583c55864e83e470333b7be878280b10e175a6eBill Wendling 80a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The action table follows the call-site table in the LSDA. The individual 81a583c55864e83e470333b7be878280b10e175a6eBill Wendling // records are of two types: 82a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 83a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Catch clause 84a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Exception specification 85a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 86a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The two record kinds have the same format, with only small differences. 87a583c55864e83e470333b7be878280b10e175a6eBill Wendling // They are distinguished by the "switch value" field: Catch clauses 88a583c55864e83e470333b7be878280b10e175a6eBill Wendling // (TypeInfos) have strictly positive switch values, and exception 89a583c55864e83e470333b7be878280b10e175a6eBill Wendling // specifications (FilterIds) have strictly negative switch values. Value 0 90a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates a catch-all clause. 91a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 925e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // Negative type IDs index into FilterIds. Positive type IDs index into 935e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // TypeInfos. The value written for a positive type ID is just the type ID 945e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // itself. For a negative type ID, however, the value written is the 95eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // (negative) byte offset of the corresponding FilterIds entry. The byte 965e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // offset is usually equal to the type ID (because the FilterIds entries are 975e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // written using a variable width encoding, which outputs one byte per entry 985e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // as long as the value written is not too large) but can differ. This kind 995e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // of complication does not occur for positive type IDs because type infos are 100eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // output using a fixed width encoding. FilterOffsets[i] holds the byte 101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset corresponding to FilterIds[i]. 102409914b773ffd53d53d214394d5636a76f673186Bill Wendling 103409914b773ffd53d53d214394d5636a76f673186Bill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 104eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<int, 16> FilterOffsets; 105eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.reserve(FilterIds.size()); 106eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int Offset = -1; 107409914b773ffd53d53d214394d5636a76f673186Bill Wendling 108409914b773ffd53d53d214394d5636a76f673186Bill Wendling for (std::vector<unsigned>::const_iterator 109409914b773ffd53d53d214394d5636a76f673186Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 110eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.push_back(Offset); 111af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner Offset -= MCAsmInfo::getULEB128Size(*I); 112eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 113eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 114eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.reserve(LandingPads.size()); 115eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 116eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int FirstAction = 0; 117eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeActions = 0; 1185e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *PrevLPI = 0; 119409914b773ffd53d53d214394d5636a76f673186Bill Wendling 1205cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 1215e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 1225e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *LPI = *I; 1235e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const std::vector<int> &TypeIds = LPI->TypeIds; 1249be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 125eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSiteActions = 0; 126eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared < TypeIds.size()) { 128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAction = 0; 1290a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling unsigned PrevAction = (unsigned)-1; 130eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 131eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared) { 1329be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SizePrevIds = PrevLPI->TypeIds.size(); 133eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(Actions.size()); 1340a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 1350a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling SizeAction = 1360a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) + 1370a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 138eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = NumShared; j != SizePrevIds; ++j) { 1400a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); 141eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction -= 1420a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 1430a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling SizeAction += -Actions[PrevAction].NextAction; 1440a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions[PrevAction].Previous; 145eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions. 1495e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 1505e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling int TypeID = TypeIds[J]; 1515e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 152eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 153af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); 154eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 155eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 156af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); 157eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSiteActions += SizeAction; 158eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 159a583c55864e83e470333b7be878280b10e175a6eBill Wendling ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 160eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Actions.push_back(Action); 1610a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 162eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 163eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 164eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Record the first action of the landing pad site. 165eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 166eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } // else identical - re-use previous FirstAction 167eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 168a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Information used when created the call-site table. The action record 169a583c55864e83e470333b7be878280b10e175a6eBill Wendling // field of the call site record is the offset of the first associated 170a583c55864e83e470333b7be878280b10e175a6eBill Wendling // action record, relative to the start of the actions table. This value is 1710a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling // biased by 1 (1 indicating the start of the actions table), and 0 172a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates that there are no actions. 173eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.push_back(FirstAction); 174eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 175eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute this sites contribution to size. 176eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeActions += SizeSiteActions; 1775e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 1785e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling PrevLPI = LPI; 179eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 180eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1815e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling return SizeActions; 1825e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling} 1835e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 184ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// CallToNoUnwindFunction - Return `true' if this is a call to a function 185ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// marked `nounwind'. Return `false' otherwise. 186ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendlingbool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) { 1875a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng assert(MI->isCall() && "This should be a call instruction!"); 188ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 189ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool MarkedNoUnwind = false; 190ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool SawFunc = false; 191ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 192ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 193ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling const MachineOperand &MO = MI->getOperand(I); 194ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 195cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!MO.isGlobal()) continue; 196d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 19746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Function *F = dyn_cast<Function>(MO.getGlobal()); 198cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (F == 0) continue; 199cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 200cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (SawFunc) { 201cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Be conservative. If we have more than one function operand for this 202cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // call, then we can't make the assumption that it's the callee and 203cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // not a parameter to the call. 204d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 205cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // FIXME: Determine if there's a way to say that `F' is the callee or 206cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // parameter. 207cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = false; 208cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner break; 209ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 210cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 211cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = F->doesNotThrow(); 212cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner SawFunc = true; 213ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 214ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 215ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling return MarkedNoUnwind; 216ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling} 217ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 218ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 219a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// has a try-range containing the call, a non-zero landing pad, and an 220ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// appropriate action. The entry for an ordinary call has a try-range 221ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// containing the call and zero for the landing pad and the action. Calls 222ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// marked 'nounwind' have no entry and must not be contained in the try-range 223ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// of any entry - they form gaps in the table. Entries must be ordered by 224ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// try-range address. 225ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException:: 226ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 227ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const RangeMapType &PadMap, 228ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 229ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const SmallVectorImpl<unsigned> &FirstActions) { 230eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The end label of the previous invoke or nounwind try-range. 2311611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *LastLabel = 0; 232eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether there is a potentially throwing instruction (currently this means 234eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // an ordinary call) between the end of the previous try-range and now. 235eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool SawPotentiallyThrowing = false; 236eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 2375cff487665097d971067cbede1598e249f673182Bill Wendling // Whether the last CallSite entry was for an invoke. 238eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool PreviousIsInvoke = false; 239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Visit all instructions in order of address. 24184ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); 242eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling I != E; ++I) { 243eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MI != E; ++MI) { 245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MI->isLabel()) { 2465a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (MI->isCall()) 247ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI); 248eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // End of the previous try-range? 2520397ada8ae1d1bc71037d8cd4a855d3ff04acbbbChris Lattner MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); 253eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (BeginLabel == LastLabel) 254eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing = false; 255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Beginning of a new try-range? 25781cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin RangeMapType::const_iterator L = PadMap.find(BeginLabel); 258eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (L == PadMap.end()) 259eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Nope, it was just some random label. 260eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 261eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 262a583c55864e83e470333b7be878280b10e175a6eBill Wendling const PadRange &P = L->second; 263eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Inconsistent landing pad map!"); 266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 267a583c55864e83e470333b7be878280b10e175a6eBill Wendling // For Dwarf exception handling (SjLj handling doesn't use this). If some 268a583c55864e83e470333b7be878280b10e175a6eBill Wendling // instruction between the previous try-range and this one may throw, 269a583c55864e83e470333b7be878280b10e175a6eBill Wendling // create a call-site entry with no landing pad for the region between the 270a583c55864e83e470333b7be878280b10e175a6eBill Wendling // try-ranges. 2713965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 272a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 }; 273eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 274eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 276eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 277eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LastLabel = LandingPad->EndLabels[P.RangeIndex]; 278eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && LastLabel && "Invalid landing pad!"); 279eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 280cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!LandingPad->LandingPadLabel) { 281cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Create a gap. 282cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner PreviousIsInvoke = false; 283cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner } else { 284eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This try-range is for an invoke. 285a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { 286a583c55864e83e470333b7be878280b10e175a6eBill Wendling BeginLabel, 287a583c55864e83e470333b7be878280b10e175a6eBill Wendling LastLabel, 288a583c55864e83e470333b7be878280b10e175a6eBill Wendling LandingPad->LandingPadLabel, 289a583c55864e83e470333b7be878280b10e175a6eBill Wendling FirstActions[P.PadIndex] 290a583c55864e83e470333b7be878280b10e175a6eBill Wendling }; 291eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 29233668c0f1a7e374d4c3c53df34efbdf570e0987bJim Grosbach // Try to merge with the previous call-site. SJLJ doesn't do this 2933965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (PreviousIsInvoke && Asm->MAI->isExceptionHandlingDwarf()) { 294eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &Prev = CallSites.back(); 295eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 296eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Extend the range of the previous entry. 297eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Prev.EndLabel = Site.EndLabel; 298eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 299eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 300eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 301eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 302eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Otherwise, create a new call-site. 3033965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (Asm->MAI->isExceptionHandlingDwarf()) 304ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.push_back(Site); 305ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach else { 306ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // SjLj EH must maintain the call sites in the order assigned 307ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // to them by the SjLjPrepare pass. 308ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel); 309ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach if (CallSites.size() < SiteNo) 310ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.resize(SiteNo); 311ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites[SiteNo - 1] = Site; 312ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach } 313eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = true; 314eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 315eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 316eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 317eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 318eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and the end of the 319eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // function may throw, create a call-site entry with no landing pad for the 320eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // region following the try-range. 3213965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 322a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { LastLabel, 0, 0, 0 }; 323eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 324eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 325ade025c65c12503aba161a4fa399fd97414abaffBill Wendling} 326ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 3270dafca90761097230f02e655fdd541f59b888315Bill Wendling/// EmitExceptionTable - Emit landing pads and actions. 3280dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 3290dafca90761097230f02e655fdd541f59b888315Bill Wendling/// The general organization of the table is complex, but the basic concepts are 3300dafca90761097230f02e655fdd541f59b888315Bill Wendling/// easy. First there is a header which describes the location and organization 3310dafca90761097230f02e655fdd541f59b888315Bill Wendling/// of the three components that follow. 332dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher/// 3330dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 1. The landing pad site information describes the range of code covered by 3340dafca90761097230f02e655fdd541f59b888315Bill Wendling/// the try. In our case it's an accumulation of the ranges covered by the 3350dafca90761097230f02e655fdd541f59b888315Bill Wendling/// invokes in the try. There is also a reference to the landing pad that 3360dafca90761097230f02e655fdd541f59b888315Bill Wendling/// handles the exception once processed. Finally an index into the actions 3370dafca90761097230f02e655fdd541f59b888315Bill Wendling/// table. 338a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 2. The action table, in our case, is composed of pairs of type IDs and next 3390dafca90761097230f02e655fdd541f59b888315Bill Wendling/// action offset. Starting with the action index from the landing pad 340a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// site, each type ID is checked for a match to the current exception. If 3410dafca90761097230f02e655fdd541f59b888315Bill Wendling/// it matches then the exception and type id are passed on to the landing 3420dafca90761097230f02e655fdd541f59b888315Bill Wendling/// pad. Otherwise the next action is looked up. This chain is terminated 34328275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// with a next action of zero. If no type id is found then the frame is 3440dafca90761097230f02e655fdd541f59b888315Bill Wendling/// unwound and handling continues. 345a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 3. Type ID table contains references to all the C++ typeinfo for all 34628275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// catches in the function. This tables is reverse indexed base 1. 347ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException::EmitExceptionTable() { 34846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 349ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 350ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 351ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 352ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Sort the landing pads in order of their type ids. This is used to fold 353ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // duplicate actions. 354ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<const LandingPadInfo *, 64> LandingPads; 355ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.reserve(PadInfos.size()); 356ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 357ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 358ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.push_back(&PadInfos[i]); 359ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 360ade025c65c12503aba161a4fa399fd97414abaffBill Wendling std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 361ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 362ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the actions table and gather the first action index for each 363ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // landing pad site. 364ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<ActionEntry, 32> Actions; 365ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<unsigned, 64> FirstActions; 3660a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions); 367ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 368ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Invokes and nounwind calls have entries in PadMap (due to being bracketed 369ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // by try-range labels when lowered). Ordinary calls do not, so appropriate 37028275fdf02885587156da5cb20388b22d5b96557Bill Wendling // try-ranges for them need be deduced when using DWARF exception handling. 371ade025c65c12503aba161a4fa399fd97414abaffBill Wendling RangeMapType PadMap; 372ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 373ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const LandingPadInfo *LandingPad = LandingPads[i]; 374ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 3751611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; 376ade025c65c12503aba161a4fa399fd97414abaffBill Wendling assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 377ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadRange P = { i, j }; 378ade025c65c12503aba161a4fa399fd97414abaffBill Wendling PadMap[BeginLabel] = P; 379ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 380ade025c65c12503aba161a4fa399fd97414abaffBill Wendling } 381ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 382ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the call-site table. 383ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<CallSiteEntry, 64> CallSites; 3848b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 385eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 386eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Final tallies. 387eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 388eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Call sites. 38984ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; 390d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 391d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 3923dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned CallSiteTableLength; 393d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 3943dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength = 0; 3959be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner else { 3969be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4 3979be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4 3989be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4 399d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov CallSiteTableLength = 4009be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); 4019be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner } 402d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 4031b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 4043dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action); 405d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 4063dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength += MCAsmInfo::getULEB128Size(i); 4071b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 408d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 409eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Type infos. 410d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 4119184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov unsigned TTypeEncoding; 412a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned TypeFormatSize; 413eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 41443e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling if (!HaveTTData) { 41528275fdf02885587156da5cb20388b22d5b96557Bill Wendling // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say 41628275fdf02885587156da5cb20388b22d5b96557Bill Wendling // that we're omitting that bit. 4179184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = dwarf::DW_EH_PE_omit; 41884ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner // dwarf::DW_EH_PE_absptr 419426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth TypeFormatSize = Asm->getDataLayout().getPointerSize(); 42081c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner } else { 421ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Okay, we have actual filters or typeinfos to emit. As such, we need to 422ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // pick a type encoding for them. We're about to emit a list of pointers to 423ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // typeinfo objects at the end of the LSDA. However, unless we're in static 424ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // mode, this reference will require a relocation by the dynamic linker. 42546b754c76bd6a720dd1dd3be248cb93a4e25d3e5Chris Lattner // 426ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Because of this, we have a couple of options: 427d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 428ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 1) If we are in -static mode, we can always use an absolute reference 429ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // from the LSDA, because the static linker will resolve it. 430d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 431ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 2) Otherwise, if the LSDA section is writable, we can output the direct 432ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // reference to the typeinfo and allow the dynamic linker to relocate 433ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // it. Since it is in a writable section, the dynamic linker won't 434ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // have a problem. 435d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 436ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 437ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we need to use some form of indirection. For example, on Darwin, 438ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we can output a statically-relocatable reference to a dyld stub. The 439ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // offset to the stub is constant, but the contents are in a section 440ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // that is updated by the dynamic linker. This is easy enough, but we 441ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // need to tell the personality function of the unwinder to indirect 442ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // through the dyld stub. 443ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 44443e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling // FIXME: When (3) is actually implemented, we'll have to emit the stubs 445ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // somewhere. This predicate should be moved to a shared location that is 446ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // in target-independent code. 447ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 4489184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); 449d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding); 450fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling } 451fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling 452fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling // Begin the exception table. 453ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // Sometimes we want not to emit the data into separate section (e.g. ARM 454ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // EHABI). In this case LSDASection will be NULL. 455d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov if (LSDASection) 456d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov Asm->OutStreamer.SwitchSection(LSDASection); 457059ea138a6e4180de0d70390f7147dac66614517Chris Lattner Asm->EmitAlignment(2); 45843e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling 4593dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA. 460d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov MCSymbol *GCCETSym = 461974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+ 46284ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Twine(Asm->getFunctionNumber())); 463974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner Asm->OutStreamer.EmitLabel(GCCETSym); 46484ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception", 46584ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->getFunctionNumber())); 4663dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling 467974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner if (IsSJLJ) 468c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_", 469c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Asm->getFunctionNumber())); 4703dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling 4713dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA header. 472ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); 473ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(TTypeEncoding, "@TType"); 474a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 475a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // The type infos need to be aligned. GCC does this by inserting padding just 476a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // before the type infos. However, this changes the size of the exception 477a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table, so you need to take this into account when you output the exception 478a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table size. However, the size is output using a variable length encoding. 479a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // So by increasing the size by inserting padding, you may increase the number 480a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // of bytes used for writing the size. If it increases, say by one byte, then 481a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // you now need to output one less byte of padding to get the type infos 4823dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // aligned. However this decreases the size of the exception table. This 483a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // changes the value you have to output for the exception table size. Due to 484a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // the variable length encoding, the number of bytes used for writing the 485a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // length may decrease. If so, you then have to increase the amount of 486a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // padding. And so on. If you look carefully at the GCC code you will see that 487a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // it indeed does this in a loop, going on and on until the values stabilize. 488a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // We chose another solution: don't output padding inside the table like GCC 489a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // does, instead output it before the table. 490a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; 4913dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned CallSiteTableLengthSize = 4923dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling MCAsmInfo::getULEB128Size(CallSiteTableLength); 4933dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TTypeBaseOffset = 4943dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // Call site format 4953dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLengthSize + // Call site table length size 4963dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength + // Call site table length 4973dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeActions + // Actions size 4983dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeTypes; 4993dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset); 5003dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TotalSize = 5013dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // LPStart format 5023dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // TType format 5033dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size 5043dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling TTypeBaseOffset; // TType base offset 505a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeAlign = (4 - TotalSize) & 3; 506a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 50786f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling if (HaveTTData) { 5086507eca124883c90cc300c1ff344f79a8b4181a5Bill Wendling // Account for any extra padding that will be added to the call site table 509f7e90ae2057adcf6fa4b023110611084f28fd6c1Bill Wendling // length. 5107e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); 5111869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling SizeAlign = 0; 51286f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling } 513b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling 5148fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); 5158fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 51628275fdf02885587156da5cb20388b22d5b96557Bill Wendling // SjLj Exception handling 517d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) { 518ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 5191869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 5201869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 5217e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 5221b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 5231b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // Emit the landing pad site information. 5248b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach unsigned idx = 0; 5258b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5268b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 5278b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const CallSiteEntry &S = *I; 528a583c55864e83e470333b7be878280b10e175a6eBill Wendling 529f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the landing pad, counted in 16-byte bundles relative to the 530f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // @LPStart address. 5310c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (VerboseAsm) { 53247b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Call Site " + Twine(idx) + " <<"); 53347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" On exception at call site "+Twine(idx)); 534f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 535f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitULEB128(idx); 5360c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling 537f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the first associated action record, relative to the start of 538f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table. This value is biased by 1 (1 indicates the start of 539f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table), and 0 indicates that there are no actions. 540f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 5410c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (S.Action == 0) 5420c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling Asm->OutStreamer.AddComment(" Action: cleanup"); 5430c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling else 54447b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Action: " + 54547b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine((S.Action - 1) / 2 + 1)); 5460c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling } 5470c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling Asm->EmitULEB128(S.Action); 5481b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 5491b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 5501b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // DWARF Exception handling 5513965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov assert(Asm->MAI->isExceptionHandlingDwarf()); 5521b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 553a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The call-site table is a list of all call sites that may throw an 554a583c55864e83e470333b7be878280b10e175a6eBill Wendling // exception (including C++ 'throw' statements) in the procedure 555a583c55864e83e470333b7be878280b10e175a6eBill Wendling // fragment. It immediately follows the LSDA header. Each entry indicates, 556a583c55864e83e470333b7be878280b10e175a6eBill Wendling // for a given call, the first corresponding action record and corresponding 557a583c55864e83e470333b7be878280b10e175a6eBill Wendling // landing pad. 558a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 559a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The table begins with the number of bytes, stored as an LEB128 560a583c55864e83e470333b7be878280b10e175a6eBill Wendling // compressed, unsigned integer. The records immediately follow the record 561a583c55864e83e470333b7be878280b10e175a6eBill Wendling // count. They are sorted in increasing call-site address. Each record 562a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates: 563a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 564a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the call-site. 565a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the landing pad. 566a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The first action record for that call site. 567a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 568a583c55864e83e470333b7be878280b10e175a6eBill Wendling // A missing entry in the call-site table indicates that a call is not 56928275fdf02885587156da5cb20388b22d5b96557Bill Wendling // supposed to throw. 570a583c55864e83e470333b7be878280b10e175a6eBill Wendling 571a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the landing pad call site table. 572ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 5731869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 5741869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 5757e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 576eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 5778fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned Entry = 0; 5781b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5795cff487665097d971067cbede1598e249f673182Bill Wendling I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 5801b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach const CallSiteEntry &S = *I; 581d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 582c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner MCSymbol *EHFuncBeginSym = 58384ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); 584d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5851611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *BeginLabel = S.BeginLabel; 5861611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner if (BeginLabel == 0) 5871611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner BeginLabel = EHFuncBeginSym; 5881611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *EndLabel = S.EndLabel; 5891611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner if (EndLabel == 0) 59084ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); 591d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5928fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 593a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the call site relative to the previous call site, counted in 594a583c55864e83e470333b7be878280b10e175a6eBill Wendling // number of 16-byte bundles. The first call site is counted relative to 595a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the start of the procedure fragment. 596f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 59747b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Call Site " + Twine(++Entry) + " <<"); 598f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); 599f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 600f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(Twine(" Call between ") + 601f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin BeginLabel->getName() + " and " + 602f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin EndLabel->getName()); 603a64371828e27dcc30d38e7246dda0f35c1dfde40Chris Lattner Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); 604eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 605a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the landing pad, counted in 16-byte bundles relative to the 606a583c55864e83e470333b7be878280b10e175a6eBill Wendling // @LPStart address. 607f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (!S.PadLabel) { 608f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 609f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(" has no landing pad"); 610ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher Asm->OutStreamer.EmitIntValue(0, 4/*size*/); 611f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } else { 612f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 613f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(Twine(" jumps to ") + 614f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin S.PadLabel->getName()); 615f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4); 616f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 617eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 618a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the first associated action record, relative to the start of 619a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table. This value is biased by 1 (1 indicates the start of 620a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table), and 0 indicates that there are no actions. 621f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 622f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (S.Action == 0) 623f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->OutStreamer.AddComment(" On action: cleanup"); 624f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin else 62547b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" On action: " + 62647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine((S.Action - 1) / 2 + 1)); 627f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 6288fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(S.Action); 6291b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 630eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 631eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 632a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Action Table. 6338fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling int Entry = 0; 6345cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<ActionEntry>::const_iterator 6355cff487665097d971067cbede1598e249f673182Bill Wendling I = Actions.begin(), E = Actions.end(); I != E; ++I) { 6365cff487665097d971067cbede1598e249f673182Bill Wendling const ActionEntry &Action = *I; 6378fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 6388fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 6398fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling // Emit comments that decode the action table. 64047b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(">> Action Record " + Twine(++Entry) + " <<"); 641f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 642f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin 643f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Type Filter 644f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 645f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Used by the runtime to match the type of the thrown exception to the 646f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // type of the catch clauses or the types in the exception specification. 647f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 64842e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands if (Action.ValueForTypeID > 0) 64947b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Catch TypeInfo " + 65047b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine(Action.ValueForTypeID)); 65142e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else if (Action.ValueForTypeID < 0) 65247b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Filter TypeInfo " + 65347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Twine(Action.ValueForTypeID)); 65442e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else 65542e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands Asm->OutStreamer.AddComment(" Cleanup"); 656f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 657f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitSLEB128(Action.ValueForTypeID); 6588fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 659f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Action Record 660f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 661f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Self-relative signed displacement in bytes of the next action record, 662f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // or 0 if there is no next action record. 663f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 6648fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (Action.NextAction == 0) { 6658fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(" No further actions"); 6668fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } else { 6678fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned NextAction = Entry + (Action.NextAction + 1) / 2; 66847b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment(" Continue to action "+Twine(NextAction)); 6698fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6708fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6718fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitSLEB128(Action.NextAction); 672eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 673eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 6742386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov EmitTypeInfos(TTypeEncoding); 6752386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6762386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov Asm->EmitAlignment(2); 6772386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov} 6782386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6792386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikovvoid DwarfException::EmitTypeInfos(unsigned TTypeEncoding) { 6802386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 6812386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 6822386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6832386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); 6842386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6852386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov int Entry = 0; 68648dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Catch TypeInfos. 6878fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !TypeInfos.empty()) { 6888fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); 689233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner Asm->OutStreamer.AddBlankLine(); 6908fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = TypeInfos.size(); 691233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 6928fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 69346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman for (std::vector<const GlobalVariable *>::const_reverse_iterator 69401c69374b508bad0ee71cd3c49414a325238e29aBill Wendling I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 695fb7634f1c7a804829fc55e3711ba62c8ade818d0Bill Wendling const GlobalVariable *GV = *I; 6968fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) 69747b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); 698239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov Asm->EmitTTypeReference(GV, TTypeEncoding); 699eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 700eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 70148dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Exception Specifications. 7028fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !FilterIds.empty()) { 7038fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); 704233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner Asm->OutStreamer.AddBlankLine(); 7058fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = 0; 706233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 7075cff487665097d971067cbede1598e249f673182Bill Wendling for (std::vector<unsigned>::const_iterator 7085cff487665097d971067cbede1598e249f673182Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 7095cff487665097d971067cbede1598e249f673182Bill Wendling unsigned TypeID = *I; 7108fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 7118fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling --Entry; 7128fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (TypeID != 0) 71347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry)); 7148fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 7158fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 7168fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(TypeID); 717eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 718eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 719eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 720eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndModule - Emit all exception information that should come after the 721eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// content. 722eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndModule() { 7235e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 724eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 725eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 72628275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// BeginFunction - Gather pre-function exception information. Assumes it's 72728275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// being emitted immediately after the function entry point. 728eec791afb127ed634ed5d1cdd2e6c47b3b70174cChris Lattnervoid DwarfException::BeginFunction(const MachineFunction *MF) { 7295e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 730eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 731eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 732eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndFunction - Gather and emit post-function exception information. 733eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 734eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndFunction() { 7355e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper llvm_unreachable("Should be implemented"); 736eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 737