~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
 
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 defines a JITDwarfEmitter object that is used by the JIT to
 
11
// write dwarf tables to memory.
 
12
//
 
13
//===----------------------------------------------------------------------===//
 
14
 
 
15
#include "JIT.h"
 
16
#include "JITDwarfEmitter.h"
 
17
#include "llvm/Function.h"
 
18
#include "llvm/ADT/DenseMap.h"
 
19
#include "llvm/CodeGen/JITCodeEmitter.h"
 
20
#include "llvm/CodeGen/MachineFunction.h"
 
21
#include "llvm/CodeGen/MachineLocation.h"
 
22
#include "llvm/CodeGen/MachineModuleInfo.h"
 
23
#include "llvm/ExecutionEngine/JITMemoryManager.h"
 
24
#include "llvm/Support/ErrorHandling.h"
 
25
#include "llvm/MC/MCAsmInfo.h"
 
26
#include "llvm/Target/TargetData.h"
 
27
#include "llvm/Target/TargetInstrInfo.h"
 
28
#include "llvm/Target/TargetFrameInfo.h"
 
29
#include "llvm/Target/TargetMachine.h"
 
30
#include "llvm/Target/TargetRegisterInfo.h"
 
31
using namespace llvm;
 
32
 
 
33
JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : MMI(0), Jit(theJit) {}
 
34
 
 
35
 
 
36
unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, 
 
37
                                               JITCodeEmitter& jce,
 
38
                                               unsigned char* StartFunction,
 
39
                                               unsigned char* EndFunction,
 
40
                                               unsigned char* &EHFramePtr) {
 
41
  assert(MMI && "MachineModuleInfo not registered!");
 
42
 
 
43
  const TargetMachine& TM = F.getTarget();
 
44
  TD = TM.getTargetData();
 
45
  stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
 
46
  RI = TM.getRegisterInfo();
 
47
  JCE = &jce;
 
48
  
 
49
  unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
 
50
                                                     EndFunction);
 
51
      
 
52
  unsigned char* Result = 0;
 
53
 
 
54
  const std::vector<Function *> Personalities = MMI->getPersonalities();
 
55
  EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
 
56
 
 
57
  Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
 
58
                       StartFunction, EndFunction, ExceptionTable);
 
59
 
 
60
  return Result;
 
61
}
 
62
 
 
63
 
 
64
void 
 
65
JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
 
66
                                const std::vector<MachineMove> &Moves) const {
 
67
  unsigned PointerSize = TD->getPointerSize();
 
68
  int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
 
69
          PointerSize : -PointerSize;
 
70
  bool IsLocal = false;
 
71
  unsigned BaseLabelID = 0;
 
72
 
 
73
  for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
 
74
    const MachineMove &Move = Moves[i];
 
75
    unsigned LabelID = Move.getLabelID();
 
76
    
 
77
    if (LabelID) {
 
78
      LabelID = MMI->MappedLabel(LabelID);
 
79
    
 
80
      // Throw out move if the label is invalid.
 
81
      if (!LabelID) continue;
 
82
    }
 
83
    
 
84
    intptr_t LabelPtr = 0;
 
85
    if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
 
86
 
 
87
    const MachineLocation &Dst = Move.getDestination();
 
88
    const MachineLocation &Src = Move.getSource();
 
89
    
 
90
    // Advance row if new location.
 
91
    if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
 
92
      JCE->emitByte(dwarf::DW_CFA_advance_loc4);
 
93
      JCE->emitInt32(LabelPtr - BaseLabelPtr);
 
94
      
 
95
      BaseLabelID = LabelID; 
 
96
      BaseLabelPtr = LabelPtr;
 
97
      IsLocal = true;
 
98
    }
 
99
    
 
100
    // If advancing cfa.
 
101
    if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
 
102
      if (!Src.isReg()) {
 
103
        if (Src.getReg() == MachineLocation::VirtualFP) {
 
104
          JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
 
105
        } else {
 
106
          JCE->emitByte(dwarf::DW_CFA_def_cfa);
 
107
          JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
 
108
        }
 
109
        
 
110
        JCE->emitULEB128Bytes(-Src.getOffset());
 
111
      } else {
 
112
        llvm_unreachable("Machine move not supported yet.");
 
113
      }
 
114
    } else if (Src.isReg() &&
 
115
      Src.getReg() == MachineLocation::VirtualFP) {
 
116
      if (Dst.isReg()) {
 
117
        JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
 
118
        JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
 
119
      } else {
 
120
        llvm_unreachable("Machine move not supported yet.");
 
121
      }
 
122
    } else {
 
123
      unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
 
124
      int Offset = Dst.getOffset() / stackGrowth;
 
125
      
 
126
      if (Offset < 0) {
 
127
        JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
 
128
        JCE->emitULEB128Bytes(Reg);
 
129
        JCE->emitSLEB128Bytes(Offset);
 
130
      } else if (Reg < 64) {
 
131
        JCE->emitByte(dwarf::DW_CFA_offset + Reg);
 
132
        JCE->emitULEB128Bytes(Offset);
 
133
      } else {
 
134
        JCE->emitByte(dwarf::DW_CFA_offset_extended);
 
135
        JCE->emitULEB128Bytes(Reg);
 
136
        JCE->emitULEB128Bytes(Offset);
 
137
      }
 
138
    }
 
139
  }
 
140
}
 
141
 
 
142
/// SharedTypeIds - How many leading type ids two landing pads have in common.
 
143
static unsigned SharedTypeIds(const LandingPadInfo *L,
 
144
                              const LandingPadInfo *R) {
 
145
  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
 
146
  unsigned LSize = LIds.size(), RSize = RIds.size();
 
147
  unsigned MinSize = LSize < RSize ? LSize : RSize;
 
148
  unsigned Count = 0;
 
149
 
 
150
  for (; Count != MinSize; ++Count)
 
151
    if (LIds[Count] != RIds[Count])
 
152
      return Count;
 
153
 
 
154
  return Count;
 
155
}
 
156
 
 
157
 
 
158
/// PadLT - Order landing pads lexicographically by type id.
 
159
static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
 
160
  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
 
161
  unsigned LSize = LIds.size(), RSize = RIds.size();
 
162
  unsigned MinSize = LSize < RSize ? LSize : RSize;
 
163
 
 
164
  for (unsigned i = 0; i != MinSize; ++i)
 
165
    if (LIds[i] != RIds[i])
 
166
      return LIds[i] < RIds[i];
 
167
 
 
168
  return LSize < RSize;
 
169
}
 
170
 
 
171
namespace {
 
172
 
 
173
struct KeyInfo {
 
174
  static inline unsigned getEmptyKey() { return -1U; }
 
175
  static inline unsigned getTombstoneKey() { return -2U; }
 
176
  static unsigned getHashValue(const unsigned &Key) { return Key; }
 
177
  static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
 
178
};
 
179
 
 
180
/// ActionEntry - Structure describing an entry in the actions table.
 
181
struct ActionEntry {
 
182
  int ValueForTypeID; // The value to write - may not be equal to the type id.
 
183
  int NextAction;
 
184
  struct ActionEntry *Previous;
 
185
};
 
186
 
 
187
/// PadRange - Structure holding a try-range and the associated landing pad.
 
188
struct PadRange {
 
189
  // The index of the landing pad.
 
190
  unsigned PadIndex;
 
191
  // The index of the begin and end labels in the landing pad's label lists.
 
192
  unsigned RangeIndex;
 
193
};
 
194
 
 
195
typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
 
196
 
 
197
/// CallSiteEntry - Structure describing an entry in the call-site table.
 
198
struct CallSiteEntry {
 
199
  unsigned BeginLabel; // zero indicates the start of the function.
 
200
  unsigned EndLabel;   // zero indicates the end of the function.
 
201
  unsigned PadLabel;   // zero indicates that there is no landing pad.
 
202
  unsigned Action;
 
203
};
 
204
 
 
205
}
 
206
 
 
207
unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
 
208
                                         unsigned char* StartFunction,
 
209
                                         unsigned char* EndFunction) const {
 
210
  assert(MMI && "MachineModuleInfo not registered!");
 
211
 
 
212
  // Map all labels and get rid of any dead landing pads.
 
213
  MMI->TidyLandingPads();
 
214
 
 
215
  const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
 
216
  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
 
217
  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
 
218
  if (PadInfos.empty()) return 0;
 
219
 
 
220
  // Sort the landing pads in order of their type ids.  This is used to fold
 
221
  // duplicate actions.
 
222
  SmallVector<const LandingPadInfo *, 64> LandingPads;
 
223
  LandingPads.reserve(PadInfos.size());
 
224
  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
 
225
    LandingPads.push_back(&PadInfos[i]);
 
226
  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
 
227
 
 
228
  // Negative type ids index into FilterIds, positive type ids index into
 
229
  // TypeInfos.  The value written for a positive type id is just the type
 
230
  // id itself.  For a negative type id, however, the value written is the
 
231
  // (negative) byte offset of the corresponding FilterIds entry.  The byte
 
232
  // offset is usually equal to the type id, because the FilterIds entries
 
233
  // are written using a variable width encoding which outputs one byte per
 
234
  // entry as long as the value written is not too large, but can differ.
 
235
  // This kind of complication does not occur for positive type ids because
 
236
  // type infos are output using a fixed width encoding.
 
237
  // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
 
238
  SmallVector<int, 16> FilterOffsets;
 
239
  FilterOffsets.reserve(FilterIds.size());
 
240
  int Offset = -1;
 
241
  for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
 
242
    E = FilterIds.end(); I != E; ++I) {
 
243
    FilterOffsets.push_back(Offset);
 
244
    Offset -= MCAsmInfo::getULEB128Size(*I);
 
245
  }
 
246
 
 
247
  // Compute the actions table and gather the first action index for each
 
248
  // landing pad site.
 
249
  SmallVector<ActionEntry, 32> Actions;
 
250
  SmallVector<unsigned, 64> FirstActions;
 
251
  FirstActions.reserve(LandingPads.size());
 
252
 
 
253
  int FirstAction = 0;
 
254
  unsigned SizeActions = 0;
 
255
  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
 
256
    const LandingPadInfo *LP = LandingPads[i];
 
257
    const std::vector<int> &TypeIds = LP->TypeIds;
 
258
    const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
 
259
    unsigned SizeSiteActions = 0;
 
260
 
 
261
    if (NumShared < TypeIds.size()) {
 
262
      unsigned SizeAction = 0;
 
263
      ActionEntry *PrevAction = 0;
 
264
 
 
265
      if (NumShared) {
 
266
        const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
 
267
        assert(Actions.size());
 
268
        PrevAction = &Actions.back();
 
269
        SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
 
270
          MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
 
271
        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
 
272
          SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
 
273
          SizeAction += -PrevAction->NextAction;
 
274
          PrevAction = PrevAction->Previous;
 
275
        }
 
276
      }
 
277
 
 
278
      // Compute the actions.
 
279
      for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
 
280
        int TypeID = TypeIds[I];
 
281
        assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
 
282
        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
 
283
        unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
 
284
 
 
285
        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
 
286
        SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
 
287
        SizeSiteActions += SizeAction;
 
288
 
 
289
        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
 
290
        Actions.push_back(Action);
 
291
 
 
292
        PrevAction = &Actions.back();
 
293
      }
 
294
 
 
295
      // Record the first action of the landing pad site.
 
296
      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
 
297
    } // else identical - re-use previous FirstAction
 
298
 
 
299
    FirstActions.push_back(FirstAction);
 
300
 
 
301
    // Compute this sites contribution to size.
 
302
    SizeActions += SizeSiteActions;
 
303
  }
 
304
 
 
305
  // Compute the call-site table.  Entries must be ordered by address.
 
306
  SmallVector<CallSiteEntry, 64> CallSites;
 
307
 
 
308
  RangeMapType PadMap;
 
309
  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
 
310
    const LandingPadInfo *LandingPad = LandingPads[i];
 
311
    for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
 
312
      unsigned BeginLabel = LandingPad->BeginLabels[j];
 
313
      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
 
314
      PadRange P = { i, j };
 
315
      PadMap[BeginLabel] = P;
 
316
    }
 
317
  }
 
318
 
 
319
  bool MayThrow = false;
 
320
  unsigned LastLabel = 0;
 
321
  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
 
322
        I != E; ++I) {
 
323
    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
 
324
          MI != E; ++MI) {
 
325
      if (!MI->isLabel()) {
 
326
        MayThrow |= MI->getDesc().isCall();
 
327
        continue;
 
328
      }
 
329
 
 
330
      unsigned BeginLabel = MI->getOperand(0).getImm();
 
331
      assert(BeginLabel && "Invalid label!");
 
332
 
 
333
      if (BeginLabel == LastLabel)
 
334
        MayThrow = false;
 
335
 
 
336
      RangeMapType::iterator L = PadMap.find(BeginLabel);
 
337
 
 
338
      if (L == PadMap.end())
 
339
        continue;
 
340
 
 
341
      PadRange P = L->second;
 
342
      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
 
343
 
 
344
      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
 
345
              "Inconsistent landing pad map!");
 
346
 
 
347
      // If some instruction between the previous try-range and this one may
 
348
      // throw, create a call-site entry with no landing pad for the region
 
349
      // between the try-ranges.
 
350
      if (MayThrow) {
 
351
        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
 
352
        CallSites.push_back(Site);
 
353
      }
 
354
 
 
355
      LastLabel = LandingPad->EndLabels[P.RangeIndex];
 
356
      CallSiteEntry Site = {BeginLabel, LastLabel,
 
357
        LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
 
358
 
 
359
      assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
 
360
              "Invalid landing pad!");
 
361
 
 
362
      // Try to merge with the previous call-site.
 
363
      if (CallSites.size()) {
 
364
        CallSiteEntry &Prev = CallSites.back();
 
365
        if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
 
366
          // Extend the range of the previous entry.
 
367
          Prev.EndLabel = Site.EndLabel;
 
368
          continue;
 
369
        }
 
370
      }
 
371
 
 
372
      // Otherwise, create a new call-site.
 
373
      CallSites.push_back(Site);
 
374
    }
 
375
  }
 
376
  // If some instruction between the previous try-range and the end of the
 
377
  // function may throw, create a call-site entry with no landing pad for the
 
378
  // region following the try-range.
 
379
  if (MayThrow) {
 
380
    CallSiteEntry Site = {LastLabel, 0, 0, 0};
 
381
    CallSites.push_back(Site);
 
382
  }
 
383
 
 
384
  // Final tallies.
 
385
  unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
 
386
                                            sizeof(int32_t) + // Site length.
 
387
                                            sizeof(int32_t)); // Landing pad.
 
388
  for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
 
389
    SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
 
390
 
 
391
  unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
 
392
 
 
393
  unsigned TypeOffset = sizeof(int8_t) + // Call site format
 
394
                        // Call-site table length
 
395
                        MCAsmInfo::getULEB128Size(SizeSites) + 
 
396
                        SizeSites + SizeActions + SizeTypes;
 
397
 
 
398
  // Begin the exception table.
 
399
  JCE->emitAlignmentWithFill(4, 0);
 
400
  // Asm->EOL("Padding");
 
401
 
 
402
  unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
 
403
 
 
404
  // Emit the header.
 
405
  JCE->emitByte(dwarf::DW_EH_PE_omit);
 
406
  // Asm->EOL("LPStart format (DW_EH_PE_omit)");
 
407
  JCE->emitByte(dwarf::DW_EH_PE_absptr);
 
408
  // Asm->EOL("TType format (DW_EH_PE_absptr)");
 
409
  JCE->emitULEB128Bytes(TypeOffset);
 
410
  // Asm->EOL("TType base offset");
 
411
  JCE->emitByte(dwarf::DW_EH_PE_udata4);
 
412
  // Asm->EOL("Call site format (DW_EH_PE_udata4)");
 
413
  JCE->emitULEB128Bytes(SizeSites);
 
414
  // Asm->EOL("Call-site table length");
 
415
 
 
416
  // Emit the landing pad site information.
 
417
  for (unsigned i = 0; i < CallSites.size(); ++i) {
 
418
    CallSiteEntry &S = CallSites[i];
 
419
    intptr_t BeginLabelPtr = 0;
 
420
    intptr_t EndLabelPtr = 0;
 
421
 
 
422
    if (!S.BeginLabel) {
 
423
      BeginLabelPtr = (intptr_t)StartFunction;
 
424
      JCE->emitInt32(0);
 
425
    } else {
 
426
      BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
 
427
      JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
 
428
    }
 
429
 
 
430
    // Asm->EOL("Region start");
 
431
 
 
432
    if (!S.EndLabel)
 
433
      EndLabelPtr = (intptr_t)EndFunction;
 
434
    else
 
435
      EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
 
436
 
 
437
    JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
 
438
    //Asm->EOL("Region length");
 
439
 
 
440
    if (!S.PadLabel) {
 
441
      JCE->emitInt32(0);
 
442
    } else {
 
443
      unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
 
444
      JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
 
445
    }
 
446
    // Asm->EOL("Landing pad");
 
447
 
 
448
    JCE->emitULEB128Bytes(S.Action);
 
449
    // Asm->EOL("Action");
 
450
  }
 
451
 
 
452
  // Emit the actions.
 
453
  for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
 
454
    ActionEntry &Action = Actions[I];
 
455
 
 
456
    JCE->emitSLEB128Bytes(Action.ValueForTypeID);
 
457
    //Asm->EOL("TypeInfo index");
 
458
    JCE->emitSLEB128Bytes(Action.NextAction);
 
459
    //Asm->EOL("Next action");
 
460
  }
 
461
 
 
462
  // Emit the type ids.
 
463
  for (unsigned M = TypeInfos.size(); M; --M) {
 
464
    GlobalVariable *GV = TypeInfos[M - 1];
 
465
    
 
466
    if (GV) {
 
467
      if (TD->getPointerSize() == sizeof(int32_t))
 
468
        JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
 
469
      else
 
470
        JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
 
471
    } else {
 
472
      if (TD->getPointerSize() == sizeof(int32_t))
 
473
        JCE->emitInt32(0);
 
474
      else
 
475
        JCE->emitInt64(0);
 
476
    }
 
477
    // Asm->EOL("TypeInfo");
 
478
  }
 
479
 
 
480
  // Emit the filter typeids.
 
481
  for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
 
482
    unsigned TypeID = FilterIds[j];
 
483
    JCE->emitULEB128Bytes(TypeID);
 
484
    //Asm->EOL("Filter TypeInfo index");
 
485
  }
 
486
 
 
487
  JCE->emitAlignmentWithFill(4, 0);
 
488
 
 
489
  return DwarfExceptionTable;
 
490
}
 
491
 
 
492
unsigned char*
 
493
JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
 
494
  unsigned PointerSize = TD->getPointerSize();
 
495
  int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
 
496
          PointerSize : -PointerSize;
 
497
  
 
498
  unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
 
499
  // EH Common Frame header
 
500
  JCE->allocateSpace(4, 0);
 
501
  unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
 
502
  JCE->emitInt32((int)0);
 
503
  JCE->emitByte(dwarf::DW_CIE_VERSION);
 
504
  JCE->emitString(Personality ? "zPLR" : "zR");
 
505
  JCE->emitULEB128Bytes(1);
 
506
  JCE->emitSLEB128Bytes(stackGrowth);
 
507
  JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
 
508
 
 
509
  if (Personality) {
 
510
    // Augmentation Size: 3 small ULEBs of one byte each, and the personality
 
511
    // function which size is PointerSize.
 
512
    JCE->emitULEB128Bytes(3 + PointerSize); 
 
513
    
 
514
    // We set the encoding of the personality as direct encoding because we use
 
515
    // the function pointer. The encoding is not relative because the current
 
516
    // PC value may be bigger than the personality function pointer.
 
517
    if (PointerSize == 4) {
 
518
      JCE->emitByte(dwarf::DW_EH_PE_sdata4); 
 
519
      JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
 
520
    } else {
 
521
      JCE->emitByte(dwarf::DW_EH_PE_sdata8);
 
522
      JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
 
523
    }
 
524
 
 
525
    // LSDA encoding: This must match the encoding used in EmitEHFrame ()
 
526
    if (PointerSize == 4)
 
527
      JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
 
528
    else
 
529
      JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
 
530
    JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
 
531
  } else {
 
532
    JCE->emitULEB128Bytes(1);
 
533
    JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
 
534
  }
 
535
 
 
536
  std::vector<MachineMove> Moves;
 
537
  RI->getInitialFrameState(Moves);
 
538
  EmitFrameMoves(0, Moves);
 
539
 
 
540
  JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
 
541
 
 
542
  JCE->emitInt32At((uintptr_t*)StartCommonPtr,
 
543
                   (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
 
544
                               FrameCommonBeginPtr));
 
545
 
 
546
  return StartCommonPtr;
 
547
}
 
548
 
 
549
 
 
550
unsigned char*
 
551
JITDwarfEmitter::EmitEHFrame(const Function* Personality,
 
552
                             unsigned char* StartCommonPtr,
 
553
                             unsigned char* StartFunction, 
 
554
                             unsigned char* EndFunction,
 
555
                             unsigned char* ExceptionTable) const {
 
556
  unsigned PointerSize = TD->getPointerSize();
 
557
  
 
558
  // EH frame header.
 
559
  unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
 
560
  JCE->allocateSpace(4, 0);
 
561
  unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
 
562
  // FDE CIE Offset
 
563
  JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
 
564
  JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
 
565
  JCE->emitInt32(EndFunction - StartFunction);
 
566
 
 
567
  // If there is a personality and landing pads then point to the language
 
568
  // specific data area in the exception table.
 
569
  if (Personality) {
 
570
    JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
 
571
        
 
572
    if (PointerSize == 4) {
 
573
      if (!MMI->getLandingPads().empty())
 
574
        JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
 
575
      else
 
576
        JCE->emitInt32((int)0);
 
577
    } else {
 
578
      if (!MMI->getLandingPads().empty())
 
579
        JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
 
580
      else
 
581
        JCE->emitInt64((int)0);
 
582
    }
 
583
  } else {
 
584
    JCE->emitULEB128Bytes(0);
 
585
  }
 
586
      
 
587
  // Indicate locations of function specific  callee saved registers in
 
588
  // frame.
 
589
  EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
 
590
 
 
591
  JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
 
592
 
 
593
  // Indicate the size of the table
 
594
  JCE->emitInt32At((uintptr_t*)StartEHPtr,
 
595
                   (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
 
596
                               StartEHPtr));
 
597
 
 
598
  // Double zeroes for the unwind runtime
 
599
  if (PointerSize == 8) {
 
600
    JCE->emitInt64(0);
 
601
    JCE->emitInt64(0);
 
602
  } else {
 
603
    JCE->emitInt32(0);
 
604
    JCE->emitInt32(0);
 
605
  }
 
606
  
 
607
  return StartEHPtr;
 
608
}
 
609
 
 
610
unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
 
611
                                         JITCodeEmitter& jce,
 
612
                                         unsigned char* StartFunction,
 
613
                                         unsigned char* EndFunction) {
 
614
  const TargetMachine& TM = F.getTarget();
 
615
  TD = TM.getTargetData();
 
616
  stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
 
617
  RI = TM.getRegisterInfo();
 
618
  JCE = &jce;
 
619
  unsigned FinalSize = 0;
 
620
  
 
621
  FinalSize += GetExceptionTableSizeInBytes(&F);
 
622
      
 
623
  const std::vector<Function *> Personalities = MMI->getPersonalities();
 
624
  FinalSize += 
 
625
    GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
 
626
 
 
627
  FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()],
 
628
                                     StartFunction);
 
629
 
 
630
  return FinalSize;
 
631
}
 
632
 
 
633
/// RoundUpToAlign - Add the specified alignment to FinalSize and returns
 
634
/// the new value.
 
635
static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
 
636
  if (Alignment == 0) Alignment = 1;
 
637
  // Since we do not know where the buffer will be allocated, be pessimistic.
 
638
  return FinalSize + Alignment;
 
639
}
 
640
  
 
641
unsigned
 
642
JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
 
643
                                       unsigned char* StartFunction) const { 
 
644
  unsigned PointerSize = TD->getPointerSize();
 
645
  unsigned FinalSize = 0;
 
646
  // EH frame header.
 
647
  FinalSize += PointerSize;
 
648
  // FDE CIE Offset
 
649
  FinalSize += 3 * PointerSize;
 
650
  // If there is a personality and landing pads then point to the language
 
651
  // specific data area in the exception table.
 
652
  if (Personality) {
 
653
    FinalSize += MCAsmInfo::getULEB128Size(4); 
 
654
    FinalSize += PointerSize;
 
655
  } else {
 
656
    FinalSize += MCAsmInfo::getULEB128Size(0);
 
657
  }
 
658
      
 
659
  // Indicate locations of function specific  callee saved registers in
 
660
  // frame.
 
661
  FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
 
662
                                        MMI->getFrameMoves());
 
663
      
 
664
  FinalSize = RoundUpToAlign(FinalSize, 4);
 
665
  
 
666
  // Double zeroes for the unwind runtime
 
667
  FinalSize += 2 * PointerSize;
 
668
 
 
669
  return FinalSize;
 
670
}
 
671
 
 
672
unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 
 
673
  const {
 
674
 
 
675
  unsigned PointerSize = TD->getPointerSize();
 
676
  int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
 
677
          PointerSize : -PointerSize;
 
678
  unsigned FinalSize = 0; 
 
679
  // EH Common Frame header
 
680
  FinalSize += PointerSize;
 
681
  FinalSize += 4;
 
682
  FinalSize += 1;
 
683
  FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
 
684
  FinalSize += MCAsmInfo::getULEB128Size(1);
 
685
  FinalSize += MCAsmInfo::getSLEB128Size(stackGrowth);
 
686
  FinalSize += 1;
 
687
  
 
688
  if (Personality) {
 
689
    FinalSize += MCAsmInfo::getULEB128Size(7);
 
690
    
 
691
    // Encoding
 
692
    FinalSize+= 1;
 
693
    //Personality
 
694
    FinalSize += PointerSize;
 
695
    
 
696
    FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
 
697
    FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
 
698
      
 
699
  } else {
 
700
    FinalSize += MCAsmInfo::getULEB128Size(1);
 
701
    FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
 
702
  }
 
703
 
 
704
  std::vector<MachineMove> Moves;
 
705
  RI->getInitialFrameState(Moves);
 
706
  FinalSize += GetFrameMovesSizeInBytes(0, Moves);
 
707
  FinalSize = RoundUpToAlign(FinalSize, 4);
 
708
  return FinalSize;
 
709
}
 
710
 
 
711
unsigned
 
712
JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
 
713
                                  const std::vector<MachineMove> &Moves) const {
 
714
  unsigned PointerSize = TD->getPointerSize();
 
715
  int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
 
716
          PointerSize : -PointerSize;
 
717
  bool IsLocal = BaseLabelPtr;
 
718
  unsigned FinalSize = 0; 
 
719
 
 
720
  for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
 
721
    const MachineMove &Move = Moves[i];
 
722
    unsigned LabelID = Move.getLabelID();
 
723
    
 
724
    if (LabelID) {
 
725
      LabelID = MMI->MappedLabel(LabelID);
 
726
    
 
727
      // Throw out move if the label is invalid.
 
728
      if (!LabelID) continue;
 
729
    }
 
730
    
 
731
    intptr_t LabelPtr = 0;
 
732
    if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
 
733
 
 
734
    const MachineLocation &Dst = Move.getDestination();
 
735
    const MachineLocation &Src = Move.getSource();
 
736
    
 
737
    // Advance row if new location.
 
738
    if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
 
739
      FinalSize++;
 
740
      FinalSize += PointerSize;
 
741
      BaseLabelPtr = LabelPtr;
 
742
      IsLocal = true;
 
743
    }
 
744
    
 
745
    // If advancing cfa.
 
746
    if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
 
747
      if (!Src.isReg()) {
 
748
        if (Src.getReg() == MachineLocation::VirtualFP) {
 
749
          ++FinalSize;
 
750
        } else {
 
751
          ++FinalSize;
 
752
          unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true);
 
753
          FinalSize += MCAsmInfo::getULEB128Size(RegNum);
 
754
        }
 
755
        
 
756
        int Offset = -Src.getOffset();
 
757
        
 
758
        FinalSize += MCAsmInfo::getULEB128Size(Offset);
 
759
      } else {
 
760
        llvm_unreachable("Machine move no supported yet.");
 
761
      }
 
762
    } else if (Src.isReg() &&
 
763
      Src.getReg() == MachineLocation::VirtualFP) {
 
764
      if (Dst.isReg()) {
 
765
        ++FinalSize;
 
766
        unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true);
 
767
        FinalSize += MCAsmInfo::getULEB128Size(RegNum);
 
768
      } else {
 
769
        llvm_unreachable("Machine move no supported yet.");
 
770
      }
 
771
    } else {
 
772
      unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
 
773
      int Offset = Dst.getOffset() / stackGrowth;
 
774
      
 
775
      if (Offset < 0) {
 
776
        ++FinalSize;
 
777
        FinalSize += MCAsmInfo::getULEB128Size(Reg);
 
778
        FinalSize += MCAsmInfo::getSLEB128Size(Offset);
 
779
      } else if (Reg < 64) {
 
780
        ++FinalSize;
 
781
        FinalSize += MCAsmInfo::getULEB128Size(Offset);
 
782
      } else {
 
783
        ++FinalSize;
 
784
        FinalSize += MCAsmInfo::getULEB128Size(Reg);
 
785
        FinalSize += MCAsmInfo::getULEB128Size(Offset);
 
786
      }
 
787
    }
 
788
  }
 
789
  return FinalSize;
 
790
}
 
791
 
 
792
unsigned 
 
793
JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
 
794
  unsigned FinalSize = 0;
 
795
 
 
796
  // Map all labels and get rid of any dead landing pads.
 
797
  MMI->TidyLandingPads();
 
798
 
 
799
  const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
 
800
  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
 
801
  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
 
802
  if (PadInfos.empty()) return 0;
 
803
 
 
804
  // Sort the landing pads in order of their type ids.  This is used to fold
 
805
  // duplicate actions.
 
806
  SmallVector<const LandingPadInfo *, 64> LandingPads;
 
807
  LandingPads.reserve(PadInfos.size());
 
808
  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
 
809
    LandingPads.push_back(&PadInfos[i]);
 
810
  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
 
811
 
 
812
  // Negative type ids index into FilterIds, positive type ids index into
 
813
  // TypeInfos.  The value written for a positive type id is just the type
 
814
  // id itself.  For a negative type id, however, the value written is the
 
815
  // (negative) byte offset of the corresponding FilterIds entry.  The byte
 
816
  // offset is usually equal to the type id, because the FilterIds entries
 
817
  // are written using a variable width encoding which outputs one byte per
 
818
  // entry as long as the value written is not too large, but can differ.
 
819
  // This kind of complication does not occur for positive type ids because
 
820
  // type infos are output using a fixed width encoding.
 
821
  // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
 
822
  SmallVector<int, 16> FilterOffsets;
 
823
  FilterOffsets.reserve(FilterIds.size());
 
824
  int Offset = -1;
 
825
  for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
 
826
    E = FilterIds.end(); I != E; ++I) {
 
827
    FilterOffsets.push_back(Offset);
 
828
    Offset -= MCAsmInfo::getULEB128Size(*I);
 
829
  }
 
830
 
 
831
  // Compute the actions table and gather the first action index for each
 
832
  // landing pad site.
 
833
  SmallVector<ActionEntry, 32> Actions;
 
834
  SmallVector<unsigned, 64> FirstActions;
 
835
  FirstActions.reserve(LandingPads.size());
 
836
 
 
837
  int FirstAction = 0;
 
838
  unsigned SizeActions = 0;
 
839
  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
 
840
    const LandingPadInfo *LP = LandingPads[i];
 
841
    const std::vector<int> &TypeIds = LP->TypeIds;
 
842
    const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
 
843
    unsigned SizeSiteActions = 0;
 
844
 
 
845
    if (NumShared < TypeIds.size()) {
 
846
      unsigned SizeAction = 0;
 
847
      ActionEntry *PrevAction = 0;
 
848
 
 
849
      if (NumShared) {
 
850
        const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
 
851
        assert(Actions.size());
 
852
        PrevAction = &Actions.back();
 
853
        SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
 
854
          MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
 
855
        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
 
856
          SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
 
857
          SizeAction += -PrevAction->NextAction;
 
858
          PrevAction = PrevAction->Previous;
 
859
        }
 
860
      }
 
861
 
 
862
      // Compute the actions.
 
863
      for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
 
864
        int TypeID = TypeIds[I];
 
865
        assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
 
866
        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
 
867
        unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
 
868
 
 
869
        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
 
870
        SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
 
871
        SizeSiteActions += SizeAction;
 
872
 
 
873
        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
 
874
        Actions.push_back(Action);
 
875
 
 
876
        PrevAction = &Actions.back();
 
877
      }
 
878
 
 
879
      // Record the first action of the landing pad site.
 
880
      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
 
881
    } // else identical - re-use previous FirstAction
 
882
 
 
883
    FirstActions.push_back(FirstAction);
 
884
 
 
885
    // Compute this sites contribution to size.
 
886
    SizeActions += SizeSiteActions;
 
887
  }
 
888
 
 
889
  // Compute the call-site table.  Entries must be ordered by address.
 
890
  SmallVector<CallSiteEntry, 64> CallSites;
 
891
 
 
892
  RangeMapType PadMap;
 
893
  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
 
894
    const LandingPadInfo *LandingPad = LandingPads[i];
 
895
    for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
 
896
      unsigned BeginLabel = LandingPad->BeginLabels[j];
 
897
      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
 
898
      PadRange P = { i, j };
 
899
      PadMap[BeginLabel] = P;
 
900
    }
 
901
  }
 
902
 
 
903
  bool MayThrow = false;
 
904
  unsigned LastLabel = 0;
 
905
  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
 
906
        I != E; ++I) {
 
907
    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
 
908
          MI != E; ++MI) {
 
909
      if (!MI->isLabel()) {
 
910
        MayThrow |= MI->getDesc().isCall();
 
911
        continue;
 
912
      }
 
913
 
 
914
      unsigned BeginLabel = MI->getOperand(0).getImm();
 
915
      assert(BeginLabel && "Invalid label!");
 
916
 
 
917
      if (BeginLabel == LastLabel)
 
918
        MayThrow = false;
 
919
 
 
920
      RangeMapType::iterator L = PadMap.find(BeginLabel);
 
921
 
 
922
      if (L == PadMap.end())
 
923
        continue;
 
924
 
 
925
      PadRange P = L->second;
 
926
      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
 
927
 
 
928
      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
 
929
              "Inconsistent landing pad map!");
 
930
 
 
931
      // If some instruction between the previous try-range and this one may
 
932
      // throw, create a call-site entry with no landing pad for the region
 
933
      // between the try-ranges.
 
934
      if (MayThrow) {
 
935
        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
 
936
        CallSites.push_back(Site);
 
937
      }
 
938
 
 
939
      LastLabel = LandingPad->EndLabels[P.RangeIndex];
 
940
      CallSiteEntry Site = {BeginLabel, LastLabel,
 
941
        LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
 
942
 
 
943
      assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
 
944
              "Invalid landing pad!");
 
945
 
 
946
      // Try to merge with the previous call-site.
 
947
      if (CallSites.size()) {
 
948
        CallSiteEntry &Prev = CallSites.back();
 
949
        if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
 
950
          // Extend the range of the previous entry.
 
951
          Prev.EndLabel = Site.EndLabel;
 
952
          continue;
 
953
        }
 
954
      }
 
955
 
 
956
      // Otherwise, create a new call-site.
 
957
      CallSites.push_back(Site);
 
958
    }
 
959
  }
 
960
  // If some instruction between the previous try-range and the end of the
 
961
  // function may throw, create a call-site entry with no landing pad for the
 
962
  // region following the try-range.
 
963
  if (MayThrow) {
 
964
    CallSiteEntry Site = {LastLabel, 0, 0, 0};
 
965
    CallSites.push_back(Site);
 
966
  }
 
967
 
 
968
  // Final tallies.
 
969
  unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
 
970
                                            sizeof(int32_t) + // Site length.
 
971
                                            sizeof(int32_t)); // Landing pad.
 
972
  for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
 
973
    SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
 
974
 
 
975
  unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
 
976
 
 
977
  unsigned TypeOffset = sizeof(int8_t) + // Call site format
 
978
                        // Call-site table length
 
979
                        MCAsmInfo::getULEB128Size(SizeSites) + 
 
980
                        SizeSites + SizeActions + SizeTypes;
 
981
 
 
982
  unsigned TotalSize = sizeof(int8_t) + // LPStart format
 
983
                       sizeof(int8_t) + // TType format
 
984
                       MCAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
 
985
                       TypeOffset;
 
986
 
 
987
  unsigned SizeAlign = (4 - TotalSize) & 3;
 
988
 
 
989
  // Begin the exception table.
 
990
  FinalSize = RoundUpToAlign(FinalSize, 4);
 
991
  for (unsigned i = 0; i != SizeAlign; ++i) {
 
992
    ++FinalSize;
 
993
  }
 
994
  
 
995
  unsigned PointerSize = TD->getPointerSize();
 
996
 
 
997
  // Emit the header.
 
998
  ++FinalSize;
 
999
  // Asm->EOL("LPStart format (DW_EH_PE_omit)");
 
1000
  ++FinalSize;
 
1001
  // Asm->EOL("TType format (DW_EH_PE_absptr)");
 
1002
  ++FinalSize;
 
1003
  // Asm->EOL("TType base offset");
 
1004
  ++FinalSize;
 
1005
  // Asm->EOL("Call site format (DW_EH_PE_udata4)");
 
1006
  ++FinalSize;
 
1007
  // Asm->EOL("Call-site table length");
 
1008
 
 
1009
  // Emit the landing pad site information.
 
1010
  for (unsigned i = 0; i < CallSites.size(); ++i) {
 
1011
    CallSiteEntry &S = CallSites[i];
 
1012
 
 
1013
    // Asm->EOL("Region start");
 
1014
    FinalSize += PointerSize;
 
1015
    
 
1016
    //Asm->EOL("Region length");
 
1017
    FinalSize += PointerSize;
 
1018
 
 
1019
    // Asm->EOL("Landing pad");
 
1020
    FinalSize += PointerSize;
 
1021
 
 
1022
    FinalSize += MCAsmInfo::getULEB128Size(S.Action);
 
1023
    // Asm->EOL("Action");
 
1024
  }
 
1025
 
 
1026
  // Emit the actions.
 
1027
  for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
 
1028
    ActionEntry &Action = Actions[I];
 
1029
 
 
1030
    //Asm->EOL("TypeInfo index");
 
1031
    FinalSize += MCAsmInfo::getSLEB128Size(Action.ValueForTypeID);
 
1032
    //Asm->EOL("Next action");
 
1033
    FinalSize += MCAsmInfo::getSLEB128Size(Action.NextAction);
 
1034
  }
 
1035
 
 
1036
  // Emit the type ids.
 
1037
  for (unsigned M = TypeInfos.size(); M; --M) {
 
1038
    // Asm->EOL("TypeInfo");
 
1039
    FinalSize += PointerSize;
 
1040
  }
 
1041
 
 
1042
  // Emit the filter typeids.
 
1043
  for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
 
1044
    unsigned TypeID = FilterIds[j];
 
1045
    FinalSize += MCAsmInfo::getULEB128Size(TypeID);
 
1046
    //Asm->EOL("Filter TypeInfo index");
 
1047
  }
 
1048
  
 
1049
  FinalSize = RoundUpToAlign(FinalSize, 4);
 
1050
 
 
1051
  return FinalSize;
 
1052
}