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/MCAsmInfo.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCSection.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/Target/TargetData.h"
26 #include "llvm/Target/TargetFrameInfo.h"
27 #include "llvm/Target/TargetLoweringObjectFile.h"
28 #include "llvm/Target/TargetOptions.h"
29 #include "llvm/Target/TargetRegisterInfo.h"
30 #include "llvm/Support/Dwarf.h"
31 #include "llvm/Support/Mangler.h"
32 #include "llvm/Support/Timer.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/ADT/StringExtras.h"
38 static TimerGroup
&getDwarfTimerGroup() {
39 static TimerGroup
DwarfTimerGroup("DWARF Exception");
40 return DwarfTimerGroup
;
43 DwarfException::DwarfException(raw_ostream
&OS
, AsmPrinter
*A
,
45 : Dwarf(OS
, A
, T
, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
46 shouldEmitTableModule(false), shouldEmitMovesModule(false),
48 if (TimePassesIsEnabled
)
49 ExceptionTimer
= new Timer("DWARF Exception Writer",
50 getDwarfTimerGroup());
53 DwarfException::~DwarfException() {
54 delete ExceptionTimer
;
57 /// SizeOfEncodedValue - Return the size of the encoding in bytes.
58 unsigned DwarfException::SizeOfEncodedValue(unsigned Encoding
) {
59 if (Encoding
== dwarf::DW_EH_PE_omit
)
62 switch (Encoding
& 0x07) {
63 case dwarf::DW_EH_PE_absptr
:
64 return TD
->getPointerSize();
65 case dwarf::DW_EH_PE_udata2
:
67 case dwarf::DW_EH_PE_udata4
:
69 case dwarf::DW_EH_PE_udata8
:
73 assert(0 && "Invalid encoded value.");
77 /// EmitCIE - Emit a Common Information Entry (CIE). This holds information that
78 /// is shared among many Frame Description Entries. There is at least one CIE
79 /// in every non-empty .debug_frame section.
80 void DwarfException::EmitCIE(const Function
*PersonalityFn
, unsigned Index
) {
81 // Size and sign of stack growth.
83 Asm
->TM
.getFrameInfo()->getStackGrowthDirection() ==
84 TargetFrameInfo::StackGrowsUp
?
85 TD
->getPointerSize() : -TD
->getPointerSize();
87 const TargetLoweringObjectFile
&TLOF
= Asm
->getObjFileLowering();
89 // Begin eh frame section.
90 Asm
->OutStreamer
.SwitchSection(TLOF
.getEHFrameSection());
92 if (MAI
->is_EHSymbolPrivate())
93 O
<< MAI
->getPrivateGlobalPrefix();
94 O
<< "EH_frame" << Index
<< ":\n";
96 EmitLabel("section_eh_frame", Index
);
98 // Define base labels.
99 EmitLabel("eh_frame_common", Index
);
101 // Define the eh frame length.
102 EmitDifference("eh_frame_common_end", Index
,
103 "eh_frame_common_begin", Index
, true);
104 Asm
->EOL("Length of Common Information Entry");
107 EmitLabel("eh_frame_common_begin", Index
);
108 Asm
->EmitInt32((int)0);
109 Asm
->EOL("CIE Identifier Tag");
110 Asm
->EmitInt8(dwarf::DW_CIE_VERSION
);
111 Asm
->EOL("CIE Version");
113 // The personality presence indicates that language specific information will
114 // show up in the eh frame. Find out how we are supposed to lower the
115 // personality function reference:
116 const MCExpr
*PersonalityRef
= 0;
117 bool IsPersonalityIndirect
= false, IsPersonalityPCRel
= false;
119 // FIXME: HANDLE STATIC CODEGEN MODEL HERE.
121 // In non-static mode, ask the object file how to represent this reference.
123 TLOF
.getSymbolForDwarfGlobalReference(PersonalityFn
, Asm
->Mang
,
124 IsPersonalityIndirect
,
128 unsigned PerEncoding
= dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
;
129 if (IsPersonalityIndirect
)
130 PerEncoding
|= dwarf::DW_EH_PE_indirect
;
131 unsigned LSDAEncoding
= dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
;
132 unsigned FDEEncoding
= dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
;
134 char Augmentation
[5] = { 0 };
135 unsigned AugmentationSize
= 0;
136 char *APtr
= Augmentation
+ 1;
138 if (PersonalityRef
) {
139 // There is a personality function.
141 AugmentationSize
+= 1 + SizeOfEncodedValue(PerEncoding
);
144 if (UsesLSDA
[Index
]) {
145 // An LSDA pointer is in the FDE augmentation.
150 if (FDEEncoding
!= dwarf::DW_EH_PE_absptr
) {
151 // A non-default pointer encoding for the FDE.
156 if (APtr
!= Augmentation
+ 1)
157 Augmentation
[0] = 'z';
159 Asm
->EmitString(Augmentation
);
160 Asm
->EOL("CIE Augmentation");
163 Asm
->EmitULEB128Bytes(1);
164 Asm
->EOL("CIE Code Alignment Factor");
165 Asm
->EmitSLEB128Bytes(stackGrowth
);
166 Asm
->EOL("CIE Data Alignment Factor");
167 Asm
->EmitInt8(RI
->getDwarfRegNum(RI
->getRARegister(), true));
168 Asm
->EOL("CIE Return Address Column");
170 Asm
->EmitULEB128Bytes(AugmentationSize
);
171 Asm
->EOL("Augmentation Size");
173 Asm
->EmitInt8(PerEncoding
);
174 Asm
->EOL("Personality", PerEncoding
);
176 // If there is a personality, we need to indicate the function's location.
177 if (PersonalityRef
) {
178 // If the reference to the personality function symbol is not already
179 // pc-relative, then we need to subtract our current address from it. Do
180 // this by emitting a label and subtracting it from the expression we
181 // already have. This is equivalent to emitting "foo - .", but we have to
182 // emit the label for "." directly.
183 if (!IsPersonalityPCRel
) {
184 SmallString
<64> Name
;
185 raw_svector_ostream(Name
) << MAI
->getPrivateGlobalPrefix()
186 << "personalityref_addr" << Asm
->getFunctionNumber() << "_" << Index
;
187 MCSymbol
*DotSym
= Asm
->OutContext
.GetOrCreateSymbol(Name
.str());
188 Asm
->OutStreamer
.EmitLabel(DotSym
);
191 MCBinaryExpr::CreateSub(PersonalityRef
,
192 MCSymbolRefExpr::Create(DotSym
,Asm
->OutContext
),
196 O
<< MAI
->getData32bitsDirective();
197 PersonalityRef
->print(O
, MAI
);
198 Asm
->EOL("Personality");
200 Asm
->EmitInt8(LSDAEncoding
);
201 Asm
->EOL("LSDA Encoding", LSDAEncoding
);
203 Asm
->EmitInt8(FDEEncoding
);
204 Asm
->EOL("FDE Encoding", FDEEncoding
);
207 // Indicate locations of general callee saved registers in frame.
208 std::vector
<MachineMove
> Moves
;
209 RI
->getInitialFrameState(Moves
);
210 EmitFrameMoves(NULL
, 0, Moves
, true);
212 // On Darwin the linker honors the alignment of eh_frame, which means it must
213 // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
214 // holes which confuse readers of eh_frame.
215 Asm
->EmitAlignment(TD
->getPointerSize() == 4 ? 2 : 3, 0, 0, false);
216 EmitLabel("eh_frame_common_end", Index
);
221 /// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
222 void DwarfException::EmitFDE(const FunctionEHFrameInfo
&EHFrameInfo
) {
223 assert(!EHFrameInfo
.function
->hasAvailableExternallyLinkage() &&
224 "Should not emit 'available externally' functions at all");
226 const Function
*TheFunc
= EHFrameInfo
.function
;
228 Asm
->OutStreamer
.SwitchSection(Asm
->getObjFileLowering().getEHFrameSection());
230 // Externally visible entry into the functions eh frame info. If the
231 // corresponding function is static, this should not be externally visible.
232 if (!TheFunc
->hasLocalLinkage())
233 if (const char *GlobalEHDirective
= MAI
->getGlobalEHDirective())
234 O
<< GlobalEHDirective
<< EHFrameInfo
.FnName
<< "\n";
236 // If corresponding function is weak definition, this should be too.
237 if (TheFunc
->isWeakForLinker() && MAI
->getWeakDefDirective())
238 O
<< MAI
->getWeakDefDirective() << EHFrameInfo
.FnName
<< "\n";
240 // If there are no calls then you can't unwind. This may mean we can omit the
241 // EH Frame, but some environments do not handle weak absolute symbols. If
242 // UnwindTablesMandatory is set we cannot do this optimization; the unwind
243 // info is to be available for non-EH uses.
244 if (!EHFrameInfo
.hasCalls
&& !UnwindTablesMandatory
&&
245 (!TheFunc
->isWeakForLinker() ||
246 !MAI
->getWeakDefDirective() ||
247 MAI
->getSupportsWeakOmittedEHFrame())) {
248 O
<< EHFrameInfo
.FnName
<< " = 0\n";
249 // This name has no connection to the function, so it might get
250 // dead-stripped when the function is not, erroneously. Prohibit
251 // dead-stripping unconditionally.
252 if (const char *UsedDirective
= MAI
->getUsedDirective())
253 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
255 O
<< EHFrameInfo
.FnName
<< ":\n";
258 EmitDifference("eh_frame_end", EHFrameInfo
.Number
,
259 "eh_frame_begin", EHFrameInfo
.Number
, true);
260 Asm
->EOL("Length of Frame Information Entry");
262 EmitLabel("eh_frame_begin", EHFrameInfo
.Number
);
264 EmitSectionOffset("eh_frame_begin", "eh_frame_common",
265 EHFrameInfo
.Number
, EHFrameInfo
.PersonalityIndex
,
268 Asm
->EOL("FDE CIE offset");
270 EmitReference("eh_func_begin", EHFrameInfo
.Number
, true, true);
271 Asm
->EOL("FDE initial location");
272 EmitDifference("eh_func_end", EHFrameInfo
.Number
,
273 "eh_func_begin", EHFrameInfo
.Number
, true);
274 Asm
->EOL("FDE address range");
276 // If there is a personality and landing pads then point to the language
277 // specific data area in the exception table.
278 if (MMI
->getPersonalities()[0] != NULL
) {
279 bool is4Byte
= TD
->getPointerSize() == sizeof(int32_t);
281 Asm
->EmitULEB128Bytes(is4Byte
? 4 : 8);
282 Asm
->EOL("Augmentation size");
284 if (EHFrameInfo
.hasLandingPads
)
285 EmitReference("exception", EHFrameInfo
.Number
, true, false);
288 Asm
->EmitInt32((int)0);
290 Asm
->EmitInt64((int)0);
292 Asm
->EOL("Language Specific Data Area");
294 Asm
->EmitULEB128Bytes(0);
295 Asm
->EOL("Augmentation size");
298 // Indicate locations of function specific callee saved registers in frame.
299 EmitFrameMoves("eh_func_begin", EHFrameInfo
.Number
, EHFrameInfo
.Moves
,
302 // On Darwin the linker honors the alignment of eh_frame, which means it
303 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you
304 // get holes which confuse readers of eh_frame.
305 Asm
->EmitAlignment(TD
->getPointerSize() == sizeof(int32_t) ? 2 : 3,
307 EmitLabel("eh_frame_end", EHFrameInfo
.Number
);
309 // If the function is marked used, this table should be also. We cannot
310 // make the mark unconditional in this case, since retaining the table also
311 // retains the function in this case, and there is code around that depends
312 // on unused functions (calling undefined externals) being dead-stripped to
313 // link correctly. Yes, there really is.
314 if (MMI
->isUsedFunction(EHFrameInfo
.function
))
315 if (const char *UsedDirective
= MAI
->getUsedDirective())
316 O
<< UsedDirective
<< EHFrameInfo
.FnName
<< "\n\n";
322 /// SharedTypeIds - How many leading type ids two landing pads have in common.
323 unsigned DwarfException::SharedTypeIds(const LandingPadInfo
*L
,
324 const LandingPadInfo
*R
) {
325 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
326 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
327 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
330 for (; Count
!= MinSize
; ++Count
)
331 if (LIds
[Count
] != RIds
[Count
])
337 /// PadLT - Order landing pads lexicographically by type id.
338 bool DwarfException::PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
339 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
340 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
341 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
343 for (unsigned i
= 0; i
!= MinSize
; ++i
)
344 if (LIds
[i
] != RIds
[i
])
345 return LIds
[i
] < RIds
[i
];
347 return LSize
< RSize
;
350 /// ComputeActionsTable - Compute the actions table and gather the first action
351 /// index for each landing pad site.
352 unsigned DwarfException::
353 ComputeActionsTable(const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
354 SmallVectorImpl
<ActionEntry
> &Actions
,
355 SmallVectorImpl
<unsigned> &FirstActions
) {
357 // The action table follows the call-site table in the LSDA. The individual
358 // records are of two types:
361 // * Exception specification
363 // The two record kinds have the same format, with only small differences.
364 // They are distinguished by the "switch value" field: Catch clauses
365 // (TypeInfos) have strictly positive switch values, and exception
366 // specifications (FilterIds) have strictly negative switch values. Value 0
367 // indicates a catch-all clause.
369 // Negative type IDs index into FilterIds. Positive type IDs index into
370 // TypeInfos. The value written for a positive type ID is just the type ID
371 // itself. For a negative type ID, however, the value written is the
372 // (negative) byte offset of the corresponding FilterIds entry. The byte
373 // offset is usually equal to the type ID (because the FilterIds entries are
374 // written using a variable width encoding, which outputs one byte per entry
375 // as long as the value written is not too large) but can differ. This kind
376 // of complication does not occur for positive type IDs because type infos are
377 // output using a fixed width encoding. FilterOffsets[i] holds the byte
378 // offset corresponding to FilterIds[i].
380 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
381 SmallVector
<int, 16> FilterOffsets
;
382 FilterOffsets
.reserve(FilterIds
.size());
385 for (std::vector
<unsigned>::const_iterator
386 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
!= E
; ++I
) {
387 FilterOffsets
.push_back(Offset
);
388 Offset
-= MCAsmInfo::getULEB128Size(*I
);
391 FirstActions
.reserve(LandingPads
.size());
394 unsigned SizeActions
= 0;
395 const LandingPadInfo
*PrevLPI
= 0;
397 for (SmallVectorImpl
<const LandingPadInfo
*>::const_iterator
398 I
= LandingPads
.begin(), E
= LandingPads
.end(); I
!= E
; ++I
) {
399 const LandingPadInfo
*LPI
= *I
;
400 const std::vector
<int> &TypeIds
= LPI
->TypeIds
;
401 const unsigned NumShared
= PrevLPI
? SharedTypeIds(LPI
, PrevLPI
) : 0;
402 unsigned SizeSiteActions
= 0;
404 if (NumShared
< TypeIds
.size()) {
405 unsigned SizeAction
= 0;
406 ActionEntry
*PrevAction
= 0;
409 const unsigned SizePrevIds
= PrevLPI
->TypeIds
.size();
410 assert(Actions
.size());
411 PrevAction
= &Actions
.back();
412 SizeAction
= MCAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
413 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
415 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
417 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
418 SizeAction
+= -PrevAction
->NextAction
;
419 PrevAction
= PrevAction
->Previous
;
423 // Compute the actions.
424 for (unsigned J
= NumShared
, M
= TypeIds
.size(); J
!= M
; ++J
) {
425 int TypeID
= TypeIds
[J
];
426 assert(-1 - TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
427 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
428 unsigned SizeTypeID
= MCAsmInfo::getSLEB128Size(ValueForTypeID
);
430 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
431 SizeAction
= SizeTypeID
+ MCAsmInfo::getSLEB128Size(NextAction
);
432 SizeSiteActions
+= SizeAction
;
434 ActionEntry Action
= { ValueForTypeID
, NextAction
, PrevAction
};
435 Actions
.push_back(Action
);
436 PrevAction
= &Actions
.back();
439 // Record the first action of the landing pad site.
440 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
441 } // else identical - re-use previous FirstAction
443 // Information used when created the call-site table. The action record
444 // field of the call site record is the offset of the first associated
445 // action record, relative to the start of the actions table. This value is
446 // biased by 1 (1 in dicating the start of the actions table), and 0
447 // indicates that there are no actions.
448 FirstActions
.push_back(FirstAction
);
450 // Compute this sites contribution to size.
451 SizeActions
+= SizeSiteActions
;
459 /// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke
460 /// has a try-range containing the call, a non-zero landing pad, and an
461 /// appropriate action. The entry for an ordinary call has a try-range
462 /// containing the call and zero for the landing pad and the action. Calls
463 /// marked 'nounwind' have no entry and must not be contained in the try-range
464 /// of any entry - they form gaps in the table. Entries must be ordered by
465 /// try-range address.
466 void DwarfException::
467 ComputeCallSiteTable(SmallVectorImpl
<CallSiteEntry
> &CallSites
,
468 const RangeMapType
&PadMap
,
469 const SmallVectorImpl
<const LandingPadInfo
*> &LandingPads
,
470 const SmallVectorImpl
<unsigned> &FirstActions
) {
471 // The end label of the previous invoke or nounwind try-range.
472 unsigned LastLabel
= 0;
474 // Whether there is a potentially throwing instruction (currently this means
475 // an ordinary call) between the end of the previous try-range and now.
476 bool SawPotentiallyThrowing
= false;
478 // Whether the last CallSite entry was for an invoke.
479 bool PreviousIsInvoke
= false;
481 // Visit all instructions in order of address.
482 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
484 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
486 if (!MI
->isLabel()) {
487 SawPotentiallyThrowing
|= MI
->getDesc().isCall();
491 unsigned BeginLabel
= MI
->getOperand(0).getImm();
492 assert(BeginLabel
&& "Invalid label!");
494 // End of the previous try-range?
495 if (BeginLabel
== LastLabel
)
496 SawPotentiallyThrowing
= false;
498 // Beginning of a new try-range?
499 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
500 if (L
== PadMap
.end())
501 // Nope, it was just some random label.
504 const PadRange
&P
= L
->second
;
505 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
506 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
507 "Inconsistent landing pad map!");
509 // For Dwarf exception handling (SjLj handling doesn't use this). If some
510 // instruction between the previous try-range and this one may throw,
511 // create a call-site entry with no landing pad for the region between the
513 if (SawPotentiallyThrowing
&&
514 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
515 CallSiteEntry Site
= { LastLabel
, BeginLabel
, 0, 0 };
516 CallSites
.push_back(Site
);
517 PreviousIsInvoke
= false;
520 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
521 assert(BeginLabel
&& LastLabel
&& "Invalid landing pad!");
523 if (LandingPad
->LandingPadLabel
) {
524 // This try-range is for an invoke.
525 CallSiteEntry Site
= {
528 LandingPad
->LandingPadLabel
,
529 FirstActions
[P
.PadIndex
]
532 // Try to merge with the previous call-site. SJLJ doesn't do this
533 if (PreviousIsInvoke
&&
534 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
535 CallSiteEntry
&Prev
= CallSites
.back();
536 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
537 // Extend the range of the previous entry.
538 Prev
.EndLabel
= Site
.EndLabel
;
543 // Otherwise, create a new call-site.
544 CallSites
.push_back(Site
);
545 PreviousIsInvoke
= true;
548 PreviousIsInvoke
= false;
553 // If some instruction between the previous try-range and the end of the
554 // function may throw, create a call-site entry with no landing pad for the
555 // region following the try-range.
556 if (SawPotentiallyThrowing
&&
557 MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
) {
558 CallSiteEntry Site
= { LastLabel
, 0, 0, 0 };
559 CallSites
.push_back(Site
);
563 /// EmitExceptionTable - Emit landing pads and actions.
565 /// The general organization of the table is complex, but the basic concepts are
566 /// easy. First there is a header which describes the location and organization
567 /// of the three components that follow.
569 /// 1. The landing pad site information describes the range of code covered by
570 /// the try. In our case it's an accumulation of the ranges covered by the
571 /// invokes in the try. There is also a reference to the landing pad that
572 /// handles the exception once processed. Finally an index into the actions
574 /// 2. The action table, in our case, is composed of pairs of type IDs and next
575 /// action offset. Starting with the action index from the landing pad
576 /// site, each type ID is checked for a match to the current exception. If
577 /// it matches then the exception and type id are passed on to the landing
578 /// pad. Otherwise the next action is looked up. This chain is terminated
579 /// with a next action of zero. If no type id is found then the frame is
580 /// unwound and handling continues.
581 /// 3. Type ID table contains references to all the C++ typeinfo for all
582 /// catches in the function. This tables is reverse indexed base 1.
583 void DwarfException::EmitExceptionTable() {
584 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
585 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
586 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
587 if (PadInfos
.empty()) return;
589 // Sort the landing pads in order of their type ids. This is used to fold
590 // duplicate actions.
591 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
592 LandingPads
.reserve(PadInfos
.size());
594 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
595 LandingPads
.push_back(&PadInfos
[i
]);
597 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
599 // Compute the actions table and gather the first action index for each
601 SmallVector
<ActionEntry
, 32> Actions
;
602 SmallVector
<unsigned, 64> FirstActions
;
603 unsigned SizeActions
= ComputeActionsTable(LandingPads
, Actions
,
606 // Invokes and nounwind calls have entries in PadMap (due to being bracketed
607 // by try-range labels when lowered). Ordinary calls do not, so appropriate
608 // try-ranges for them need be deduced when using DWARF exception handling.
610 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
611 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
612 for (unsigned j
= 0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
613 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
614 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
615 PadRange P
= { i
, j
};
616 PadMap
[BeginLabel
] = P
;
620 // Compute the call-site table.
621 SmallVector
<CallSiteEntry
, 64> CallSites
;
622 ComputeCallSiteTable(CallSites
, PadMap
, LandingPads
, FirstActions
);
627 const unsigned SiteStartSize
= SizeOfEncodedValue(dwarf::DW_EH_PE_udata4
);
628 const unsigned SiteLengthSize
= SizeOfEncodedValue(dwarf::DW_EH_PE_udata4
);
629 const unsigned LandingPadSize
= SizeOfEncodedValue(dwarf::DW_EH_PE_udata4
);
630 bool IsSJLJ
= MAI
->getExceptionHandlingType() == ExceptionHandling::SjLj
;
631 bool HaveTTData
= IsSJLJ
? (!TypeInfos
.empty() || !FilterIds
.empty()) : true;
637 SizeSites
= CallSites
.size() *
638 (SiteStartSize
+ SiteLengthSize
+ LandingPadSize
);
640 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
) {
641 SizeSites
+= MCAsmInfo::getULEB128Size(CallSites
[i
].Action
);
643 SizeSites
+= MCAsmInfo::getULEB128Size(i
);
647 const MCSection
*LSDASection
= Asm
->getObjFileLowering().getLSDASection();
648 unsigned TTypeFormat
;
649 unsigned TypeFormatSize
;
652 // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
653 // that we're omitting that bit.
654 TTypeFormat
= dwarf::DW_EH_PE_omit
;
655 TypeFormatSize
= SizeOfEncodedValue(dwarf::DW_EH_PE_absptr
);
657 // Okay, we have actual filters or typeinfos to emit. As such, we need to
658 // pick a type encoding for them. We're about to emit a list of pointers to
659 // typeinfo objects at the end of the LSDA. However, unless we're in static
660 // mode, this reference will require a relocation by the dynamic linker.
662 // Because of this, we have a couple of options:
664 // 1) If we are in -static mode, we can always use an absolute reference
665 // from the LSDA, because the static linker will resolve it.
667 // 2) Otherwise, if the LSDA section is writable, we can output the direct
668 // reference to the typeinfo and allow the dynamic linker to relocate
669 // it. Since it is in a writable section, the dynamic linker won't
672 // 3) Finally, if we're in PIC mode and the LDSA section isn't writable,
673 // we need to use some form of indirection. For example, on Darwin,
674 // we can output a statically-relocatable reference to a dyld stub. The
675 // offset to the stub is constant, but the contents are in a section
676 // that is updated by the dynamic linker. This is easy enough, but we
677 // need to tell the personality function of the unwinder to indirect
678 // through the dyld stub.
680 // FIXME: When (3) is actually implemented, we'll have to emit the stubs
681 // somewhere. This predicate should be moved to a shared location that is
682 // in target-independent code.
684 if (LSDASection
->getKind().isWriteable() ||
685 Asm
->TM
.getRelocationModel() == Reloc::Static
)
686 TTypeFormat
= dwarf::DW_EH_PE_absptr
;
688 TTypeFormat
= dwarf::DW_EH_PE_indirect
| dwarf::DW_EH_PE_pcrel
|
689 dwarf::DW_EH_PE_sdata4
;
691 TypeFormatSize
= SizeOfEncodedValue(TTypeFormat
);
694 // Begin the exception table.
695 Asm
->OutStreamer
.SwitchSection(LSDASection
);
696 Asm
->EmitAlignment(2, 0, 0, false);
698 O
<< "GCC_except_table" << SubprogramCount
<< ":\n";
700 // The type infos need to be aligned. GCC does this by inserting padding just
701 // before the type infos. However, this changes the size of the exception
702 // table, so you need to take this into account when you output the exception
703 // table size. However, the size is output using a variable length encoding.
704 // So by increasing the size by inserting padding, you may increase the number
705 // of bytes used for writing the size. If it increases, say by one byte, then
706 // you now need to output one less byte of padding to get the type infos
707 // aligned. However this decreases the size of the exception table. This
708 // changes the value you have to output for the exception table size. Due to
709 // the variable length encoding, the number of bytes used for writing the
710 // length may decrease. If so, you then have to increase the amount of
711 // padding. And so on. If you look carefully at the GCC code you will see that
712 // it indeed does this in a loop, going on and on until the values stabilize.
713 // We chose another solution: don't output padding inside the table like GCC
714 // does, instead output it before the table.
715 unsigned SizeTypes
= TypeInfos
.size() * TypeFormatSize
;
716 unsigned TyOffset
= sizeof(int8_t) + // Call site format
717 MCAsmInfo::getULEB128Size(SizeSites
) + // Call-site table length
718 SizeSites
+ SizeActions
+ SizeTypes
;
719 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
720 sizeof(int8_t) + // TType format
722 MCAsmInfo::getULEB128Size(TyOffset
) : 0) + // TType base offset
724 unsigned SizeAlign
= (4 - TotalSize
) & 3;
726 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
731 EmitLabel("exception", SubprogramCount
);
734 SmallString
<16> LSDAName
;
735 raw_svector_ostream(LSDAName
) << MAI
->getPrivateGlobalPrefix() <<
736 "_LSDA_" << Asm
->getFunctionNumber();
737 O
<< LSDAName
.str() << ":\n";
741 Asm
->EmitInt8(dwarf::DW_EH_PE_omit
);
742 Asm
->EOL("@LPStart format", dwarf::DW_EH_PE_omit
);
744 Asm
->EmitInt8(TTypeFormat
);
745 Asm
->EOL("@TType format", TTypeFormat
);
748 Asm
->EmitULEB128Bytes(TyOffset
);
749 Asm
->EOL("@TType base offset");
752 // SjLj Exception handling
754 Asm
->EmitInt8(dwarf::DW_EH_PE_udata4
);
755 Asm
->EOL("Call site format", dwarf::DW_EH_PE_udata4
);
756 Asm
->EmitULEB128Bytes(SizeSites
);
757 Asm
->EOL("Call site table length");
759 // Emit the landing pad site information.
761 for (SmallVectorImpl
<CallSiteEntry
>::const_iterator
762 I
= CallSites
.begin(), E
= CallSites
.end(); I
!= E
; ++I
, ++idx
) {
763 const CallSiteEntry
&S
= *I
;
765 // Offset of the landing pad, counted in 16-byte bundles relative to the
767 Asm
->EmitULEB128Bytes(idx
);
768 Asm
->EOL("Landing pad");
770 // Offset of the first associated action record, relative to the start of
771 // the action table. This value is biased by 1 (1 indicates the start of
772 // the action table), and 0 indicates that there are no actions.
773 Asm
->EmitULEB128Bytes(S
.Action
);
777 // DWARF Exception handling
778 assert(MAI
->getExceptionHandlingType() == ExceptionHandling::Dwarf
);
780 // The call-site table is a list of all call sites that may throw an
781 // exception (including C++ 'throw' statements) in the procedure
782 // fragment. It immediately follows the LSDA header. Each entry indicates,
783 // for a given call, the first corresponding action record and corresponding
786 // The table begins with the number of bytes, stored as an LEB128
787 // compressed, unsigned integer. The records immediately follow the record
788 // count. They are sorted in increasing call-site address. Each record
791 // * The position of the call-site.
792 // * The position of the landing pad.
793 // * The first action record for that call site.
795 // A missing entry in the call-site table indicates that a call is not
796 // supposed to throw.
798 // Emit the landing pad call site table.
799 Asm
->EmitInt8(dwarf::DW_EH_PE_udata4
);
800 Asm
->EOL("Call site format", dwarf::DW_EH_PE_udata4
);
801 Asm
->EmitULEB128Bytes(SizeSites
);
802 Asm
->EOL("Call site table size");
804 for (SmallVectorImpl
<CallSiteEntry
>::const_iterator
805 I
= CallSites
.begin(), E
= CallSites
.end(); I
!= E
; ++I
) {
806 const CallSiteEntry
&S
= *I
;
807 const char *BeginTag
;
808 unsigned BeginNumber
;
811 BeginTag
= "eh_func_begin";
812 BeginNumber
= SubprogramCount
;
815 BeginNumber
= S
.BeginLabel
;
818 // Offset of the call site relative to the previous call site, counted in
819 // number of 16-byte bundles. The first call site is counted relative to
820 // the start of the procedure fragment.
821 EmitSectionOffset(BeginTag
, "eh_func_begin", BeginNumber
, SubprogramCount
,
823 Asm
->EOL("Region start");
826 EmitDifference("eh_func_end", SubprogramCount
, BeginTag
, BeginNumber
,
829 EmitDifference("label", S
.EndLabel
, BeginTag
, BeginNumber
, true);
831 Asm
->EOL("Region length");
833 // Offset of the landing pad, counted in 16-byte bundles relative to the
838 EmitSectionOffset("label", "eh_func_begin", S
.PadLabel
, SubprogramCount
,
841 Asm
->EOL("Landing pad");
843 // Offset of the first associated action record, relative to the start of
844 // the action table. This value is biased by 1 (1 indicates the start of
845 // the action table), and 0 indicates that there are no actions.
846 Asm
->EmitULEB128Bytes(S
.Action
);
851 // Emit the Action Table.
852 for (SmallVectorImpl
<ActionEntry
>::const_iterator
853 I
= Actions
.begin(), E
= Actions
.end(); I
!= E
; ++I
) {
854 const ActionEntry
&Action
= *I
;
858 // Used by the runtime to match the type of the thrown exception to the
859 // type of the catch clauses or the types in the exception specification.
861 Asm
->EmitSLEB128Bytes(Action
.ValueForTypeID
);
862 Asm
->EOL("TypeInfo index");
866 // Self-relative signed displacement in bytes of the next action record,
867 // or 0 if there is no next action record.
869 Asm
->EmitSLEB128Bytes(Action
.NextAction
);
870 Asm
->EOL("Next action");
873 // Emit the Catch Clauses. The code for the catch clauses following the same
874 // try is similar to a switch statement. The catch clause action record
875 // informs the runtime about the type of a catch clause and about the
876 // associated switch value.
878 // Action Record Fields:
881 // Positive value, starting at 1. Index in the types table of the
882 // __typeinfo for the catch-clause type. 1 is the first word preceding
883 // TTBase, 2 is the second word, and so on. Used by the runtime to check
884 // if the thrown exception type matches the catch-clause type. Back-end
885 // generated switch statements check against this value.
888 // Signed offset, in bytes from the start of this field, to the next
889 // chained action record, or zero if none.
891 // The order of the action records determined by the next field is the order
892 // of the catch clauses as they appear in the source code, and must be kept in
893 // the same order. As a result, changing the order of the catch clause would
894 // change the semantics of the program.
895 for (std::vector
<GlobalVariable
*>::const_reverse_iterator
896 I
= TypeInfos
.rbegin(), E
= TypeInfos
.rend(); I
!= E
; ++I
) {
897 const GlobalVariable
*GV
= *I
;
901 O
<< Asm
->Mang
->getMangledName(GV
);
906 Asm
->EOL("TypeInfo");
909 // Emit the Type Table.
910 for (std::vector
<unsigned>::const_iterator
911 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
912 unsigned TypeID
= *I
;
913 Asm
->EmitULEB128Bytes(TypeID
);
914 Asm
->EOL("Filter TypeInfo index");
917 Asm
->EmitAlignment(2, 0, 0, false);
920 /// EndModule - Emit all exception information that should come after the
922 void DwarfException::EndModule() {
923 if (MAI
->getExceptionHandlingType() != ExceptionHandling::Dwarf
)
926 if (!shouldEmitMovesModule
&& !shouldEmitTableModule
)
929 if (TimePassesIsEnabled
)
930 ExceptionTimer
->startTimer();
932 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
934 for (unsigned I
= 0, E
= Personalities
.size(); I
< E
; ++I
)
935 EmitCIE(Personalities
[I
], I
);
937 for (std::vector
<FunctionEHFrameInfo
>::iterator
938 I
= EHFrames
.begin(), E
= EHFrames
.end(); I
!= E
; ++I
)
941 if (TimePassesIsEnabled
)
942 ExceptionTimer
->stopTimer();
945 /// BeginFunction - Gather pre-function exception information. Assumes it's
946 /// being emitted immediately after the function entry point.
947 void DwarfException::BeginFunction(MachineFunction
*MF
) {
948 if (!MMI
|| !MAI
->doesSupportExceptionHandling()) return;
950 if (TimePassesIsEnabled
)
951 ExceptionTimer
->startTimer();
954 shouldEmitTable
= shouldEmitMoves
= false;
956 // Map all labels and get rid of any dead landing pads.
957 MMI
->TidyLandingPads();
959 // If any landing pads survive, we need an EH table.
960 if (!MMI
->getLandingPads().empty())
961 shouldEmitTable
= true;
963 // See if we need frame move info.
964 if (!MF
->getFunction()->doesNotThrow() || UnwindTablesMandatory
)
965 shouldEmitMoves
= true;
967 if (shouldEmitMoves
|| shouldEmitTable
)
968 // Assumes in correct section after the entry point.
969 EmitLabel("eh_func_begin", ++SubprogramCount
);
971 shouldEmitTableModule
|= shouldEmitTable
;
972 shouldEmitMovesModule
|= shouldEmitMoves
;
974 if (TimePassesIsEnabled
)
975 ExceptionTimer
->stopTimer();
978 /// EndFunction - Gather and emit post-function exception information.
980 void DwarfException::EndFunction() {
981 if (!shouldEmitMoves
&& !shouldEmitTable
) return;
983 if (TimePassesIsEnabled
)
984 ExceptionTimer
->startTimer();
986 EmitLabel("eh_func_end", SubprogramCount
);
987 EmitExceptionTable();
989 std::string FunctionEHName
=
990 Asm
->Mang
->getMangledName(MF
->getFunction(), ".eh",
991 Asm
->MAI
->is_EHSymbolPrivate());
993 // Save EH frame information
994 EHFrames
.push_back(FunctionEHFrameInfo(FunctionEHName
, SubprogramCount
,
995 MMI
->getPersonalityIndex(),
996 MF
->getFrameInfo()->hasCalls(),
997 !MMI
->getLandingPads().empty(),
998 MMI
->getFrameMoves(),
1001 // Record if this personality index uses a landing pad.
1002 UsesLSDA
[MMI
->getPersonalityIndex()] |= !MMI
->getLandingPads().empty();
1004 if (TimePassesIsEnabled
)
1005 ExceptionTimer
->stopTimer();