1 //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains support for writing dwarf exception info into asm files.
12 //===----------------------------------------------------------------------===//
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/TargetData.h"
24 #include "llvm/Target/TargetFrameInfo.h"
25 #include "llvm/Target/TargetLoweringObjectFile.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/Target/TargetRegisterInfo.h"
28 #include "llvm/ADT/StringExtras.h"
31 static TimerGroup
&getDwarfTimerGroup() {
32 static TimerGroup
DwarfTimerGroup("Dwarf Exception");
33 return DwarfTimerGroup
;
36 DwarfException::DwarfException(raw_ostream
&OS
, AsmPrinter
*A
,
37 const TargetAsmInfo
*T
)
38 : Dwarf(OS
, A
, T
, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
39 shouldEmitTableModule(false), shouldEmitMovesModule(false),
41 if (TimePassesIsEnabled
)
42 ExceptionTimer
= new Timer("Dwarf Exception Writer",
43 getDwarfTimerGroup());
46 DwarfException::~DwarfException() {
47 delete ExceptionTimer
;
50 void DwarfException::EmitCommonEHFrame(const Function
*Personality
,
52 // Size and sign of stack growth.
54 Asm
->TM
.getFrameInfo()->getStackGrowthDirection() ==
55 TargetFrameInfo::StackGrowsUp
?
56 TD
->getPointerSize() : -TD
->getPointerSize();
58 // Begin eh frame section.
59 Asm
->SwitchToSection(Asm
->getObjFileLowering().getEHFrameSection());
61 if (TAI
->is_EHSymbolPrivate())
62 O
<< TAI
->getPrivateGlobalPrefix();
64 O
<< "EH_frame" << Index
<< ":\n";
65 EmitLabel("section_eh_frame", Index
);
67 // Define base labels.
68 EmitLabel("eh_frame_common", Index
);
70 // Define the eh frame length.
71 EmitDifference("eh_frame_common_end", Index
,
72 "eh_frame_common_begin", Index
, true);
73 Asm
->EOL("Length of Common Information Entry");
76 EmitLabel("eh_frame_common_begin", Index
);
77 Asm
->EmitInt32((int)0);
78 Asm
->EOL("CIE Identifier Tag");
79 Asm
->EmitInt8(dwarf::DW_CIE_VERSION
);
80 Asm
->EOL("CIE Version");
82 // The personality presence indicates that language specific information will
83 // show up in the eh frame.
84 Asm
->EmitString(Personality
? "zPLR" : "zR");
85 Asm
->EOL("CIE Augmentation");
88 Asm
->EmitULEB128Bytes(1);
89 Asm
->EOL("CIE Code Alignment Factor");
90 Asm
->EmitSLEB128Bytes(stackGrowth
);
91 Asm
->EOL("CIE Data Alignment Factor");
92 Asm
->EmitInt8(RI
->getDwarfRegNum(RI
->getRARegister(), true));
93 Asm
->EOL("CIE Return Address Column");
95 // If there is a personality, we need to indicate the functions location.
97 Asm
->EmitULEB128Bytes(7);
98 Asm
->EOL("Augmentation Size");
100 if (TAI
->getNeedsIndirectEncoding()) {
101 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
|
102 dwarf::DW_EH_PE_indirect
);
103 Asm
->EOL("Personality (pcrel sdata4 indirect)");
105 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
106 Asm
->EOL("Personality (pcrel sdata4)");
109 PrintRelDirective(true);
110 O
<< TAI
->getPersonalityPrefix();
111 Asm
->EmitExternalGlobal((const GlobalVariable
*)(Personality
));
112 O
<< TAI
->getPersonalitySuffix();
113 if (strcmp(TAI
->getPersonalitySuffix(), "+4@GOTPCREL"))
114 O
<< "-" << TAI
->getPCSymbol();
115 Asm
->EOL("Personality");
117 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
118 Asm
->EOL("LSDA Encoding (pcrel sdata4)");
120 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
121 Asm
->EOL("FDE Encoding (pcrel sdata4)");
123 Asm
->EmitULEB128Bytes(1);
124 Asm
->EOL("Augmentation Size");
126 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
127 Asm
->EOL("FDE Encoding (pcrel sdata4)");
130 // Indicate locations of general callee saved registers in frame.
131 std::vector
<MachineMove
> Moves
;
132 RI
->getInitialFrameState(Moves
);
133 EmitFrameMoves(NULL
, 0, Moves
, true);
135 // On Darwin the linker honors the alignment of eh_frame, which means it must
136 // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
137 // holes which confuse readers of eh_frame.
138 Asm
->EmitAlignment(TD
->getPointerSize() == sizeof(int32_t) ? 2 : 3,
140 EmitLabel("eh_frame_common_end", Index
);
145 /// EmitEHFrame - Emit function exception frame information.
147 void DwarfException::EmitEHFrame(const FunctionEHFrameInfo
&EHFrameInfo
) {
148 assert(!EHFrameInfo
.function
->hasAvailableExternallyLinkage() &&
149 "Should not emit 'available externally' functions at all");
151 const Function
*TheFunc
= EHFrameInfo
.function
;
153 Asm
->SwitchToSection(Asm
->getObjFileLowering().getEHFrameSection());
155 // Externally visible entry into the functions eh frame info. If the
156 // corresponding function is static, this should not be externally visible.
157 if (!TheFunc
->hasLocalLinkage())
158 if (const char *GlobalEHDirective
= TAI
->getGlobalEHDirective())
159 O
<< GlobalEHDirective
<< EHFrameInfo
.FnName
<< "\n";
161 // If corresponding function is weak definition, this should be too.
162 if (TheFunc
->isWeakForLinker() && TAI
->getWeakDefDirective())
163 O
<< TAI
->getWeakDefDirective() << EHFrameInfo
.FnName
<< "\n";
165 // If there are no calls then you can't unwind. This may mean we can omit the
166 // EH Frame, but some environments do not handle weak absolute symbols. If
167 // UnwindTablesMandatory is set we cannot do this optimization; the unwind
168 // info is to be available for non-EH uses.
169 if (!EHFrameInfo
.hasCalls
&& !UnwindTablesMandatory
&&
170 (!TheFunc
->isWeakForLinker() ||
171 !TAI
->getWeakDefDirective() ||
172 TAI
->getSupportsWeakOmittedEHFrame())) {
173 O
<< EHFrameInfo
.FnName
<< " = 0\n";
174 // This name has no connection to the function, so it might get
175 // dead-stripped when the function is not, erroneously. Prohibit
176 // dead-stripping unconditionally.
177 if (const char *UsedDirective
= TAI
->getUsedDirective())
178 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
180 O
<< EHFrameInfo
.FnName
<< ":\n";
183 EmitDifference("eh_frame_end", EHFrameInfo
.Number
,
184 "eh_frame_begin", EHFrameInfo
.Number
, true);
185 Asm
->EOL("Length of Frame Information Entry");
187 EmitLabel("eh_frame_begin", EHFrameInfo
.Number
);
189 EmitSectionOffset("eh_frame_begin", "eh_frame_common",
190 EHFrameInfo
.Number
, EHFrameInfo
.PersonalityIndex
,
193 Asm
->EOL("FDE CIE offset");
195 EmitReference("eh_func_begin", EHFrameInfo
.Number
, true, true);
196 Asm
->EOL("FDE initial location");
197 EmitDifference("eh_func_end", EHFrameInfo
.Number
,
198 "eh_func_begin", EHFrameInfo
.Number
, true);
199 Asm
->EOL("FDE address range");
201 // If there is a personality and landing pads then point to the language
202 // specific data area in the exception table.
203 if (EHFrameInfo
.PersonalityIndex
) {
204 Asm
->EmitULEB128Bytes(4);
205 Asm
->EOL("Augmentation size");
207 if (EHFrameInfo
.hasLandingPads
)
208 EmitReference("exception", EHFrameInfo
.Number
, true, true);
210 Asm
->EmitInt32((int)0);
211 Asm
->EOL("Language Specific Data Area");
213 Asm
->EmitULEB128Bytes(0);
214 Asm
->EOL("Augmentation size");
217 // Indicate locations of function specific callee saved registers in frame.
218 EmitFrameMoves("eh_func_begin", EHFrameInfo
.Number
, EHFrameInfo
.Moves
,
221 // On Darwin the linker honors the alignment of eh_frame, which means it
222 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you
223 // get holes which confuse readers of eh_frame.
224 Asm
->EmitAlignment(TD
->getPointerSize() == sizeof(int32_t) ? 2 : 3,
226 EmitLabel("eh_frame_end", EHFrameInfo
.Number
);
228 // If the function is marked used, this table should be also. We cannot
229 // make the mark unconditional in this case, since retaining the table also
230 // retains the function in this case, and there is code around that depends
231 // on unused functions (calling undefined externals) being dead-stripped to
232 // link correctly. Yes, there really is.
233 if (MMI
->isUsedFunction(EHFrameInfo
.function
))
234 if (const char *UsedDirective
= TAI
->getUsedDirective())
235 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
239 /// SharedTypeIds - How many leading type ids two landing pads have in common.
240 unsigned DwarfException::SharedTypeIds(const LandingPadInfo
*L
,
241 const LandingPadInfo
*R
) {
242 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
243 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
244 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
247 for (; Count
!= MinSize
; ++Count
)
248 if (LIds
[Count
] != RIds
[Count
])
254 /// PadLT - Order landing pads lexicographically by type id.
255 bool DwarfException::PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
256 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
257 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
258 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
260 for (unsigned i
= 0; i
!= MinSize
; ++i
)
261 if (LIds
[i
] != RIds
[i
])
262 return LIds
[i
] < RIds
[i
];
264 return LSize
< RSize
;
267 /// ComputeActionsTable - Compute the actions table and gather the first action
268 /// index for each landing pad site.
269 unsigned DwarfException::
270 ComputeActionsTable(const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
271 SmallVectorImpl
<ActionEntry
> &Actions
,
272 SmallVectorImpl
<unsigned> &FirstActions
) {
273 // Negative type IDs index into FilterIds. Positive type IDs index into
274 // TypeInfos. The value written for a positive type ID is just the type ID
275 // itself. For a negative type ID, however, the value written is the
276 // (negative) byte offset of the corresponding FilterIds entry. The byte
277 // offset is usually equal to the type ID (because the FilterIds entries are
278 // written using a variable width encoding, which outputs one byte per entry
279 // as long as the value written is not too large) but can differ. This kind
280 // of complication does not occur for positive type IDs because type infos are
281 // output using a fixed width encoding. FilterOffsets[i] holds the byte
282 // offset corresponding to FilterIds[i].
284 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
285 SmallVector
<int, 16> FilterOffsets
;
286 FilterOffsets
.reserve(FilterIds
.size());
289 for (std::vector
<unsigned>::const_iterator
290 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
!= E
; ++I
) {
291 FilterOffsets
.push_back(Offset
);
292 Offset
-= TargetAsmInfo::getULEB128Size(*I
);
295 FirstActions
.reserve(LandingPads
.size());
298 unsigned SizeActions
= 0;
299 const LandingPadInfo
*PrevLPI
= 0;
301 for (SmallVectorImpl
<const LandingPadInfo
*>::const_iterator
302 I
= LandingPads
.begin(), E
= LandingPads
.end(); I
!= E
; ++I
) {
303 const LandingPadInfo
*LPI
= *I
;
304 const std::vector
<int> &TypeIds
= LPI
->TypeIds
;
305 const unsigned NumShared
= PrevLPI
? SharedTypeIds(LPI
, PrevLPI
) : 0;
306 unsigned SizeSiteActions
= 0;
308 if (NumShared
< TypeIds
.size()) {
309 unsigned SizeAction
= 0;
310 ActionEntry
*PrevAction
= 0;
313 const unsigned SizePrevIds
= PrevLPI
->TypeIds
.size();
314 assert(Actions
.size());
315 PrevAction
= &Actions
.back();
316 SizeAction
= TargetAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
317 TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
319 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
321 TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
322 SizeAction
+= -PrevAction
->NextAction
;
323 PrevAction
= PrevAction
->Previous
;
327 // Compute the actions.
328 for (unsigned J
= NumShared
, M
= TypeIds
.size(); J
!= M
; ++J
) {
329 int TypeID
= TypeIds
[J
];
330 assert(-1 - TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
331 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
332 unsigned SizeTypeID
= TargetAsmInfo::getSLEB128Size(ValueForTypeID
);
334 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
335 SizeAction
= SizeTypeID
+ TargetAsmInfo::getSLEB128Size(NextAction
);
336 SizeSiteActions
+= SizeAction
;
338 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
339 Actions
.push_back(Action
);
340 PrevAction
= &Actions
.back();
343 // Record the first action of the landing pad site.
344 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
345 } // else identical - re-use previous FirstAction
347 FirstActions
.push_back(FirstAction
);
349 // Compute this sites contribution to size.
350 SizeActions
+= SizeSiteActions
;
358 /// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke
359 /// has a try-range containing the call, a non-zero landing pad and an
360 /// appropriate action. The entry for an ordinary call has a try-range
361 /// containing the call and zero for the landing pad and the action. Calls
362 /// marked 'nounwind' have no entry and must not be contained in the try-range
363 /// of any entry - they form gaps in the table. Entries must be ordered by
364 /// try-range address.
365 void DwarfException::
366 ComputeCallSiteTable(SmallVectorImpl
<CallSiteEntry
> &CallSites
,
367 const RangeMapType
&PadMap
,
368 const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
369 const SmallVectorImpl
<unsigned> &FirstActions
) {
370 // The end label of the previous invoke or nounwind try-range.
371 unsigned LastLabel
= 0;
373 // Whether there is a potentially throwing instruction (currently this means
374 // an ordinary call) between the end of the previous try-range and now.
375 bool SawPotentiallyThrowing
= false;
377 // Whether the last CallSite entry was for an invoke.
378 bool PreviousIsInvoke
= false;
380 // Visit all instructions in order of address.
381 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
383 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
385 if (!MI
->isLabel()) {
386 SawPotentiallyThrowing
|= MI
->getDesc().isCall();
390 unsigned BeginLabel
= MI
->getOperand(0).getImm();
391 assert(BeginLabel
&& "Invalid label!");
393 // End of the previous try-range?
394 if (BeginLabel
== LastLabel
)
395 SawPotentiallyThrowing
= false;
397 // Beginning of a new try-range?
398 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
399 if (L
== PadMap
.end())
400 // Nope, it was just some random label.
403 PadRange P
= L
->second
;
404 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
405 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
406 "Inconsistent landing pad map!");
408 // If some instruction between the previous try-range and this one may
409 // throw, create a call-site entry with no landing pad for the region
410 // between the try-ranges.
411 if (SawPotentiallyThrowing
) {
412 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
413 CallSites
.push_back(Site
);
414 PreviousIsInvoke
= false;
417 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
418 assert(BeginLabel
&& LastLabel
&& "Invalid landing pad!");
420 if (LandingPad
->LandingPadLabel
) {
421 // This try-range is for an invoke.
422 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
423 LandingPad
->LandingPadLabel
,
424 FirstActions
[P
.PadIndex
]};
426 // Try to merge with the previous call-site.
427 if (PreviousIsInvoke
) {
428 CallSiteEntry
&Prev
= CallSites
.back();
429 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
430 // Extend the range of the previous entry.
431 Prev
.EndLabel
= Site
.EndLabel
;
436 // Otherwise, create a new call-site.
437 CallSites
.push_back(Site
);
438 PreviousIsInvoke
= true;
441 PreviousIsInvoke
= false;
446 // If some instruction between the previous try-range and the end of the
447 // function may throw, create a call-site entry with no landing pad for the
448 // region following the try-range.
449 if (SawPotentiallyThrowing
) {
450 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
451 CallSites
.push_back(Site
);
455 /// EmitExceptionTable - Emit landing pads and actions.
457 /// The general organization of the table is complex, but the basic concepts are
458 /// easy. First there is a header which describes the location and organization
459 /// of the three components that follow.
461 /// 1. The landing pad site information describes the range of code covered by
462 /// the try. In our case it's an accumulation of the ranges covered by the
463 /// invokes in the try. There is also a reference to the landing pad that
464 /// handles the exception once processed. Finally an index into the actions
466 /// 2. The action table, in our case, is composed of pairs of type ids and next
467 /// action offset. Starting with the action index from the landing pad
468 /// site, each type Id is checked for a match to the current exception. If
469 /// it matches then the exception and type id are passed on to the landing
470 /// pad. Otherwise the next action is looked up. This chain is terminated
471 /// with a next action of zero. If no type id is found the the frame is
472 /// unwound and handling continues.
473 /// 3. Type id table contains references to all the C++ typeinfo for all
474 /// catches in the function. This tables is reversed indexed base 1.
475 void DwarfException::EmitExceptionTable() {
476 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
477 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
478 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
479 if (PadInfos
.empty()) return;
481 // Sort the landing pads in order of their type ids. This is used to fold
482 // duplicate actions.
483 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
484 LandingPads
.reserve(PadInfos
.size());
486 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
487 LandingPads
.push_back(&PadInfos
[i
]);
489 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
491 // Compute the actions table and gather the first action index for each
493 SmallVector
<ActionEntry
, 32> Actions
;
494 SmallVector
<unsigned, 64> FirstActions
;
495 unsigned SizeActions
= ComputeActionsTable(LandingPads
, Actions
, FirstActions
);
497 // Invokes and nounwind calls have entries in PadMap (due to being bracketed
498 // by try-range labels when lowered). Ordinary calls do not, so appropriate
499 // try-ranges for them need be deduced.
501 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
502 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
503 for (unsigned j
= 0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
504 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
505 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
506 PadRange P
= { i
, j
};
507 PadMap
[BeginLabel
] = P
;
511 // Compute the call-site table.
512 SmallVector
<CallSiteEntry
, 64> CallSites
;
513 ComputeCallSiteTable(CallSites
, PadMap
, LandingPads
, FirstActions
);
518 const unsigned SiteStartSize
= sizeof(int32_t); // DW_EH_PE_udata4
519 const unsigned SiteLengthSize
= sizeof(int32_t); // DW_EH_PE_udata4
520 const unsigned LandingPadSize
= sizeof(int32_t); // DW_EH_PE_udata4
521 unsigned SizeSites
= CallSites
.size() * (SiteStartSize
+
524 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
525 SizeSites
+= TargetAsmInfo::getULEB128Size(CallSites
[i
].Action
);
528 const unsigned TypeInfoSize
= TD
->getPointerSize(); // DW_EH_PE_absptr
529 unsigned SizeTypes
= TypeInfos
.size() * TypeInfoSize
;
531 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
532 TargetAsmInfo::getULEB128Size(SizeSites
) + // Call-site table length
533 SizeSites
+ SizeActions
+ SizeTypes
;
535 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
536 sizeof(int8_t) + // TType format
537 TargetAsmInfo::getULEB128Size(TypeOffset
) + // TType base offset
540 unsigned SizeAlign
= (4 - TotalSize
) & 3;
542 // Begin the exception table.
543 const MCSection
*LSDASection
= Asm
->getObjFileLowering().getLSDASection();
544 Asm
->SwitchToSection(LSDASection
);
545 Asm
->EmitAlignment(2, 0, 0, false);
546 O
<< "GCC_except_table" << SubprogramCount
<< ":\n";
548 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
553 EmitLabel("exception", SubprogramCount
);
556 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
557 Asm
->EOL("LPStart format (DW_EH_PE_omit)");
560 if (TypeInfos
.empty() && FilterIds
.empty()) {
561 // If there are no typeinfos or filters, there is nothing to emit, optimize
562 // by specifying the "omit" encoding.
563 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
564 Asm
->EOL("TType format (DW_EH_PE_omit)");
566 // Okay, we have actual filters or typeinfos to emit. As such, we need to
567 // pick a type encoding for them. We're about to emit a list of pointers to
568 // typeinfo objects at the end of the LSDA. However, unless we're in static
569 // mode, this reference will require a relocation by the dynamic linker.
571 // Because of this, we have a couple of options:
572 // 1) If we are in -static mode, we can always use an absolute reference
573 // from the LSDA, because the static linker will resolve it.
574 // 2) Otherwise, if the LSDA section is writable, we can output the direct
575 // reference to the typeinfo and allow the dynamic linker to relocate
576 // it. Since it is in a writable section, the dynamic linker won't
578 // 3) Finally, if we're in PIC mode and the LDSA section isn't writable,
579 // we need to use some form of indirection. For example, on Darwin,
580 // we can output a statically-relocatable reference to a dyld stub. The
581 // offset to the stub is constant, but the contents are in a section
582 // that is updated by the dynamic linker. This is easy enough, but we
583 // need to tell the personality function of the unwinder to indirect
584 // through the dyld stub.
586 // FIXME: When this is actually implemented, we'll have to emit the stubs
587 // somewhere. This predicate should be moved to a shared location that is
588 // in target-independent code.
590 if (LSDASection
->isWritable() ||
591 Asm
->TM
.getRelocationModel() == Reloc::Static
) {
592 Asm
->EmitInt8(DW_EH_PE_absptr
);
593 Asm
->EOL("TType format (DW_EH_PE_absptr)");
595 Asm
->EmitInt8(DW_EH_PE_pcrel
| DW_EH_PE_indirect
| DW_EH_PE_sdata4
);
596 Asm
->EOL("TType format (DW_EH_PE_pcrel | DW_EH_PE_indirect"
597 " | DW_EH_PE_sdata4)");
599 Asm
->EmitULEB128Bytes(TypeOffset
);
600 Asm
->EOL("TType base offset");
603 Asm
->EmitInt8(dwarf::DW_EH_PE_absptr
);
604 Asm
->EOL("TType format (DW_EH_PE_absptr)");
605 Asm
->EmitULEB128Bytes(TypeOffset
);
606 Asm
->EOL("TType base offset");
609 Asm
->EmitInt8(dwarf::DW_EH_PE_udata4
);
610 Asm
->EOL("Call site format (DW_EH_PE_udata4)");
611 Asm
->EmitULEB128Bytes(SizeSites
);
612 Asm
->EOL("Call-site table length");
614 // Emit the landing pad site information.
615 for (SmallVectorImpl
<CallSiteEntry
>::const_iterator
616 I
= CallSites
.begin(), E
= CallSites
.end(); I
!= E
; ++I
) {
617 const CallSiteEntry
&S
= *I
;
618 const char *BeginTag
;
619 unsigned BeginNumber
;
622 BeginTag
= "eh_func_begin";
623 BeginNumber
= SubprogramCount
;
626 BeginNumber
= S
.BeginLabel
;
629 EmitSectionOffset(BeginTag
, "eh_func_begin", BeginNumber
, SubprogramCount
,
631 Asm
->EOL("Region start");
634 EmitDifference("eh_func_end", SubprogramCount
, BeginTag
, BeginNumber
,
637 EmitDifference("label", S
.EndLabel
, BeginTag
, BeginNumber
, true);
639 Asm
->EOL("Region length");
644 EmitSectionOffset("label", "eh_func_begin", S
.PadLabel
, SubprogramCount
,
647 Asm
->EOL("Landing pad");
649 Asm
->EmitULEB128Bytes(S
.Action
);
654 for (SmallVectorImpl
<ActionEntry
>::const_iterator
655 I
= Actions
.begin(), E
= Actions
.end(); I
!= E
; ++I
) {
656 const ActionEntry
&Action
= *I
;
657 Asm
->EmitSLEB128Bytes(Action
.ValueForTypeID
);
658 Asm
->EOL("TypeInfo index");
659 Asm
->EmitSLEB128Bytes(Action
.NextAction
);
660 Asm
->EOL("Next action");
663 // Emit the type ids.
664 for (std::vector
<GlobalVariable
*>::const_reverse_iterator
665 I
= TypeInfos
.rbegin(), E
= TypeInfos
.rend(); I
!= E
; ++I
) {
666 GlobalVariable
*GV
= *I
;
671 O
<< Asm
->getGlobalLinkName(GV
, GLN
);
676 Asm
->EOL("TypeInfo");
679 // Emit the filter typeids.
680 for (std::vector
<unsigned>::const_iterator
681 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
682 unsigned TypeID
= *I
;
683 Asm
->EmitULEB128Bytes(TypeID
);
684 Asm
->EOL("Filter TypeInfo index");
687 Asm
->EmitAlignment(2, 0, 0, false);
690 /// EndModule - Emit all exception information that should come after the
692 void DwarfException::EndModule() {
693 if (TimePassesIsEnabled
)
694 ExceptionTimer
->startTimer();
696 if (shouldEmitMovesModule
|| shouldEmitTableModule
) {
697 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
698 for (unsigned i
= 0; i
< Personalities
.size(); ++i
)
699 EmitCommonEHFrame(Personalities
[i
], i
);
701 for (std::vector
<FunctionEHFrameInfo
>::iterator I
= EHFrames
.begin(),
702 E
= EHFrames
.end(); I
!= E
; ++I
)
706 if (TimePassesIsEnabled
)
707 ExceptionTimer
->stopTimer();
710 /// BeginFunction - Gather pre-function exception information. Assumes being
711 /// emitted immediately after the function entry point.
712 void DwarfException::BeginFunction(MachineFunction
*MF
) {
713 if (TimePassesIsEnabled
)
714 ExceptionTimer
->startTimer();
717 shouldEmitTable
= shouldEmitMoves
= false;
719 if (MMI
&& TAI
->doesSupportExceptionHandling()) {
720 // Map all labels and get rid of any dead landing pads.
721 MMI
->TidyLandingPads();
723 // If any landing pads survive, we need an EH table.
724 if (MMI
->getLandingPads().size())
725 shouldEmitTable
= true;
727 // See if we need frame move info.
728 if (!MF
->getFunction()->doesNotThrow() || UnwindTablesMandatory
)
729 shouldEmitMoves
= true;
731 if (shouldEmitMoves
|| shouldEmitTable
)
732 // Assumes in correct section after the entry point.
733 EmitLabel("eh_func_begin", ++SubprogramCount
);
736 shouldEmitTableModule
|= shouldEmitTable
;
737 shouldEmitMovesModule
|= shouldEmitMoves
;
739 if (TimePassesIsEnabled
)
740 ExceptionTimer
->stopTimer();
743 /// EndFunction - Gather and emit post-function exception information.
745 void DwarfException::EndFunction() {
746 if (TimePassesIsEnabled
)
747 ExceptionTimer
->startTimer();
749 if (shouldEmitMoves
|| shouldEmitTable
) {
750 EmitLabel("eh_func_end", SubprogramCount
);
751 EmitExceptionTable();
753 // Save EH frame information
755 FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF
),
757 MMI
->getPersonalityIndex(),
758 MF
->getFrameInfo()->hasCalls(),
759 !MMI
->getLandingPads().empty(),
760 MMI
->getFrameMoves(),
764 if (TimePassesIsEnabled
)
765 ExceptionTimer
->stopTimer();