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