1c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//===-- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer --===// 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// 10c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// This file contains support for writing exception info into assembly files. 11eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 12eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===// 13eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 14c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "EHStreamer.h" 156d7337896f1bcdfbdee90c9c33371c2a373f422aChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 16fc4da0cea8a0f6c9c1483b92c2dffda217c0ba24David Greene#include "llvm/CodeGen/MachineFunction.h" 17c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/CodeGen/MachineInstr.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineModuleInfo.h" 19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/IR/Function.h" 208c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCAsmInfo.h" 216c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 227a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner#include "llvm/MC/MCSymbol.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/LEB128.h" 24d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 26eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm; 27eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 28c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesEHStreamer::EHStreamer(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} 29bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesEHStreamer::~EHStreamer() {} 31bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 32c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// How many leading type ids two landing pads have in common. 33c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesunsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L, 34c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const LandingPadInfo *R) { 35eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 36eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 37eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 38eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Count = 0; 39eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 40eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (; Count != MinSize; ++Count) 41eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[Count] != RIds[Count]) 42eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 43eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 44eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 45eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 46eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Compute the actions table and gather the first action index for each landing 48c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// pad site. 49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesunsigned EHStreamer:: 50c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinescomputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 51ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<ActionEntry> &Actions, 52ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVectorImpl<unsigned> &FirstActions) { 53a583c55864e83e470333b7be878280b10e175a6eBill Wendling 54a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The action table follows the call-site table in the LSDA. The individual 55a583c55864e83e470333b7be878280b10e175a6eBill Wendling // records are of two types: 56a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 57a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Catch clause 58a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * Exception specification 59a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 60a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The two record kinds have the same format, with only small differences. 61a583c55864e83e470333b7be878280b10e175a6eBill Wendling // They are distinguished by the "switch value" field: Catch clauses 62a583c55864e83e470333b7be878280b10e175a6eBill Wendling // (TypeInfos) have strictly positive switch values, and exception 63a583c55864e83e470333b7be878280b10e175a6eBill Wendling // specifications (FilterIds) have strictly negative switch values. Value 0 64a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates a catch-all clause. 65a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 665e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // Negative type IDs index into FilterIds. Positive type IDs index into 675e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // TypeInfos. The value written for a positive type ID is just the type ID 685e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // itself. For a negative type ID, however, the value written is the 69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // (negative) byte offset of the corresponding FilterIds entry. The byte 705e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // offset is usually equal to the type ID (because the FilterIds entries are 715e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // written using a variable width encoding, which outputs one byte per entry 725e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // as long as the value written is not too large) but can differ. This kind 735e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling // of complication does not occur for positive type IDs because type infos are 74eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // output using a fixed width encoding. FilterOffsets[i] holds the byte 75eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset corresponding to FilterIds[i]. 76409914b773ffd53d53d214394d5636a76f673186Bill Wendling 77409914b773ffd53d53d214394d5636a76f673186Bill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 78eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<int, 16> FilterOffsets; 79eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.reserve(FilterIds.size()); 80eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int Offset = -1; 81409914b773ffd53d53d214394d5636a76f673186Bill Wendling 82409914b773ffd53d53d214394d5636a76f673186Bill Wendling for (std::vector<unsigned>::const_iterator 83409914b773ffd53d53d214394d5636a76f673186Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 84eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.push_back(Offset); 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset -= getULEB128Size(*I); 86eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 87eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 88eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.reserve(LandingPads.size()); 89eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 90eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int FirstAction = 0; 91eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeActions = 0; 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const LandingPadInfo *PrevLPI = nullptr; 93409914b773ffd53d53d214394d5636a76f673186Bill Wendling 945cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 955e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 965e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const LandingPadInfo *LPI = *I; 975e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling const std::vector<int> &TypeIds = LPI->TypeIds; 98c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines unsigned NumShared = PrevLPI ? sharedTypeIDs(LPI, PrevLPI) : 0; 99eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSiteActions = 0; 100eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared < TypeIds.size()) { 102eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAction = 0; 1030a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling unsigned PrevAction = (unsigned)-1; 104eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 105eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared) { 1069be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SizePrevIds = PrevLPI->TypeIds.size(); 107eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(Actions.size()); 1080a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SizeAction = getSLEB128Size(Actions[PrevAction].NextAction) + 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getSLEB128Size(Actions[PrevAction].ValueForTypeID); 111eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 112eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = NumShared; j != SizePrevIds; ++j) { 1130a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SizeAction -= getSLEB128Size(Actions[PrevAction].ValueForTypeID); 1150a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling SizeAction += -Actions[PrevAction].NextAction; 1160a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions[PrevAction].Previous; 117eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 118eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 119eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 120eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions. 1215e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 1225e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling int TypeID = TypeIds[J]; 1235e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int ValueForTypeID = 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines isFilterEHSelector(TypeID) ? FilterOffsets[-1 - TypeID] : TypeID; 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SizeTypeID = getSLEB128Size(ValueForTypeID); 127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SizeAction = SizeTypeID + getSLEB128Size(NextAction); 130eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSiteActions += SizeAction; 131eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 132a583c55864e83e470333b7be878280b10e175a6eBill Wendling ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 133eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Actions.push_back(Action); 1340a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling PrevAction = Actions.size() - 1; 135eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 136eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 137eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Record the first action of the landing pad site. 138eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } // else identical - re-use previous FirstAction 140eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 141a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Information used when created the call-site table. The action record 142a583c55864e83e470333b7be878280b10e175a6eBill Wendling // field of the call site record is the offset of the first associated 143a583c55864e83e470333b7be878280b10e175a6eBill Wendling // action record, relative to the start of the actions table. This value is 1440a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling // biased by 1 (1 indicating the start of the actions table), and 0 145a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates that there are no actions. 146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.push_back(FirstAction); 147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute this sites contribution to size. 149eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeActions += SizeSiteActions; 1505e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 1515e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling PrevLPI = LPI; 152eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 153eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 1545e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling return SizeActions; 1555e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling} 1565e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling 157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Return `true' if this is a call to a function marked `nounwind'. Return 158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// `false' otherwise. 159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool EHStreamer::callToNoUnwindFunction(const MachineInstr *MI) { 1605a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng assert(MI->isCall() && "This should be a call instruction!"); 161ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 162ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool MarkedNoUnwind = false; 163ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling bool SawFunc = false; 164ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 165ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 166ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling const MachineOperand &MO = MI->getOperand(I); 167ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 168cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!MO.isGlobal()) continue; 169d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 17046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Function *F = dyn_cast<Function>(MO.getGlobal()); 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!F) continue; 172cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 173cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (SawFunc) { 174cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Be conservative. If we have more than one function operand for this 175cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // call, then we can't make the assumption that it's the callee and 176cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // not a parameter to the call. 177d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 178cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // FIXME: Determine if there's a way to say that `F' is the callee or 179cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // parameter. 180cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = false; 181cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner break; 182ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 183cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner 184cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner MarkedNoUnwind = F->doesNotThrow(); 185cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner SawFunc = true; 186ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling } 187ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 188ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling return MarkedNoUnwind; 189ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling} 190ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling 1910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid EHStreamer::computePadMap( 1920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 1930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar RangeMapType &PadMap) { 194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Invokes and nounwind calls have entries in PadMap (due to being bracketed 195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // by try-range labels when lowered). Ordinary calls do not, so appropriate 196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // try-ranges for them need be deduced so we can put them in the LSDA. 197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const LandingPadInfo *LandingPad = LandingPads[i]; 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; 201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PadRange P = { i, j }; 203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PadMap[BeginLabel] = P; 204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar} 2070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 2080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// Compute the call-site table. The entry for an invoke has a try-range 2090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// containing the call, a non-zero landing pad, and an appropriate action. The 2100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// entry for an ordinary call has a try-range containing the call and zero for 2110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// the landing pad and the action. Calls marked 'nounwind' have no entry and 2120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// must not be contained in the try-range of any entry - they form gaps in the 2130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// table. Entries must be ordered by try-range address. 2140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid EHStreamer:: 2150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarcomputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 2160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 2170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar const SmallVectorImpl<unsigned> &FirstActions) { 2180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar RangeMapType PadMap; 2190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar computePadMap(LandingPads, PadMap); 220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 221eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The end label of the previous invoke or nounwind try-range. 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *LastLabel = nullptr; 223eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 224eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether there is a potentially throwing instruction (currently this means 225eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // an ordinary call) between the end of the previous try-range and now. 226eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool SawPotentiallyThrowing = false; 227eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 2285cff487665097d971067cbede1598e249f673182Bill Wendling // Whether the last CallSite entry was for an invoke. 229eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool PreviousIsInvoke = false; 230eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; 232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Visit all instructions in order of address. 234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &MBB : *Asm->MF) { 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &MI : MBB) { 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!MI.isEHLabel()) { 237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (MI.isCall()) 238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI); 239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 241eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 242eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // End of the previous try-range? 243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol(); 244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (BeginLabel == LastLabel) 245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing = false; 246eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 247eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Beginning of a new try-range? 24881cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin RangeMapType::const_iterator L = PadMap.find(BeginLabel); 249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (L == PadMap.end()) 250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Nope, it was just some random label. 251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 252eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 253a583c55864e83e470333b7be878280b10e175a6eBill Wendling const PadRange &P = L->second; 254eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Inconsistent landing pad map!"); 257eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 258a583c55864e83e470333b7be878280b10e175a6eBill Wendling // For Dwarf exception handling (SjLj handling doesn't use this). If some 259a583c55864e83e470333b7be878280b10e175a6eBill Wendling // instruction between the previous try-range and this one may throw, 260a583c55864e83e470333b7be878280b10e175a6eBill Wendling // create a call-site entry with no landing pad for the region between the 261a583c55864e83e470333b7be878280b10e175a6eBill Wendling // try-ranges. 262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (SawPotentiallyThrowing && Asm->MAI->usesCFIForEH()) { 263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallSiteEntry Site = { LastLabel, BeginLabel, nullptr, 0 }; 264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 267eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 268eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LastLabel = LandingPad->EndLabels[P.RangeIndex]; 269eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && LastLabel && "Invalid landing pad!"); 270eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 271cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner if (!LandingPad->LandingPadLabel) { 272cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner // Create a gap. 273cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner PreviousIsInvoke = false; 274cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner } else { 275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This try-range is for an invoke. 276a583c55864e83e470333b7be878280b10e175a6eBill Wendling CallSiteEntry Site = { 277a583c55864e83e470333b7be878280b10e175a6eBill Wendling BeginLabel, 278a583c55864e83e470333b7be878280b10e175a6eBill Wendling LastLabel, 279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LandingPad, 280a583c55864e83e470333b7be878280b10e175a6eBill Wendling FirstActions[P.PadIndex] 281a583c55864e83e470333b7be878280b10e175a6eBill Wendling }; 282eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 28333668c0f1a7e374d4c3c53df34efbdf570e0987bJim Grosbach // Try to merge with the previous call-site. SJLJ doesn't do this 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (PreviousIsInvoke && !IsSJLJ) { 285eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &Prev = CallSites.back(); 286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Site.LPad == Prev.LPad && Site.Action == Prev.Action) { 287eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Extend the range of the previous entry. 288eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Prev.EndLabel = Site.EndLabel; 289eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 290eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 291eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 292eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 293eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Otherwise, create a new call-site. 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!IsSJLJ) 295ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.push_back(Site); 296ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach else { 297ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // SjLj EH must maintain the call sites in the order assigned 298ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach // to them by the SjLjPrepare pass. 299ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel); 300ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach if (CallSites.size() < SiteNo) 301ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites.resize(SiteNo); 302ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSites[SiteNo - 1] = Site; 303ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach } 304eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = true; 305eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 306eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 307eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 308eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 309eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and the end of the 310eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // function may throw, create a call-site entry with no landing pad for the 311eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // region following the try-range. 312cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (SawPotentiallyThrowing && !IsSJLJ && LastLabel != nullptr) { 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 }; 314eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 315eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 316ade025c65c12503aba161a4fa399fd97414abaffBill Wendling} 317ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 318c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Emit landing pads and actions. 3190dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 3200dafca90761097230f02e655fdd541f59b888315Bill Wendling/// The general organization of the table is complex, but the basic concepts are 3210dafca90761097230f02e655fdd541f59b888315Bill Wendling/// easy. First there is a header which describes the location and organization 3220dafca90761097230f02e655fdd541f59b888315Bill Wendling/// of the three components that follow. 323dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher/// 3240dafca90761097230f02e655fdd541f59b888315Bill Wendling/// 1. The landing pad site information describes the range of code covered by 3250dafca90761097230f02e655fdd541f59b888315Bill Wendling/// the try. In our case it's an accumulation of the ranges covered by the 3260dafca90761097230f02e655fdd541f59b888315Bill Wendling/// invokes in the try. There is also a reference to the landing pad that 3270dafca90761097230f02e655fdd541f59b888315Bill Wendling/// handles the exception once processed. Finally an index into the actions 3280dafca90761097230f02e655fdd541f59b888315Bill Wendling/// table. 329a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 2. The action table, in our case, is composed of pairs of type IDs and next 3300dafca90761097230f02e655fdd541f59b888315Bill Wendling/// action offset. Starting with the action index from the landing pad 331a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// site, each type ID is checked for a match to the current exception. If 3320dafca90761097230f02e655fdd541f59b888315Bill Wendling/// it matches then the exception and type id are passed on to the landing 3330dafca90761097230f02e655fdd541f59b888315Bill Wendling/// pad. Otherwise the next action is looked up. This chain is terminated 33428275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// with a next action of zero. If no type id is found then the frame is 3350dafca90761097230f02e655fdd541f59b888315Bill Wendling/// unwound and handling continues. 336a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// 3. Type ID table contains references to all the C++ typeinfo for all 33728275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// catches in the function. This tables is reverse indexed base 1. 338c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid EHStreamer::emitExceptionTable() { 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos(); 340ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 341ade025c65c12503aba161a4fa399fd97414abaffBill Wendling const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 342ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 343ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Sort the landing pads in order of their type ids. This is used to fold 344ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // duplicate actions. 345ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<const LandingPadInfo *, 64> LandingPads; 346ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.reserve(PadInfos.size()); 347ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 348ade025c65c12503aba161a4fa399fd97414abaffBill Wendling for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 349ade025c65c12503aba161a4fa399fd97414abaffBill Wendling LandingPads.push_back(&PadInfos[i]); 350ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Order landing pads lexicographically by type id. 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(LandingPads.begin(), LandingPads.end(), 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines [](const LandingPadInfo *L, 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const LandingPadInfo *R) { return L->TypeIds < R->TypeIds; }); 355ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 356ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the actions table and gather the first action index for each 357ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // landing pad site. 358ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<ActionEntry, 32> Actions; 359ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<unsigned, 64> FirstActions; 360c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines unsigned SizeActions = 361c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines computeActionsTable(LandingPads, Actions, FirstActions); 362ade025c65c12503aba161a4fa399fd97414abaffBill Wendling 363ade025c65c12503aba161a4fa399fd97414abaffBill Wendling // Compute the call-site table. 364ade025c65c12503aba161a4fa399fd97414abaffBill Wendling SmallVector<CallSiteEntry, 64> CallSites; 365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines computeCallSiteTable(CallSites, LandingPads, FirstActions); 366eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 367eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Final tallies. 368eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 369eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Call sites. 37084ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; 371d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 372d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 3733dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned CallSiteTableLength; 374d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 3753dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength = 0; 3769be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner else { 3779be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4 3789be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4 3799be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4 380d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov CallSiteTableLength = 3819be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); 3829be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner } 383d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 3841b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallSiteTableLength += getULEB128Size(CallSites[i].Action); 386d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallSiteTableLength += getULEB128Size(i); 3881b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 389d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling 390eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Type infos. 3916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 3929184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov unsigned TTypeEncoding; 393a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned TypeFormatSize; 394eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 39543e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling if (!HaveTTData) { 39628275fdf02885587156da5cb20388b22d5b96557Bill Wendling // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say 39728275fdf02885587156da5cb20388b22d5b96557Bill Wendling // that we're omitting that bit. 3989184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = dwarf::DW_EH_PE_omit; 39984ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner // dwarf::DW_EH_PE_absptr 400426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth TypeFormatSize = Asm->getDataLayout().getPointerSize(); 40181c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner } else { 402ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Okay, we have actual filters or typeinfos to emit. As such, we need to 403ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // pick a type encoding for them. We're about to emit a list of pointers to 404ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // typeinfo objects at the end of the LSDA. However, unless we're in static 405ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // mode, this reference will require a relocation by the dynamic linker. 40646b754c76bd6a720dd1dd3be248cb93a4e25d3e5Chris Lattner // 407ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // Because of this, we have a couple of options: 408d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 409ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 1) If we are in -static mode, we can always use an absolute reference 410ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // from the LSDA, because the static linker will resolve it. 411d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 412ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 2) Otherwise, if the LSDA section is writable, we can output the direct 413ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // reference to the typeinfo and allow the dynamic linker to relocate 414ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // it. Since it is in a writable section, the dynamic linker won't 415ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // have a problem. 416d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov // 417ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 418ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we need to use some form of indirection. For example, on Darwin, 419ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // we can output a statically-relocatable reference to a dyld stub. The 420ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // offset to the stub is constant, but the contents are in a section 421ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // that is updated by the dynamic linker. This is easy enough, but we 422ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // need to tell the personality function of the unwinder to indirect 423ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // through the dyld stub. 424ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 42543e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling // FIXME: When (3) is actually implemented, we'll have to emit the stubs 426ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // somewhere. This predicate should be moved to a shared location that is 427ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // in target-independent code. 428ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner // 4299184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); 430d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding); 431fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling } 432fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling 433fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling // Begin the exception table. 434ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // Sometimes we want not to emit the data into separate section (e.g. ARM 435ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov // EHABI). In this case LSDASection will be NULL. 436d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov if (LSDASection) 4376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->SwitchSection(LSDASection); 438059ea138a6e4180de0d70390f7147dac66614517Chris Lattner Asm->EmitAlignment(2); 43943e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling 4403dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA. 441d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov MCSymbol *GCCETSym = 4426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutContext.getOrCreateSymbol(Twine("GCC_except_table")+ 44384ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner Twine(Asm->getFunctionNumber())); 4446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->EmitLabel(GCCETSym); 4456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->EmitLabel(Asm->getCurExceptionSym()); 4463dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling 4473dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // Emit the LSDA header. 448ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); 449ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(TTypeEncoding, "@TType"); 450a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 451a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // The type infos need to be aligned. GCC does this by inserting padding just 452a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // before the type infos. However, this changes the size of the exception 453a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table, so you need to take this into account when you output the exception 454a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // table size. However, the size is output using a variable length encoding. 455a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // So by increasing the size by inserting padding, you may increase the number 456a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // of bytes used for writing the size. If it increases, say by one byte, then 457a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // you now need to output one less byte of padding to get the type infos 4583dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling // aligned. However this decreases the size of the exception table. This 459a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // changes the value you have to output for the exception table size. Due to 460a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // the variable length encoding, the number of bytes used for writing the 461a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // length may decrease. If so, you then have to increase the amount of 462a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // padding. And so on. If you look carefully at the GCC code you will see that 463a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // it indeed does this in a loop, going on and on until the values stabilize. 464a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // We chose another solution: don't output padding inside the table like GCC 465a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling // does, instead output it before the table. 466a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CallSiteTableLengthSize = getULEB128Size(CallSiteTableLength); 4683dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TTypeBaseOffset = 4693dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // Call site format 4703dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLengthSize + // Call site table length size 4713dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling CallSiteTableLength + // Call site table length 4723dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeActions + // Actions size 4733dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling SizeTypes; 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned TTypeBaseOffsetSize = getULEB128Size(TTypeBaseOffset); 4753dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling unsigned TotalSize = 4763dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // LPStart format 4773dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling sizeof(int8_t) + // TType format 4783dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size 4793dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling TTypeBaseOffset; // TType base offset 480a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling unsigned SizeAlign = (4 - TotalSize) & 3; 481a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling 48286f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling if (HaveTTData) { 4836507eca124883c90cc300c1ff344f79a8b4181a5Bill Wendling // Account for any extra padding that will be added to the call site table 484f7e90ae2057adcf6fa4b023110611084f28fd6c1Bill Wendling // length. 4857e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); 4861869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling SizeAlign = 0; 48786f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling } 488b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling 4896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); 4908fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 49128275fdf02885587156da5cb20388b22d5b96557Bill Wendling // SjLj Exception handling 492d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling if (IsSJLJ) { 493ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 4941869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 4951869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 4967e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 4971b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 4981b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach // Emit the landing pad site information. 4998b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach unsigned idx = 0; 5008b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5018b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 5028b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const CallSiteEntry &S = *I; 503a583c55864e83e470333b7be878280b10e175a6eBill Wendling 504f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the landing pad, counted in 16-byte bundles relative to the 505f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // @LPStart address. 5060c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (VerboseAsm) { 5076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(">> Call Site " + Twine(idx) + " <<"); 5086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" On exception at call site "+Twine(idx)); 509f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 510f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitULEB128(idx); 5110c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling 512f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Offset of the first associated action record, relative to the start of 513f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table. This value is biased by 1 (1 indicates the start of 514f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // the action table), and 0 indicates that there are no actions. 515f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 5160c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling if (S.Action == 0) 5176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Action: cleanup"); 5180c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling else 5196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Action: " + 5206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Twine((S.Action - 1) / 2 + 1)); 5210c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling } 5220c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling Asm->EmitULEB128(S.Action); 5231b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 5241b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } else { 525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Itanium LSDA exception handling 5261b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach 527a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The call-site table is a list of all call sites that may throw an 528a583c55864e83e470333b7be878280b10e175a6eBill Wendling // exception (including C++ 'throw' statements) in the procedure 529a583c55864e83e470333b7be878280b10e175a6eBill Wendling // fragment. It immediately follows the LSDA header. Each entry indicates, 530a583c55864e83e470333b7be878280b10e175a6eBill Wendling // for a given call, the first corresponding action record and corresponding 531a583c55864e83e470333b7be878280b10e175a6eBill Wendling // landing pad. 532a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 533a583c55864e83e470333b7be878280b10e175a6eBill Wendling // The table begins with the number of bytes, stored as an LEB128 534a583c55864e83e470333b7be878280b10e175a6eBill Wendling // compressed, unsigned integer. The records immediately follow the record 535a583c55864e83e470333b7be878280b10e175a6eBill Wendling // count. They are sorted in increasing call-site address. Each record 536a583c55864e83e470333b7be878280b10e175a6eBill Wendling // indicates: 537a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 538a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the call-site. 539a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The position of the landing pad. 540a583c55864e83e470333b7be878280b10e175a6eBill Wendling // * The first action record for that call site. 541a583c55864e83e470333b7be878280b10e175a6eBill Wendling // 542a583c55864e83e470333b7be878280b10e175a6eBill Wendling // A missing entry in the call-site table indicates that a call is not 54328275fdf02885587156da5cb20388b22d5b96557Bill Wendling // supposed to throw. 544a583c55864e83e470333b7be878280b10e175a6eBill Wendling 545a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the landing pad call site table. 546ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 5471869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling 5481869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling // Add extra padding if it wasn't added to the TType base offset. 5497e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 550eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 5518fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned Entry = 0; 5521b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach for (SmallVectorImpl<CallSiteEntry>::const_iterator 5535cff487665097d971067cbede1598e249f673182Bill Wendling I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 5541b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach const CallSiteEntry &S = *I; 555d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *EHFuncBeginSym = Asm->getFunctionBegin(); 557d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 5581611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *BeginLabel = S.BeginLabel; 559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!BeginLabel) 5601611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner BeginLabel = EHFuncBeginSym; 5611611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner MCSymbol *EndLabel = S.EndLabel; 562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!EndLabel) 5634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EndLabel = Asm->getFunctionEnd(); 5648fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 565a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the call site relative to the previous call site, counted in 566a583c55864e83e470333b7be878280b10e175a6eBill Wendling // number of 16-byte bundles. The first call site is counted relative to 567a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the start of the procedure fragment. 568f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 5696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) + " <<"); 570f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); 571f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 5726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(Twine(" Call between ") + 5736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BeginLabel->getName() + " and " + 5746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar EndLabel->getName()); 575a64371828e27dcc30d38e7246dda0f35c1dfde40Chris Lattner Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); 576eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 577a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the landing pad, counted in 16-byte bundles relative to the 578a583c55864e83e470333b7be878280b10e175a6eBill Wendling // @LPStart address. 579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!S.LPad) { 580f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 5816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" has no landing pad"); 5826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->EmitIntValue(0, 4/*size*/); 583f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } else { 584f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) 5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(Twine(" jumps to ") + 5866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar S.LPad->LandingPadLabel->getName()); 587ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Asm->EmitLabelDifference(S.LPad->LandingPadLabel, EHFuncBeginSym, 4); 588f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 589eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 590a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Offset of the first associated action record, relative to the start of 591a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table. This value is biased by 1 (1 indicates the start of 592a583c55864e83e470333b7be878280b10e175a6eBill Wendling // the action table), and 0 indicates that there are no actions. 593f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 594f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (S.Action == 0) 5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" On action: cleanup"); 596f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin else 5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" On action: " + 5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Twine((S.Action - 1) / 2 + 1)); 599f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 6008fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(S.Action); 6011b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach } 602eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 603eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 604a583c55864e83e470333b7be878280b10e175a6eBill Wendling // Emit the Action Table. 6058fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling int Entry = 0; 6065cff487665097d971067cbede1598e249f673182Bill Wendling for (SmallVectorImpl<ActionEntry>::const_iterator 6075cff487665097d971067cbede1598e249f673182Bill Wendling I = Actions.begin(), E = Actions.end(); I != E; ++I) { 6085cff487665097d971067cbede1598e249f673182Bill Wendling const ActionEntry &Action = *I; 6098fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 6108fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 6118fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling // Emit comments that decode the action table. 6126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(">> Action Record " + Twine(++Entry) + " <<"); 613f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 614f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin 615f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Type Filter 616f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 617f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Used by the runtime to match the type of the thrown exception to the 618f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // type of the catch clauses or the types in the exception specification. 619f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 62042e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands if (Action.ValueForTypeID > 0) 6216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Catch TypeInfo " + 6226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Twine(Action.ValueForTypeID)); 62342e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else if (Action.ValueForTypeID < 0) 6246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Filter TypeInfo " + 6256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Twine(Action.ValueForTypeID)); 62642e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands else 6276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Cleanup"); 628f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin } 629f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin Asm->EmitSLEB128(Action.ValueForTypeID); 6308fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 631f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Action Record 632f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // 633f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // Self-relative signed displacement in bytes of the next action record, 634f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin // or 0 if there is no next action record. 635f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin if (VerboseAsm) { 6368fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (Action.NextAction == 0) { 6376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" No further actions"); 6388fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } else { 6398fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling unsigned NextAction = Entry + (Action.NextAction + 1) / 2; 6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(" Continue to action "+Twine(NextAction)); 6418fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6428fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6438fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitSLEB128(Action.NextAction); 644eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 645eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 646c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines emitTypeInfos(TTypeEncoding); 6472386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6482386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov Asm->EmitAlignment(2); 6492386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov} 6502386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 651c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid EHStreamer::emitTypeInfos(unsigned TTypeEncoding) { 65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos(); 6532386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 6542386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); 6562386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov 6572386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov int Entry = 0; 65848dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Catch TypeInfos. 6598fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !TypeInfos.empty()) { 6606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); 6616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddBlankLine(); 6628fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = TypeInfos.size(); 663233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 6648fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 665cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (const GlobalValue *GV : make_range(TypeInfos.rbegin(), 666cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar TypeInfos.rend())) { 6678fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) 6686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--)); 669239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov Asm->EmitTTypeReference(GV, TTypeEncoding); 670eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 671eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 67248dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling // Emit the Exception Specifications. 6738fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm && !FilterIds.empty()) { 6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); 6756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddBlankLine(); 6768fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Entry = 0; 677233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner } 6785cff487665097d971067cbede1598e249f673182Bill Wendling for (std::vector<unsigned>::const_iterator 6795cff487665097d971067cbede1598e249f673182Bill Wendling I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 6805cff487665097d971067cbede1598e249f673182Bill Wendling unsigned TypeID = *I; 6818fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling if (VerboseAsm) { 6828fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling --Entry; 683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (isFilterEHSelector(TypeID)) 6846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry)); 6858fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling } 6868fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling 6878fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling Asm->EmitULEB128(TypeID); 688eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 689eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 690