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/MachineFunction.h"
19 #include "llvm/CodeGen/MachineLocation.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/Target/TargetData.h"
23 #include "llvm/Target/TargetFrameInfo.h"
24 #include "llvm/Target/TargetLoweringObjectFile.h"
25 #include "llvm/Target/TargetOptions.h"
26 #include "llvm/Target/TargetRegisterInfo.h"
27 #include "llvm/Support/Dwarf.h"
28 #include "llvm/Support/Mangler.h"
29 #include "llvm/Support/Timer.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringExtras.h"
35 static TimerGroup
&getDwarfTimerGroup() {
36 static TimerGroup
DwarfTimerGroup("Dwarf Exception");
37 return DwarfTimerGroup
;
40 DwarfException::DwarfException(raw_ostream
&OS
, AsmPrinter
*A
,
42 : Dwarf(OS
, A
, T
, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
43 shouldEmitTableModule(false), shouldEmitMovesModule(false),
45 if (TimePassesIsEnabled
)
46 ExceptionTimer
= new Timer("Dwarf Exception Writer",
47 getDwarfTimerGroup());
50 DwarfException::~DwarfException() {
51 delete ExceptionTimer
;
54 /// EmitCIE - Emit a Common Information Entry (CIE). This holds information that
55 /// is shared among many Frame Description Entries. There is at least one CIE
56 /// in every non-empty .debug_frame section.
57 void DwarfException::EmitCIE(const Function
*Personality
, unsigned Index
) {
58 // Size and sign of stack growth.
60 Asm
->TM
.getFrameInfo()->getStackGrowthDirection() ==
61 TargetFrameInfo::StackGrowsUp
?
62 TD
->getPointerSize() : -TD
->getPointerSize();
64 // Begin eh frame section.
65 Asm
->OutStreamer
.SwitchSection(Asm
->getObjFileLowering().getEHFrameSection());
67 if (MAI
->is_EHSymbolPrivate())
68 O
<< MAI
->getPrivateGlobalPrefix();
70 O
<< "EH_frame" << Index
<< ":\n";
71 EmitLabel("section_eh_frame", Index
);
73 // Define base labels.
74 EmitLabel("eh_frame_common", Index
);
76 // Define the eh frame length.
77 EmitDifference("eh_frame_common_end", Index
,
78 "eh_frame_common_begin", Index
, true);
79 Asm
->EOL("Length of Common Information Entry");
82 EmitLabel("eh_frame_common_begin", Index
);
83 Asm
->EmitInt32((int)0);
84 Asm
->EOL("CIE Identifier Tag");
85 Asm
->EmitInt8(dwarf::DW_CIE_VERSION
);
86 Asm
->EOL("CIE Version");
88 // The personality presence indicates that language specific information will
89 // show up in the eh frame.
90 Asm
->EmitString(Personality
? "zPLR" : "zR");
91 Asm
->EOL("CIE Augmentation");
94 Asm
->EmitULEB128Bytes(1);
95 Asm
->EOL("CIE Code Alignment Factor");
96 Asm
->EmitSLEB128Bytes(stackGrowth
);
97 Asm
->EOL("CIE Data Alignment Factor");
98 Asm
->EmitInt8(RI
->getDwarfRegNum(RI
->getRARegister(), true));
99 Asm
->EOL("CIE Return Address Column");
101 // If there is a personality, we need to indicate the function's location.
103 Asm
->EmitULEB128Bytes(7);
104 Asm
->EOL("Augmentation Size");
106 if (MAI
->getNeedsIndirectEncoding()) {
107 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
|
108 dwarf::DW_EH_PE_indirect
);
109 Asm
->EOL("Personality (pcrel sdata4 indirect)");
111 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
112 Asm
->EOL("Personality (pcrel sdata4)");
115 PrintRelDirective(true);
116 O
<< MAI
->getPersonalityPrefix();
117 Asm
->EmitExternalGlobal((const GlobalVariable
*)(Personality
));
118 O
<< MAI
->getPersonalitySuffix();
119 if (strcmp(MAI
->getPersonalitySuffix(), "+4@GOTPCREL"))
120 O
<< "-" << MAI
->getPCSymbol();
121 Asm
->EOL("Personality");
123 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
124 Asm
->EOL("LSDA Encoding (pcrel sdata4)");
126 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
127 Asm
->EOL("FDE Encoding (pcrel sdata4)");
129 Asm
->EmitULEB128Bytes(1);
130 Asm
->EOL("Augmentation Size");
132 Asm
->EmitInt8(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
133 Asm
->EOL("FDE Encoding (pcrel sdata4)");
136 // Indicate locations of general callee saved registers in frame.
137 std::vector
<MachineMove
> Moves
;
138 RI
->getInitialFrameState(Moves
);
139 EmitFrameMoves(NULL
, 0, Moves
, true);
141 // On Darwin the linker honors the alignment of eh_frame, which means it must
142 // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
143 // holes which confuse readers of eh_frame.
144 Asm
->EmitAlignment(TD
->getPointerSize() == sizeof(int32_t) ? 2 : 3,
146 EmitLabel("eh_frame_common_end", Index
);
151 /// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
152 void DwarfException::EmitFDE(const FunctionEHFrameInfo
&EHFrameInfo
) {
153 assert(!EHFrameInfo
.function
->hasAvailableExternallyLinkage() &&
154 "Should not emit 'available externally' functions at all");
156 const Function
*TheFunc
= EHFrameInfo
.function
;
158 Asm
->OutStreamer
.SwitchSection(Asm
->getObjFileLowering().getEHFrameSection());
160 // Externally visible entry into the functions eh frame info. If the
161 // corresponding function is static, this should not be externally visible.
162 if (!TheFunc
->hasLocalLinkage())
163 if (const char *GlobalEHDirective
= MAI
->getGlobalEHDirective())
164 O
<< GlobalEHDirective
<< EHFrameInfo
.FnName
<< "\n";
166 // If corresponding function is weak definition, this should be too.
167 if (TheFunc
->isWeakForLinker() && MAI
->getWeakDefDirective())
168 O
<< MAI
->getWeakDefDirective() << EHFrameInfo
.FnName
<< "\n";
170 // If there are no calls then you can't unwind. This may mean we can omit the
171 // EH Frame, but some environments do not handle weak absolute symbols. If
172 // UnwindTablesMandatory is set we cannot do this optimization; the unwind
173 // info is to be available for non-EH uses.
174 if (!EHFrameInfo
.hasCalls
&& !UnwindTablesMandatory
&&
175 (!TheFunc
->isWeakForLinker() ||
176 !MAI
->getWeakDefDirective() ||
177 MAI
->getSupportsWeakOmittedEHFrame())) {
178 O
<< EHFrameInfo
.FnName
<< " = 0\n";
179 // This name has no connection to the function, so it might get
180 // dead-stripped when the function is not, erroneously. Prohibit
181 // dead-stripping unconditionally.
182 if (const char *UsedDirective
= MAI
->getUsedDirective())
183 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
185 O
<< EHFrameInfo
.FnName
<< ":\n";
188 EmitDifference("eh_frame_end", EHFrameInfo
.Number
,
189 "eh_frame_begin", EHFrameInfo
.Number
, true);
190 Asm
->EOL("Length of Frame Information Entry");
192 EmitLabel("eh_frame_begin", EHFrameInfo
.Number
);
194 EmitSectionOffset("eh_frame_begin", "eh_frame_common",
195 EHFrameInfo
.Number
, EHFrameInfo
.PersonalityIndex
,
198 Asm
->EOL("FDE CIE offset");
200 EmitReference("eh_func_begin", EHFrameInfo
.Number
, true, true);
201 Asm
->EOL("FDE initial location");
202 EmitDifference("eh_func_end", EHFrameInfo
.Number
,
203 "eh_func_begin", EHFrameInfo
.Number
, true);
204 Asm
->EOL("FDE address range");
206 // If there is a personality and landing pads then point to the language
207 // specific data area in the exception table.
208 if (MMI
->getPersonalities()[0] != NULL
) {
209 bool is4Byte
= TD
->getPointerSize() == sizeof(int32_t);
211 Asm
->EmitULEB128Bytes(is4Byte
? 4 : 8);
212 Asm
->EOL("Augmentation size");
214 if (EHFrameInfo
.hasLandingPads
)
215 EmitReference("exception", EHFrameInfo
.Number
, true, false);
218 Asm
->EmitInt32((int)0);
220 Asm
->EmitInt64((int)0);
222 Asm
->EOL("Language Specific Data Area");
224 Asm
->EmitULEB128Bytes(0);
225 Asm
->EOL("Augmentation size");
228 // Indicate locations of function specific callee saved registers in frame.
229 EmitFrameMoves("eh_func_begin", EHFrameInfo
.Number
, EHFrameInfo
.Moves
,
232 // On Darwin the linker honors the alignment of eh_frame, which means it
233 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you
234 // get holes which confuse readers of eh_frame.
235 Asm
->EmitAlignment(TD
->getPointerSize() == sizeof(int32_t) ? 2 : 3,
237 EmitLabel("eh_frame_end", EHFrameInfo
.Number
);
239 // If the function is marked used, this table should be also. We cannot
240 // make the mark unconditional in this case, since retaining the table also
241 // retains the function in this case, and there is code around that depends
242 // on unused functions (calling undefined externals) being dead-stripped to
243 // link correctly. Yes, there really is.
244 if (MMI
->isUsedFunction(EHFrameInfo
.function
))
245 if (const char *UsedDirective
= MAI
->getUsedDirective())
246 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
252 /// SharedTypeIds - How many leading type ids two landing pads have in common.
253 unsigned DwarfException::SharedTypeIds(const LandingPadInfo
*L
,
254 const LandingPadInfo
*R
) {
255 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
256 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
257 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
260 for (; Count
!= MinSize
; ++Count
)
261 if (LIds
[Count
] != RIds
[Count
])
267 /// PadLT - Order landing pads lexicographically by type id.
268 bool DwarfException::PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
269 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
270 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
271 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
273 for (unsigned i
= 0; i
!= MinSize
; ++i
)
274 if (LIds
[i
] != RIds
[i
])
275 return LIds
[i
] < RIds
[i
];
277 return LSize
< RSize
;
280 /// ComputeActionsTable - Compute the actions table and gather the first action
281 /// index for each landing pad site.
282 unsigned DwarfException::
283 ComputeActionsTable(const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
284 SmallVectorImpl
<ActionEntry
> &Actions
,
285 SmallVectorImpl
<unsigned> &FirstActions
) {
287 // The action table follows the call-site table in the LSDA. The individual
288 // records are of two types:
291 // * Exception specification
293 // The two record kinds have the same format, with only small differences.
294 // They are distinguished by the "switch value" field: Catch clauses
295 // (TypeInfos) have strictly positive switch values, and exception
296 // specifications (FilterIds) have strictly negative switch values. Value 0
297 // indicates a catch-all clause.
299 // Negative type IDs index into FilterIds. Positive type IDs index into
300 // TypeInfos. The value written for a positive type ID is just the type ID
301 // itself. For a negative type ID, however, the value written is the
302 // (negative) byte offset of the corresponding FilterIds entry. The byte
303 // offset is usually equal to the type ID (because the FilterIds entries are
304 // written using a variable width encoding, which outputs one byte per entry
305 // as long as the value written is not too large) but can differ. This kind
306 // of complication does not occur for positive type IDs because type infos are
307 // output using a fixed width encoding. FilterOffsets[i] holds the byte
308 // offset corresponding to FilterIds[i].
310 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
311 SmallVector
<int, 16> FilterOffsets
;
312 FilterOffsets
.reserve(FilterIds
.size());
315 for (std::vector
<unsigned>::const_iterator
316 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
!= E
; ++I
) {
317 FilterOffsets
.push_back(Offset
);
318 Offset
-= MCAsmInfo::getULEB128Size(*I
);
321 FirstActions
.reserve(LandingPads
.size());
324 unsigned SizeActions
= 0;
325 const LandingPadInfo
*PrevLPI
= 0;
327 for (SmallVectorImpl
<const LandingPadInfo
*>::const_iterator
328 I
= LandingPads
.begin(), E
= LandingPads
.end(); I
!= E
; ++I
) {
329 const LandingPadInfo
*LPI
= *I
;
330 const std::vector
<int> &TypeIds
= LPI
->TypeIds
;
331 const unsigned NumShared
= PrevLPI
? SharedTypeIds(LPI
, PrevLPI
) : 0;
332 unsigned SizeSiteActions
= 0;
334 if (NumShared
< TypeIds
.size()) {
335 unsigned SizeAction
= 0;
336 ActionEntry
*PrevAction
= 0;
339 const unsigned SizePrevIds
= PrevLPI
->TypeIds
.size();
340 assert(Actions
.size());
341 PrevAction
= &Actions
.back();
342 SizeAction
= MCAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
343 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
345 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
347 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
348 SizeAction
+= -PrevAction
->NextAction
;
349 PrevAction
= PrevAction
->Previous
;
353 // Compute the actions.
354 for (unsigned J
= NumShared
, M
= TypeIds
.size(); J
!= M
; ++J
) {
355 int TypeID
= TypeIds
[J
];
356 assert(-1 - TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
357 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
358 unsigned SizeTypeID
= MCAsmInfo::getSLEB128Size(ValueForTypeID
);
360 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
361 SizeAction
= SizeTypeID
+ MCAsmInfo::getSLEB128Size(NextAction
);
362 SizeSiteActions
+= SizeAction
;
364 ActionEntry Action
= { ValueForTypeID
, NextAction
, PrevAction
};
365 Actions
.push_back(Action
);
366 PrevAction
= &Actions
.back();
369 // Record the first action of the landing pad site.
370 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
371 } // else identical - re-use previous FirstAction
373 // Information used when created the call-site table. The action record
374 // field of the call site record is the offset of the first associated
375 // action record, relative to the start of the actions table. This value is
376 // biased by 1 (1 in dicating the start of the actions table), and 0
377 // indicates that there are no actions.
378 FirstActions
.push_back(FirstAction
);
380 // Compute this sites contribution to size.
381 SizeActions
+= SizeSiteActions
;
389 /// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke
390 /// has a try-range containing the call, a non-zero landing pad, and an
391 /// appropriate action. The entry for an ordinary call has a try-range
392 /// containing the call and zero for the landing pad and the action. Calls
393 /// marked 'nounwind' have no entry and must not be contained in the try-range
394 /// of any entry - they form gaps in the table. Entries must be ordered by
395 /// try-range address.
396 void DwarfException::
397 ComputeCallSiteTable(SmallVectorImpl
<CallSiteEntry
> &CallSites
,
398 const RangeMapType
&PadMap
,
399 const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
400 const SmallVectorImpl
<unsigned> &FirstActions
) {
401 // The end label of the previous invoke or nounwind try-range.
402 unsigned LastLabel
= 0;
404 // Whether there is a potentially throwing instruction (currently this means
405 // an ordinary call) between the end of the previous try-range and now.
406 bool SawPotentiallyThrowing
= false;
408 // Whether the last CallSite entry was for an invoke.
409 bool PreviousIsInvoke
= false;
411 // Visit all instructions in order of address.
412 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
414 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
416 if (!MI
->isLabel()) {
417 SawPotentiallyThrowing
|= MI
->getDesc().isCall();
421 unsigned BeginLabel
= MI
->getOperand(0).getImm();
422 assert(BeginLabel
&& "Invalid label!");
424 // End of the previous try-range?
425 if (BeginLabel
== LastLabel
)
426 SawPotentiallyThrowing
= false;
428 // Beginning of a new try-range?
429 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
430 if (L
== PadMap
.end())
431 // Nope, it was just some random label.
434 const PadRange
&P
= L
->second
;
435 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
436 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
437 "Inconsistent landing pad map!");
439 // For Dwarf exception handling (SjLj handling doesn't use this). If some
440 // instruction between the previous try-range and this one may throw,
441 // create a call-site entry with no landing pad for the region between the
443 if (SawPotentiallyThrowing
&&
444 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
445 CallSiteEntry Site
= { LastLabel
, BeginLabel
, 0, 0 };
446 CallSites
.push_back(Site
);
447 PreviousIsInvoke
= false;
450 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
451 assert(BeginLabel
&& LastLabel
&& "Invalid landing pad!");
453 if (LandingPad
->LandingPadLabel
) {
454 // This try-range is for an invoke.
455 CallSiteEntry Site
= {
458 LandingPad
->LandingPadLabel
,
459 FirstActions
[P
.PadIndex
]
462 // Try to merge with the previous call-site. SJLJ doesn't do this
463 if (PreviousIsInvoke
&&
464 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
465 CallSiteEntry
&Prev
= CallSites
.back();
466 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
467 // Extend the range of the previous entry.
468 Prev
.EndLabel
= Site
.EndLabel
;
473 // Otherwise, create a new call-site.
474 CallSites
.push_back(Site
);
475 PreviousIsInvoke
= true;
478 PreviousIsInvoke
= false;
483 // If some instruction between the previous try-range and the end of the
484 // function may throw, create a call-site entry with no landing pad for the
485 // region following the try-range.
486 if (SawPotentiallyThrowing
&&
487 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
488 CallSiteEntry Site
= { LastLabel
, 0, 0, 0 };
489 CallSites
.push_back(Site
);
493 /// EmitExceptionTable - Emit landing pads and actions.
495 /// The general organization of the table is complex, but the basic concepts are
496 /// easy. First there is a header which describes the location and organization
497 /// of the three components that follow.
499 /// 1. The landing pad site information describes the range of code covered by
500 /// the try. In our case it's an accumulation of the ranges covered by the
501 /// invokes in the try. There is also a reference to the landing pad that
502 /// handles the exception once processed. Finally an index into the actions
504 /// 2. The action table, in our case, is composed of pairs of type IDs and next
505 /// action offset. Starting with the action index from the landing pad
506 /// site, each type ID is checked for a match to the current exception. If
507 /// it matches then the exception and type id are passed on to the landing
508 /// pad. Otherwise the next action is looked up. This chain is terminated
509 /// with a next action of zero. If no type id is found the the frame is
510 /// unwound and handling continues.
511 /// 3. Type ID table contains references to all the C++ typeinfo for all
512 /// catches in the function. This tables is reversed indexed base 1.
513 void DwarfException::EmitExceptionTable() {
514 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
515 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
516 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
517 if (PadInfos
.empty()) return;
519 // Sort the landing pads in order of their type ids. This is used to fold
520 // duplicate actions.
521 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
522 LandingPads
.reserve(PadInfos
.size());
524 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
525 LandingPads
.push_back(&PadInfos
[i
]);
527 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
529 // Compute the actions table and gather the first action index for each
531 SmallVector
<ActionEntry
, 32> Actions
;
532 SmallVector
<unsigned, 64> FirstActions
;
533 unsigned SizeActions
= ComputeActionsTable(LandingPads
, Actions
, FirstActions
);
535 // Invokes and nounwind calls have entries in PadMap (due to being bracketed
536 // by try-range labels when lowered). Ordinary calls do not, so appropriate
537 // try-ranges for them need be deduced when using Dwarf exception handling.
539 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
540 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
541 for (unsigned j
= 0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
542 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
543 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
544 PadRange P
= { i
, j
};
545 PadMap
[BeginLabel
] = P
;
549 // Compute the call-site table.
550 SmallVector
<CallSiteEntry
, 64> CallSites
;
551 ComputeCallSiteTable(CallSites
, PadMap
, LandingPads
, FirstActions
);
556 const unsigned SiteStartSize
= sizeof(int32_t); // DW_EH_PE_udata4
557 const unsigned SiteLengthSize
= sizeof(int32_t); // DW_EH_PE_udata4
558 const unsigned LandingPadSize
= sizeof(int32_t); // DW_EH_PE_udata4
561 bool HaveTTData
= (MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
)
562 ? (!TypeInfos
.empty() || !FilterIds
.empty()) : true;
565 if (MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
) {
568 SizeSites
= CallSites
.size() *
569 (SiteStartSize
+ SiteLengthSize
+ LandingPadSize
);
570 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
) {
571 SizeSites
+= MCAsmInfo::getULEB128Size(CallSites
[i
].Action
);
572 if (MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
)
573 SizeSites
+= MCAsmInfo::getULEB128Size(i
);
576 const unsigned TypeInfoSize
= TD
->getPointerSize(); // DW_EH_PE_absptr
577 unsigned SizeTypes
= TypeInfos
.size() * TypeInfoSize
;
579 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
580 MCAsmInfo::getULEB128Size(SizeSites
) + // Call-site table length
581 SizeSites
+ SizeActions
+ SizeTypes
;
583 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
584 sizeof(int8_t) + // TType format
586 MCAsmInfo::getULEB128Size(TypeOffset
) : 0) + // TType base offset
589 unsigned SizeAlign
= (4 - TotalSize
) & 3;
591 // Begin the exception table.
592 const MCSection
*LSDASection
= Asm
->getObjFileLowering().getLSDASection();
593 Asm
->OutStreamer
.SwitchSection(LSDASection
);
594 Asm
->EmitAlignment(2, 0, 0, false);
595 O
<< "GCC_except_table" << SubprogramCount
<< ":\n";
597 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
602 EmitLabel("exception", SubprogramCount
);
603 if (MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
) {
604 SmallString
<16> LSDAName
;
605 raw_svector_ostream(LSDAName
) << MAI
->getPrivateGlobalPrefix() <<
606 "_LSDA_" << Asm
->getFunctionNumber();
607 O
<< LSDAName
.str() << ":\n";
611 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
612 Asm
->EOL("@LPStart format (DW_EH_PE_omit)");
615 if (TypeInfos
.empty() && FilterIds
.empty()) {
616 // If there are no typeinfos or filters, there is nothing to emit, optimize
617 // by specifying the "omit" encoding.
618 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
619 Asm
->EOL("@TType format (DW_EH_PE_omit)");
621 // Okay, we have actual filters or typeinfos to emit. As such, we need to
622 // pick a type encoding for them. We're about to emit a list of pointers to
623 // typeinfo objects at the end of the LSDA. However, unless we're in static
624 // mode, this reference will require a relocation by the dynamic linker.
626 // Because of this, we have a couple of options:
627 // 1) If we are in -static mode, we can always use an absolute reference
628 // from the LSDA, because the static linker will resolve it.
629 // 2) Otherwise, if the LSDA section is writable, we can output the direct
630 // reference to the typeinfo and allow the dynamic linker to relocate
631 // it. Since it is in a writable section, the dynamic linker won't
633 // 3) Finally, if we're in PIC mode and the LDSA section isn't writable,
634 // we need to use some form of indirection. For example, on Darwin,
635 // we can output a statically-relocatable reference to a dyld stub. The
636 // offset to the stub is constant, but the contents are in a section
637 // that is updated by the dynamic linker. This is easy enough, but we
638 // need to tell the personality function of the unwinder to indirect
639 // through the dyld stub.
641 // FIXME: When this is actually implemented, we'll have to emit the stubs
642 // somewhere. This predicate should be moved to a shared location that is
643 // in target-independent code.
645 if (LSDASection
->isWritable() ||
646 Asm
->TM
.getRelocationModel() == Reloc::Static
) {
647 Asm
->EmitInt8(DW_EH_PE_absptr
);
648 Asm
->EOL("TType format (DW_EH_PE_absptr)");
650 Asm
->EmitInt8(DW_EH_PE_pcrel
| DW_EH_PE_indirect
| DW_EH_PE_sdata4
);
651 Asm
->EOL("TType format (DW_EH_PE_pcrel | DW_EH_PE_indirect"
652 " | DW_EH_PE_sdata4)");
654 Asm
->EmitULEB128Bytes(TypeOffset
);
655 Asm
->EOL("TType base offset");
658 // For SjLj exceptions, if there is no TypeInfo, then we just explicitly
659 // say that we're omitting that bit.
660 // FIXME: does this apply to Dwarf also? The above #if 0 implies yes?
662 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
663 Asm
->EOL("@TType format (DW_EH_PE_omit)");
665 Asm
->EmitInt8(dwarf::DW_EH_PE_absptr
);
666 Asm
->EOL("@TType format (DW_EH_PE_absptr)");
667 Asm
->EmitULEB128Bytes(TypeOffset
);
668 Asm
->EOL("@TType base offset");
672 // SjLj Exception handilng
673 if (MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
) {
674 Asm
->EmitInt8(dwarf::DW_EH_PE_udata4
);
675 Asm
->EOL("Call site format (DW_EH_PE_udata4)");
676 Asm
->EmitULEB128Bytes(SizeSites
);
677 Asm
->EOL("Call site table length");
679 // Emit the landing pad site information.
681 for (SmallVectorImpl
<CallSiteEntry
>::const_iterator
682 I
= CallSites
.begin(), E
= CallSites
.end(); I
!= E
; ++I
, ++idx
) {
683 const CallSiteEntry
&S
= *I
;
685 // Offset of the landing pad, counted in 16-byte bundles relative to the
687 Asm
->EmitULEB128Bytes(idx
);
688 Asm
->EOL("Landing pad");
690 // Offset of the first associated action record, relative to the start of
691 // the action table. This value is biased by 1 (1 indicates the start of
692 // the action table), and 0 indicates that there are no actions.
693 Asm
->EmitULEB128Bytes(S
.Action
);
697 // DWARF Exception handling
698 assert(MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
);
700 // The call-site table is a list of all call sites that may throw an
701 // exception (including C++ 'throw' statements) in the procedure
702 // fragment. It immediately follows the LSDA header. Each entry indicates,
703 // for a given call, the first corresponding action record and corresponding
706 // The table begins with the number of bytes, stored as an LEB128
707 // compressed, unsigned integer. The records immediately follow the record
708 // count. They are sorted in increasing call-site address. Each record
711 // * The position of the call-site.
712 // * The position of the landing pad.
713 // * The first action record for that call site.
715 // A missing entry in the call-site table indicates that a call is not
716 // supposed to throw. Such calls include:
718 // * Calls to destructors within cleanup code. C++ semantics forbids these
720 // * Calls to intrinsic routines in the standard library which are known
721 // not to throw (sin, memcpy, et al).
723 // If the runtime does not find the call-site entry for a given call, it
724 // will call `terminate()'.
726 // Emit the landing pad call site table.
727 Asm
->EmitInt8(dwarf::DW_EH_PE_udata4
);
728 Asm
->EOL("Call site format (DW_EH_PE_udata4)");
729 Asm
->EmitULEB128Bytes(SizeSites
);
730 Asm
->EOL("Call site table size");
732 for (SmallVectorImpl
<CallSiteEntry
>::const_iterator
733 I
= CallSites
.begin(), E
= CallSites
.end(); I
!= E
; ++I
) {
734 const CallSiteEntry
&S
= *I
;
735 const char *BeginTag
;
736 unsigned BeginNumber
;
739 BeginTag
= "eh_func_begin";
740 BeginNumber
= SubprogramCount
;
743 BeginNumber
= S
.BeginLabel
;
746 // Offset of the call site relative to the previous call site, counted in
747 // number of 16-byte bundles. The first call site is counted relative to
748 // the start of the procedure fragment.
749 EmitSectionOffset(BeginTag
, "eh_func_begin", BeginNumber
, SubprogramCount
,
751 Asm
->EOL("Region start");
754 EmitDifference("eh_func_end", SubprogramCount
, BeginTag
, BeginNumber
,
757 EmitDifference("label", S
.EndLabel
, BeginTag
, BeginNumber
, true);
759 Asm
->EOL("Region length");
761 // Offset of the landing pad, counted in 16-byte bundles relative to the
766 EmitSectionOffset("label", "eh_func_begin", S
.PadLabel
, SubprogramCount
,
769 Asm
->EOL("Landing pad");
771 // Offset of the first associated action record, relative to the start of
772 // the action table. This value is biased by 1 (1 indicates the start of
773 // the action table), and 0 indicates that there are no actions.
774 Asm
->EmitULEB128Bytes(S
.Action
);
779 // Emit the Action Table.
780 for (SmallVectorImpl
<ActionEntry
>::const_iterator
781 I
= Actions
.begin(), E
= Actions
.end(); I
!= E
; ++I
) {
782 const ActionEntry
&Action
= *I
;
786 // Used by the runtime to match the type of the thrown exception to the
787 // type of the catch clauses or the types in the exception specification.
789 Asm
->EmitSLEB128Bytes(Action
.ValueForTypeID
);
790 Asm
->EOL("TypeInfo index");
794 // Self-relative signed displacement in bytes of the next action record,
795 // or 0 if there is no next action record.
797 Asm
->EmitSLEB128Bytes(Action
.NextAction
);
798 Asm
->EOL("Next action");
801 // Emit the Catch Clauses. The code for the catch clauses following the same
802 // try is similar to a switch statement. The catch clause action record
803 // informs the runtime about the type of a catch clause and about the
804 // associated switch value.
806 // Action Record Fields:
809 // Positive value, starting at 1. Index in the types table of the
810 // __typeinfo for the catch-clause type. 1 is the first word preceding
811 // TTBase, 2 is the second word, and so on. Used by the runtime to check
812 // if the thrown exception type matches the catch-clause type. Back-end
813 // generated switch statements check against this value.
816 // Signed offset, in bytes from the start of this field, to the next
817 // chained action record, or zero if none.
819 // The order of the action records determined by the next field is the order
820 // of the catch clauses as they appear in the source code, and must be kept in
821 // the same order. As a result, changing the order of the catch clause would
822 // change the semantics of the program.
823 for (std::vector
<GlobalVariable
*>::const_reverse_iterator
824 I
= TypeInfos
.rbegin(), E
= TypeInfos
.rend(); I
!= E
; ++I
) {
825 const GlobalVariable
*GV
= *I
;
830 O
<< Asm
->getGlobalLinkName(GV
, GLN
);
835 Asm
->EOL("TypeInfo");
838 // Emit the Type Table.
839 for (std::vector
<unsigned>::const_iterator
840 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
841 unsigned TypeID
= *I
;
842 Asm
->EmitULEB128Bytes(TypeID
);
843 Asm
->EOL("Filter TypeInfo index");
846 Asm
->EmitAlignment(2, 0, 0, false);
849 /// EndModule - Emit all exception information that should come after the
851 void DwarfException::EndModule() {
852 if (MAI
->getExceptionHandlingType() != ExceptionHandling::Dwarf
)
854 if (TimePassesIsEnabled
)
855 ExceptionTimer
->startTimer();
857 if (shouldEmitMovesModule
|| shouldEmitTableModule
) {
858 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
859 for (unsigned i
= 0; i
< Personalities
.size(); ++i
)
860 EmitCIE(Personalities
[i
], i
);
862 for (std::vector
<FunctionEHFrameInfo
>::iterator I
= EHFrames
.begin(),
863 E
= EHFrames
.end(); I
!= E
; ++I
)
867 if (TimePassesIsEnabled
)
868 ExceptionTimer
->stopTimer();
871 /// BeginFunction - Gather pre-function exception information. Assumes being
872 /// emitted immediately after the function entry point.
873 void DwarfException::BeginFunction(MachineFunction
*MF
) {
874 if (TimePassesIsEnabled
)
875 ExceptionTimer
->startTimer();
878 shouldEmitTable
= shouldEmitMoves
= false;
880 if (MMI
&& MAI
->doesSupportExceptionHandling()) {
881 // Map all labels and get rid of any dead landing pads.
882 MMI
->TidyLandingPads();
884 // If any landing pads survive, we need an EH table.
885 if (MMI
->getLandingPads().size())
886 shouldEmitTable
= true;
888 // See if we need frame move info.
889 if (!MF
->getFunction()->doesNotThrow() || UnwindTablesMandatory
)
890 shouldEmitMoves
= true;
892 if (shouldEmitMoves
|| shouldEmitTable
)
893 // Assumes in correct section after the entry point.
894 EmitLabel("eh_func_begin", ++SubprogramCount
);
897 shouldEmitTableModule
|= shouldEmitTable
;
898 shouldEmitMovesModule
|= shouldEmitMoves
;
900 if (TimePassesIsEnabled
)
901 ExceptionTimer
->stopTimer();
904 /// EndFunction - Gather and emit post-function exception information.
906 void DwarfException::EndFunction() {
907 if (TimePassesIsEnabled
)
908 ExceptionTimer
->startTimer();
910 if (shouldEmitMoves
|| shouldEmitTable
) {
911 EmitLabel("eh_func_end", SubprogramCount
);
912 EmitExceptionTable();
914 // Save EH frame information
916 FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF
),
918 MMI
->getPersonalityIndex(),
919 MF
->getFrameInfo()->hasCalls(),
920 !MMI
->getLandingPads().empty(),
921 MMI
->getFrameMoves(),
925 if (TimePassesIsEnabled
)
926 ExceptionTimer
->stopTimer();