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