DwarfException.cpp revision 0530f42b442cdcca775f7163b95b5b0d99a4a9b4
1//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for writing dwarf exception info into asm files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DwarfException.h"
15#include "llvm/Module.h"
16#include "llvm/CodeGen/MachineModuleInfo.h"
17#include "llvm/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineLocation.h"
19#include "llvm/Support/Dwarf.h"
20#include "llvm/Support/Timer.h"
21#include "llvm/Support/raw_ostream.h"
22#include "llvm/Target/TargetAsmInfo.h"
23#include "llvm/Target/TargetRegisterInfo.h"
24#include "llvm/Target/TargetData.h"
25#include "llvm/Target/TargetFrameInfo.h"
26#include "llvm/Target/TargetOptions.h"
27#include "llvm/ADT/StringExtras.h"
28using namespace llvm;
29
30static TimerGroup &getDwarfTimerGroup() {
31  static TimerGroup DwarfTimerGroup("Dwarf Exception");
32  return DwarfTimerGroup;
33}
34
35DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
36                               const TargetAsmInfo *T)
37  : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
38    shouldEmitTableModule(false), shouldEmitMovesModule(false),
39    ExceptionTimer(0) {
40  if (TimePassesIsEnabled)
41    ExceptionTimer = new Timer("Dwarf Exception Writer",
42                               getDwarfTimerGroup());
43}
44
45DwarfException::~DwarfException() {
46  delete ExceptionTimer;
47}
48
49void DwarfException::EmitCommonEHFrame(const Function *Personality,
50                                       unsigned Index) {
51  // Size and sign of stack growth.
52  int stackGrowth =
53    Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
54    TargetFrameInfo::StackGrowsUp ?
55    TD->getPointerSize() : -TD->getPointerSize();
56
57  // Begin eh frame section.
58  Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
59
60  if (!TAI->doesRequireNonLocalEHFrameLabel())
61    O << TAI->getEHGlobalPrefix();
62
63  O << "EH_frame" << Index << ":\n";
64  EmitLabel("section_eh_frame", Index);
65
66  // Define base labels.
67  EmitLabel("eh_frame_common", Index);
68
69  // Define the eh frame length.
70  EmitDifference("eh_frame_common_end", Index,
71                 "eh_frame_common_begin", Index, true);
72  Asm->EOL("Length of Common Information Entry");
73
74  // EH frame header.
75  EmitLabel("eh_frame_common_begin", Index);
76  Asm->EmitInt32((int)0);
77  Asm->EOL("CIE Identifier Tag");
78  Asm->EmitInt8(dwarf::DW_CIE_VERSION);
79  Asm->EOL("CIE Version");
80
81  // The personality presence indicates that language specific information will
82  // show up in the eh frame.
83  Asm->EmitString(Personality ? "zPLR" : "zR");
84  Asm->EOL("CIE Augmentation");
85
86  // Round out reader.
87  Asm->EmitULEB128Bytes(1);
88  Asm->EOL("CIE Code Alignment Factor");
89  Asm->EmitSLEB128Bytes(stackGrowth);
90  Asm->EOL("CIE Data Alignment Factor");
91  Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
92  Asm->EOL("CIE Return Address Column");
93
94  // If there is a personality, we need to indicate the functions location.
95  if (Personality) {
96    Asm->EmitULEB128Bytes(7);
97    Asm->EOL("Augmentation Size");
98
99    if (TAI->getNeedsIndirectEncoding()) {
100      Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
101                    dwarf::DW_EH_PE_indirect);
102      Asm->EOL("Personality (pcrel sdata4 indirect)");
103    } else {
104      Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
105      Asm->EOL("Personality (pcrel sdata4)");
106    }
107
108    PrintRelDirective(true);
109    O << TAI->getPersonalityPrefix();
110    Asm->EmitExternalGlobal((const GlobalVariable *)(Personality));
111    O << TAI->getPersonalitySuffix();
112    if (strcmp(TAI->getPersonalitySuffix(), "+4@GOTPCREL"))
113      O << "-" << TAI->getPCSymbol();
114    Asm->EOL("Personality");
115
116    Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
117    Asm->EOL("LSDA Encoding (pcrel sdata4)");
118
119    Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
120    Asm->EOL("FDE Encoding (pcrel sdata4)");
121  } else {
122    Asm->EmitULEB128Bytes(1);
123    Asm->EOL("Augmentation Size");
124
125    Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
126    Asm->EOL("FDE Encoding (pcrel sdata4)");
127  }
128
129  // Indicate locations of general callee saved registers in frame.
130  std::vector<MachineMove> Moves;
131  RI->getInitialFrameState(Moves);
132  EmitFrameMoves(NULL, 0, Moves, true);
133
134  // On Darwin the linker honors the alignment of eh_frame, which means it must
135  // be 8-byte on 64-bit targets to match what gcc does.  Otherwise you get
136  // holes which confuse readers of eh_frame.
137  Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
138                     0, 0, false);
139  EmitLabel("eh_frame_common_end", Index);
140
141  Asm->EOL();
142}
143
144/// EmitEHFrame - Emit function exception frame information.
145///
146void DwarfException::EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
147  assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() &&
148         "Should not emit 'available externally' functions at all");
149
150  Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage();
151  Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
152
153  // Externally visible entry into the functions eh frame info. If the
154  // corresponding function is static, this should not be externally visible.
155  if (linkage != Function::InternalLinkage &&
156      linkage != Function::PrivateLinkage) {
157    if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
158      O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
159  }
160
161  // If corresponding function is weak definition, this should be too.
162  if ((linkage == Function::WeakAnyLinkage ||
163       linkage == Function::WeakODRLinkage ||
164       linkage == Function::LinkOnceAnyLinkage ||
165       linkage == Function::LinkOnceODRLinkage) &&
166      TAI->getWeakDefDirective())
167    O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
168
169  // If there are no calls then you can't unwind.  This may mean we can omit the
170  // EH Frame, but some environments do not handle weak absolute symbols. If
171  // UnwindTablesMandatory is set we cannot do this optimization; the unwind
172  // info is to be available for non-EH uses.
173  if (!EHFrameInfo.hasCalls &&
174      !UnwindTablesMandatory &&
175      ((linkage != Function::WeakAnyLinkage &&
176        linkage != Function::WeakODRLinkage &&
177        linkage != Function::LinkOnceAnyLinkage &&
178        linkage != Function::LinkOnceODRLinkage) ||
179       !TAI->getWeakDefDirective() ||
180       TAI->getSupportsWeakOmittedEHFrame())) {
181    O << EHFrameInfo.FnName << " = 0\n";
182    // This name has no connection to the function, so it might get
183    // dead-stripped when the function is not, erroneously.  Prohibit
184    // dead-stripping unconditionally.
185    if (const char *UsedDirective = TAI->getUsedDirective())
186      O << UsedDirective << EHFrameInfo.FnName << "\n\n";
187  } else {
188    O << EHFrameInfo.FnName << ":\n";
189
190    // EH frame header.
191    EmitDifference("eh_frame_end", EHFrameInfo.Number,
192                   "eh_frame_begin", EHFrameInfo.Number, true);
193    Asm->EOL("Length of Frame Information Entry");
194
195    EmitLabel("eh_frame_begin", EHFrameInfo.Number);
196
197    if (TAI->doesRequireNonLocalEHFrameLabel()) {
198      PrintRelDirective(true, true);
199      PrintLabelName("eh_frame_begin", EHFrameInfo.Number);
200
201      if (!TAI->isAbsoluteEHSectionOffsets())
202        O << "-EH_frame" << EHFrameInfo.PersonalityIndex;
203    } else {
204      EmitSectionOffset("eh_frame_begin", "eh_frame_common",
205                        EHFrameInfo.Number, EHFrameInfo.PersonalityIndex,
206                        true, true, false);
207    }
208
209    Asm->EOL("FDE CIE offset");
210
211    EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
212    Asm->EOL("FDE initial location");
213    EmitDifference("eh_func_end", EHFrameInfo.Number,
214                   "eh_func_begin", EHFrameInfo.Number, true);
215    Asm->EOL("FDE address range");
216
217    // If there is a personality and landing pads then point to the language
218    // specific data area in the exception table.
219    if (EHFrameInfo.PersonalityIndex) {
220      Asm->EmitULEB128Bytes(4);
221      Asm->EOL("Augmentation size");
222
223      if (EHFrameInfo.hasLandingPads)
224        EmitReference("exception", EHFrameInfo.Number, true, true);
225      else
226        Asm->EmitInt32((int)0);
227      Asm->EOL("Language Specific Data Area");
228    } else {
229      Asm->EmitULEB128Bytes(0);
230      Asm->EOL("Augmentation size");
231    }
232
233    // Indicate locations of function specific callee saved registers in frame.
234    EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves,
235                   true);
236
237    // On Darwin the linker honors the alignment of eh_frame, which means it
238    // must be 8-byte on 64-bit targets to match what gcc does.  Otherwise you
239    // get holes which confuse readers of eh_frame.
240    Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
241                       0, 0, false);
242    EmitLabel("eh_frame_end", EHFrameInfo.Number);
243
244    // If the function is marked used, this table should be also.  We cannot
245    // make the mark unconditional in this case, since retaining the table also
246    // retains the function in this case, and there is code around that depends
247    // on unused functions (calling undefined externals) being dead-stripped to
248    // link correctly.  Yes, there really is.
249    if (MMI->getUsedFunctions().count(EHFrameInfo.function))
250      if (const char *UsedDirective = TAI->getUsedDirective())
251        O << UsedDirective << EHFrameInfo.FnName << "\n\n";
252  }
253}
254
255/// EmitExceptionTable - Emit landing pads and actions.
256///
257/// The general organization of the table is complex, but the basic concepts are
258/// easy.  First there is a header which describes the location and organization
259/// of the three components that follow.
260///
261///  1. The landing pad site information describes the range of code covered by
262///     the try.  In our case it's an accumulation of the ranges covered by the
263///     invokes in the try.  There is also a reference to the landing pad that
264///     handles the exception once processed.  Finally an index into the actions
265///     table.
266///  2. The action table, in our case, is composed of pairs of type ids and next
267///     action offset.  Starting with the action index from the landing pad
268///     site, each type Id is checked for a match to the current exception.  If
269///     it matches then the exception and type id are passed on to the landing
270///     pad.  Otherwise the next action is looked up.  This chain is terminated
271///     with a next action of zero.  If no type id is found the the frame is
272///     unwound and handling continues.
273///  3. Type id table contains references to all the C++ typeinfo for all
274///     catches in the function.  This tables is reversed indexed base 1.
275
276/// SharedTypeIds - How many leading type ids two landing pads have in common.
277unsigned DwarfException::SharedTypeIds(const LandingPadInfo *L,
278                                       const LandingPadInfo *R) {
279  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
280  unsigned LSize = LIds.size(), RSize = RIds.size();
281  unsigned MinSize = LSize < RSize ? LSize : RSize;
282  unsigned Count = 0;
283
284  for (; Count != MinSize; ++Count)
285    if (LIds[Count] != RIds[Count])
286      return Count;
287
288  return Count;
289}
290
291/// PadLT - Order landing pads lexicographically by type id.
292bool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
293  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
294  unsigned LSize = LIds.size(), RSize = RIds.size();
295  unsigned MinSize = LSize < RSize ? LSize : RSize;
296
297  for (unsigned i = 0; i != MinSize; ++i)
298    if (LIds[i] != RIds[i])
299      return LIds[i] < RIds[i];
300
301  return LSize < RSize;
302}
303
304void DwarfException::EmitExceptionTable() {
305  const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
306  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
307  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
308  if (PadInfos.empty()) return;
309
310  // Sort the landing pads in order of their type ids.  This is used to fold
311  // duplicate actions.
312  SmallVector<const LandingPadInfo *, 64> LandingPads;
313  LandingPads.reserve(PadInfos.size());
314  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
315    LandingPads.push_back(&PadInfos[i]);
316  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
317
318  // Negative type ids index into FilterIds, positive type ids index into
319  // TypeInfos.  The value written for a positive type id is just the type id
320  // itself.  For a negative type id, however, the value written is the
321  // (negative) byte offset of the corresponding FilterIds entry.  The byte
322  // offset is usually equal to the type id, because the FilterIds entries are
323  // written using a variable width encoding which outputs one byte per entry as
324  // long as the value written is not too large, but can differ.  This kind of
325  // complication does not occur for positive type ids because type infos are
326  // output using a fixed width encoding.  FilterOffsets[i] holds the byte
327  // offset corresponding to FilterIds[i].
328  SmallVector<int, 16> FilterOffsets;
329  FilterOffsets.reserve(FilterIds.size());
330  int Offset = -1;
331  for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
332        E = FilterIds.end(); I != E; ++I) {
333    FilterOffsets.push_back(Offset);
334    Offset -= TargetAsmInfo::getULEB128Size(*I);
335  }
336
337  // Compute the actions table and gather the first action index for each
338  // landing pad site.
339  SmallVector<ActionEntry, 32> Actions;
340  SmallVector<unsigned, 64> FirstActions;
341  FirstActions.reserve(LandingPads.size());
342
343  int FirstAction = 0;
344  unsigned SizeActions = 0;
345  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
346    const LandingPadInfo *LP = LandingPads[i];
347    const std::vector<int> &TypeIds = LP->TypeIds;
348    const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
349    unsigned SizeSiteActions = 0;
350
351    if (NumShared < TypeIds.size()) {
352      unsigned SizeAction = 0;
353      ActionEntry *PrevAction = 0;
354
355      if (NumShared) {
356        const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
357        assert(Actions.size());
358        PrevAction = &Actions.back();
359        SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
360          TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
361
362        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
363          SizeAction -=
364            TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
365          SizeAction += -PrevAction->NextAction;
366          PrevAction = PrevAction->Previous;
367        }
368      }
369
370      // Compute the actions.
371      for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
372        int TypeID = TypeIds[I];
373        assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
374        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
375        unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
376
377        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
378        SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
379        SizeSiteActions += SizeAction;
380
381        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
382        Actions.push_back(Action);
383
384        PrevAction = &Actions.back();
385      }
386
387      // Record the first action of the landing pad site.
388      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
389    } // else identical - re-use previous FirstAction
390
391    FirstActions.push_back(FirstAction);
392
393    // Compute this sites contribution to size.
394    SizeActions += SizeSiteActions;
395  }
396
397  // Compute the call-site table.  The entry for an invoke has a try-range
398  // containing the call, a non-zero landing pad and an appropriate action.  The
399  // entry for an ordinary call has a try-range containing the call and zero for
400  // the landing pad and the action.  Calls marked 'nounwind' have no entry and
401  // must not be contained in the try-range of any entry - they form gaps in the
402  // table.  Entries must be ordered by try-range address.
403  SmallVector<CallSiteEntry, 64> CallSites;
404
405  RangeMapType PadMap;
406
407  // Invokes and nounwind calls have entries in PadMap (due to being bracketed
408  // by try-range labels when lowered).  Ordinary calls do not, so appropriate
409  // try-ranges for them need be deduced.
410  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
411    const LandingPadInfo *LandingPad = LandingPads[i];
412    for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
413      unsigned BeginLabel = LandingPad->BeginLabels[j];
414      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
415      PadRange P = { i, j };
416      PadMap[BeginLabel] = P;
417    }
418  }
419
420  // The end label of the previous invoke or nounwind try-range.
421  unsigned LastLabel = 0;
422
423  // Whether there is a potentially throwing instruction (currently this means
424  // an ordinary call) between the end of the previous try-range and now.
425  bool SawPotentiallyThrowing = false;
426
427  // Whether the last callsite entry was for an invoke.
428  bool PreviousIsInvoke = false;
429
430  // Visit all instructions in order of address.
431  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
432       I != E; ++I) {
433    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
434         MI != E; ++MI) {
435      if (!MI->isLabel()) {
436        SawPotentiallyThrowing |= MI->getDesc().isCall();
437        continue;
438      }
439
440      unsigned BeginLabel = MI->getOperand(0).getImm();
441      assert(BeginLabel && "Invalid label!");
442
443      // End of the previous try-range?
444      if (BeginLabel == LastLabel)
445        SawPotentiallyThrowing = false;
446
447      // Beginning of a new try-range?
448      RangeMapType::iterator L = PadMap.find(BeginLabel);
449      if (L == PadMap.end())
450        // Nope, it was just some random label.
451        continue;
452
453      PadRange P = L->second;
454      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
455
456      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
457             "Inconsistent landing pad map!");
458
459      // If some instruction between the previous try-range and this one may
460      // throw, create a call-site entry with no landing pad for the region
461      // between the try-ranges.
462      if (SawPotentiallyThrowing) {
463        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
464        CallSites.push_back(Site);
465        PreviousIsInvoke = false;
466      }
467
468      LastLabel = LandingPad->EndLabels[P.RangeIndex];
469      assert(BeginLabel && LastLabel && "Invalid landing pad!");
470
471      if (LandingPad->LandingPadLabel) {
472        // This try-range is for an invoke.
473        CallSiteEntry Site = {BeginLabel, LastLabel,
474                              LandingPad->LandingPadLabel,
475                              FirstActions[P.PadIndex]};
476
477        // Try to merge with the previous call-site.
478        if (PreviousIsInvoke) {
479          CallSiteEntry &Prev = CallSites.back();
480          if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
481            // Extend the range of the previous entry.
482            Prev.EndLabel = Site.EndLabel;
483            continue;
484          }
485        }
486
487        // Otherwise, create a new call-site.
488        CallSites.push_back(Site);
489        PreviousIsInvoke = true;
490      } else {
491        // Create a gap.
492        PreviousIsInvoke = false;
493      }
494    }
495  }
496
497  // If some instruction between the previous try-range and the end of the
498  // function may throw, create a call-site entry with no landing pad for the
499  // region following the try-range.
500  if (SawPotentiallyThrowing) {
501    CallSiteEntry Site = {LastLabel, 0, 0, 0};
502    CallSites.push_back(Site);
503  }
504
505  // Final tallies.
506
507  // Call sites.
508  const unsigned SiteStartSize  = sizeof(int32_t); // DW_EH_PE_udata4
509  const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4
510  const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4
511  unsigned SizeSites = CallSites.size() * (SiteStartSize +
512                                           SiteLengthSize +
513                                           LandingPadSize);
514  for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
515    SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
516
517  // Type infos.
518  const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr
519  unsigned SizeTypes = TypeInfos.size() * TypeInfoSize;
520
521  unsigned TypeOffset = sizeof(int8_t) + // Call site format
522    TargetAsmInfo::getULEB128Size(SizeSites) + // Call-site table length
523    SizeSites + SizeActions + SizeTypes;
524
525  unsigned TotalSize = sizeof(int8_t) + // LPStart format
526                       sizeof(int8_t) + // TType format
527           TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
528                       TypeOffset;
529
530  unsigned SizeAlign = (4 - TotalSize) & 3;
531
532  // Begin the exception table.
533  Asm->SwitchToDataSection(TAI->getDwarfExceptionSection());
534  Asm->EmitAlignment(2, 0, 0, false);
535  O << "GCC_except_table" << SubprogramCount << ":\n";
536
537  for (unsigned i = 0; i != SizeAlign; ++i) {
538    Asm->EmitInt8(0);
539    Asm->EOL("Padding");
540    }
541
542  EmitLabel("exception", SubprogramCount);
543
544  // Emit the header.
545  Asm->EmitInt8(dwarf::DW_EH_PE_omit);
546  Asm->EOL("LPStart format (DW_EH_PE_omit)");
547  Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
548  Asm->EOL("TType format (DW_EH_PE_absptr)");
549  Asm->EmitULEB128Bytes(TypeOffset);
550  Asm->EOL("TType base offset");
551  Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
552  Asm->EOL("Call site format (DW_EH_PE_udata4)");
553  Asm->EmitULEB128Bytes(SizeSites);
554  Asm->EOL("Call-site table length");
555
556  // Emit the landing pad site information.
557  for (unsigned i = 0; i < CallSites.size(); ++i) {
558    CallSiteEntry &S = CallSites[i];
559    const char *BeginTag;
560    unsigned BeginNumber;
561
562    if (!S.BeginLabel) {
563      BeginTag = "eh_func_begin";
564      BeginNumber = SubprogramCount;
565    } else {
566      BeginTag = "label";
567      BeginNumber = S.BeginLabel;
568    }
569
570    EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
571                      true, true);
572    Asm->EOL("Region start");
573
574    if (!S.EndLabel)
575      EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
576                     true);
577    else
578      EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
579
580    Asm->EOL("Region length");
581
582    if (!S.PadLabel)
583      Asm->EmitInt32(0);
584    else
585      EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
586                        true, true);
587
588    Asm->EOL("Landing pad");
589
590    Asm->EmitULEB128Bytes(S.Action);
591    Asm->EOL("Action");
592  }
593
594  // Emit the actions.
595  for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
596    ActionEntry &Action = Actions[I];
597
598    Asm->EmitSLEB128Bytes(Action.ValueForTypeID);
599    Asm->EOL("TypeInfo index");
600    Asm->EmitSLEB128Bytes(Action.NextAction);
601    Asm->EOL("Next action");
602  }
603
604  // Emit the type ids.
605  for (unsigned M = TypeInfos.size(); M; --M) {
606    GlobalVariable *GV = TypeInfos[M - 1];
607    PrintRelDirective();
608
609    if (GV) {
610      std::string GLN;
611      O << Asm->getGlobalLinkName(GV, GLN);
612    } else {
613      O << "0";
614    }
615
616    Asm->EOL("TypeInfo");
617  }
618
619  // Emit the filter typeids.
620  for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
621    unsigned TypeID = FilterIds[j];
622    Asm->EmitULEB128Bytes(TypeID);
623    Asm->EOL("Filter TypeInfo index");
624  }
625
626  Asm->EmitAlignment(2, 0, 0, false);
627}
628
629/// EndModule - Emit all exception information that should come after the
630/// content.
631void DwarfException::EndModule() {
632  if (TimePassesIsEnabled)
633    ExceptionTimer->startTimer();
634
635  if (shouldEmitMovesModule || shouldEmitTableModule) {
636    const std::vector<Function *> Personalities = MMI->getPersonalities();
637    for (unsigned i = 0; i < Personalities.size(); ++i)
638      EmitCommonEHFrame(Personalities[i], i);
639
640    for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(),
641           E = EHFrames.end(); I != E; ++I)
642      EmitEHFrame(*I);
643  }
644
645  if (TimePassesIsEnabled)
646    ExceptionTimer->stopTimer();
647}
648
649/// BeginFunction - Gather pre-function exception information.  Assumes being
650/// emitted immediately after the function entry point.
651void DwarfException::BeginFunction(MachineFunction *MF) {
652  if (TimePassesIsEnabled)
653    ExceptionTimer->startTimer();
654
655  this->MF = MF;
656  shouldEmitTable = shouldEmitMoves = false;
657
658  if (MMI && TAI->doesSupportExceptionHandling()) {
659    // Map all labels and get rid of any dead landing pads.
660    MMI->TidyLandingPads();
661
662    // If any landing pads survive, we need an EH table.
663    if (MMI->getLandingPads().size())
664      shouldEmitTable = true;
665
666    // See if we need frame move info.
667    if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory)
668      shouldEmitMoves = true;
669
670    if (shouldEmitMoves || shouldEmitTable)
671      // Assumes in correct section after the entry point.
672      EmitLabel("eh_func_begin", ++SubprogramCount);
673  }
674
675  shouldEmitTableModule |= shouldEmitTable;
676  shouldEmitMovesModule |= shouldEmitMoves;
677
678  if (TimePassesIsEnabled)
679    ExceptionTimer->stopTimer();
680}
681
682/// EndFunction - Gather and emit post-function exception information.
683///
684void DwarfException::EndFunction() {
685  if (TimePassesIsEnabled)
686    ExceptionTimer->startTimer();
687
688  if (shouldEmitMoves || shouldEmitTable) {
689    EmitLabel("eh_func_end", SubprogramCount);
690    EmitExceptionTable();
691
692    // Save EH frame information
693    std::string Name;
694    EHFrames.push_back(
695        FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF, Name),
696                            SubprogramCount,
697                            MMI->getPersonalityIndex(),
698                            MF->getFrameInfo()->hasCalls(),
699                            !MMI->getLandingPads().empty(),
700                            MMI->getFrameMoves(),
701                            MF->getFunction()));
702  }
703
704  if (TimePassesIsEnabled)
705    ExceptionTimer->stopTimer();
706}
707