1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
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 defines a JITDwarfEmitter object that is used by the JIT to
11 // write dwarf tables to memory.
13 //===----------------------------------------------------------------------===//
16 #include "JITDwarfEmitter.h"
17 #include "llvm/Function.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/CodeGen/JITCodeEmitter.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineLocation.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/ExecutionEngine/JITMemoryManager.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/Target/TargetData.h"
28 #include "llvm/Target/TargetInstrInfo.h"
29 #include "llvm/Target/TargetFrameLowering.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Target/TargetRegisterInfo.h"
34 JITDwarfEmitter::JITDwarfEmitter(JIT
& theJit
) : MMI(0), Jit(theJit
) {}
37 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction
& F
,
39 unsigned char* StartFunction
,
40 unsigned char* EndFunction
,
41 unsigned char* &EHFramePtr
) {
42 assert(MMI
&& "MachineModuleInfo not registered!");
44 const TargetMachine
& TM
= F
.getTarget();
45 TD
= TM
.getTargetData();
46 stackGrowthDirection
= TM
.getFrameLowering()->getStackGrowthDirection();
47 RI
= TM
.getRegisterInfo();
48 TFI
= TM
.getFrameLowering();
51 unsigned char* ExceptionTable
= EmitExceptionTable(&F
, StartFunction
,
54 unsigned char* Result
= 0;
56 const std::vector
<const Function
*> Personalities
= MMI
->getPersonalities();
57 EHFramePtr
= EmitCommonEHFrame(Personalities
[MMI
->getPersonalityIndex()]);
59 Result
= EmitEHFrame(Personalities
[MMI
->getPersonalityIndex()], EHFramePtr
,
60 StartFunction
, EndFunction
, ExceptionTable
);
67 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr
,
68 const std::vector
<MachineMove
> &Moves
) const {
69 unsigned PointerSize
= TD
->getPointerSize();
70 int stackGrowth
= stackGrowthDirection
== TargetFrameLowering::StackGrowsUp
?
71 PointerSize
: -PointerSize
;
72 MCSymbol
*BaseLabel
= 0;
74 for (unsigned i
= 0, N
= Moves
.size(); i
< N
; ++i
) {
75 const MachineMove
&Move
= Moves
[i
];
76 MCSymbol
*Label
= Move
.getLabel();
78 // Throw out move if the label is invalid.
79 if (Label
&& (*JCE
->getLabelLocations())[Label
] == 0)
82 intptr_t LabelPtr
= 0;
83 if (Label
) LabelPtr
= JCE
->getLabelAddress(Label
);
85 const MachineLocation
&Dst
= Move
.getDestination();
86 const MachineLocation
&Src
= Move
.getSource();
88 // Advance row if new location.
89 if (BaseLabelPtr
&& Label
&& BaseLabel
!= Label
) {
90 JCE
->emitByte(dwarf::DW_CFA_advance_loc4
);
91 JCE
->emitInt32(LabelPtr
- BaseLabelPtr
);
94 BaseLabelPtr
= LabelPtr
;
98 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
100 if (Src
.getReg() == MachineLocation::VirtualFP
) {
101 JCE
->emitByte(dwarf::DW_CFA_def_cfa_offset
);
103 JCE
->emitByte(dwarf::DW_CFA_def_cfa
);
104 JCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Src
.getReg(), true));
107 JCE
->emitULEB128Bytes(-Src
.getOffset());
109 llvm_unreachable("Machine move not supported yet.");
111 } else if (Src
.isReg() &&
112 Src
.getReg() == MachineLocation::VirtualFP
) {
114 JCE
->emitByte(dwarf::DW_CFA_def_cfa_register
);
115 JCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Dst
.getReg(), true));
117 llvm_unreachable("Machine move not supported yet.");
120 unsigned Reg
= RI
->getDwarfRegNum(Src
.getReg(), true);
121 int Offset
= Dst
.getOffset() / stackGrowth
;
124 JCE
->emitByte(dwarf::DW_CFA_offset_extended_sf
);
125 JCE
->emitULEB128Bytes(Reg
);
126 JCE
->emitSLEB128Bytes(Offset
);
127 } else if (Reg
< 64) {
128 JCE
->emitByte(dwarf::DW_CFA_offset
+ Reg
);
129 JCE
->emitULEB128Bytes(Offset
);
131 JCE
->emitByte(dwarf::DW_CFA_offset_extended
);
132 JCE
->emitULEB128Bytes(Reg
);
133 JCE
->emitULEB128Bytes(Offset
);
139 /// SharedTypeIds - How many leading type ids two landing pads have in common.
140 static unsigned SharedTypeIds(const LandingPadInfo
*L
,
141 const LandingPadInfo
*R
) {
142 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
143 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
144 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
147 for (; Count
!= MinSize
; ++Count
)
148 if (LIds
[Count
] != RIds
[Count
])
155 /// PadLT - Order landing pads lexicographically by type id.
156 static bool PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
157 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
158 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
159 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
161 for (unsigned i
= 0; i
!= MinSize
; ++i
)
162 if (LIds
[i
] != RIds
[i
])
163 return LIds
[i
] < RIds
[i
];
165 return LSize
< RSize
;
170 /// ActionEntry - Structure describing an entry in the actions table.
172 int ValueForTypeID
; // The value to write - may not be equal to the type id.
174 struct ActionEntry
*Previous
;
177 /// PadRange - Structure holding a try-range and the associated landing pad.
179 // The index of the landing pad.
181 // The index of the begin and end labels in the landing pad's label lists.
185 typedef DenseMap
<MCSymbol
*, PadRange
> RangeMapType
;
187 /// CallSiteEntry - Structure describing an entry in the call-site table.
188 struct CallSiteEntry
{
189 MCSymbol
*BeginLabel
; // zero indicates the start of the function.
190 MCSymbol
*EndLabel
; // zero indicates the end of the function.
191 MCSymbol
*PadLabel
; // zero indicates that there is no landing pad.
197 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction
* MF
,
198 unsigned char* StartFunction
,
199 unsigned char* EndFunction
) const {
200 assert(MMI
&& "MachineModuleInfo not registered!");
202 // Map all labels and get rid of any dead landing pads.
203 MMI
->TidyLandingPads(JCE
->getLabelLocations());
205 const std::vector
<const GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
206 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
207 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
208 if (PadInfos
.empty()) return 0;
210 // Sort the landing pads in order of their type ids. This is used to fold
211 // duplicate actions.
212 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
213 LandingPads
.reserve(PadInfos
.size());
214 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
215 LandingPads
.push_back(&PadInfos
[i
]);
216 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
218 // Negative type ids index into FilterIds, positive type ids index into
219 // TypeInfos. The value written for a positive type id is just the type
220 // id itself. For a negative type id, however, the value written is the
221 // (negative) byte offset of the corresponding FilterIds entry. The byte
222 // offset is usually equal to the type id, because the FilterIds entries
223 // are written using a variable width encoding which outputs one byte per
224 // entry as long as the value written is not too large, but can differ.
225 // This kind of complication does not occur for positive type ids because
226 // type infos are output using a fixed width encoding.
227 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
228 SmallVector
<int, 16> FilterOffsets
;
229 FilterOffsets
.reserve(FilterIds
.size());
231 for(std::vector
<unsigned>::const_iterator I
= FilterIds
.begin(),
232 E
= FilterIds
.end(); I
!= E
; ++I
) {
233 FilterOffsets
.push_back(Offset
);
234 Offset
-= MCAsmInfo::getULEB128Size(*I
);
237 // Compute the actions table and gather the first action index for each
239 SmallVector
<ActionEntry
, 32> Actions
;
240 SmallVector
<unsigned, 64> FirstActions
;
241 FirstActions
.reserve(LandingPads
.size());
244 unsigned SizeActions
= 0;
245 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
246 const LandingPadInfo
*LP
= LandingPads
[i
];
247 const std::vector
<int> &TypeIds
= LP
->TypeIds
;
248 const unsigned NumShared
= i
? SharedTypeIds(LP
, LandingPads
[i
-1]) : 0;
249 unsigned SizeSiteActions
= 0;
251 if (NumShared
< TypeIds
.size()) {
252 unsigned SizeAction
= 0;
253 ActionEntry
*PrevAction
= 0;
256 const unsigned SizePrevIds
= LandingPads
[i
-1]->TypeIds
.size();
257 assert(Actions
.size());
258 PrevAction
= &Actions
.back();
259 SizeAction
= MCAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
260 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
261 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
262 SizeAction
-= MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
263 SizeAction
+= -PrevAction
->NextAction
;
264 PrevAction
= PrevAction
->Previous
;
268 // Compute the actions.
269 for (unsigned I
= NumShared
, M
= TypeIds
.size(); I
!= M
; ++I
) {
270 int TypeID
= TypeIds
[I
];
271 assert(-1-TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
272 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
273 unsigned SizeTypeID
= MCAsmInfo::getSLEB128Size(ValueForTypeID
);
275 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
276 SizeAction
= SizeTypeID
+ MCAsmInfo::getSLEB128Size(NextAction
);
277 SizeSiteActions
+= SizeAction
;
279 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
280 Actions
.push_back(Action
);
282 PrevAction
= &Actions
.back();
285 // Record the first action of the landing pad site.
286 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
287 } // else identical - re-use previous FirstAction
289 FirstActions
.push_back(FirstAction
);
291 // Compute this sites contribution to size.
292 SizeActions
+= SizeSiteActions
;
295 // Compute the call-site table. Entries must be ordered by address.
296 SmallVector
<CallSiteEntry
, 64> CallSites
;
299 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
300 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
301 for (unsigned j
=0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
302 MCSymbol
*BeginLabel
= LandingPad
->BeginLabels
[j
];
303 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
304 PadRange P
= { i
, j
};
305 PadMap
[BeginLabel
] = P
;
309 bool MayThrow
= false;
310 MCSymbol
*LastLabel
= 0;
311 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
313 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
315 if (!MI
->isLabel()) {
316 MayThrow
|= MI
->getDesc().isCall();
320 MCSymbol
*BeginLabel
= MI
->getOperand(0).getMCSymbol();
321 assert(BeginLabel
&& "Invalid label!");
323 if (BeginLabel
== LastLabel
)
326 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
328 if (L
== PadMap
.end())
331 PadRange P
= L
->second
;
332 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
334 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
335 "Inconsistent landing pad map!");
337 // If some instruction between the previous try-range and this one may
338 // throw, create a call-site entry with no landing pad for the region
339 // between the try-ranges.
341 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
342 CallSites
.push_back(Site
);
345 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
346 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
347 LandingPad
->LandingPadLabel
, FirstActions
[P
.PadIndex
]};
349 assert(Site
.BeginLabel
&& Site
.EndLabel
&& Site
.PadLabel
&&
350 "Invalid landing pad!");
352 // Try to merge with the previous call-site.
353 if (CallSites
.size()) {
354 CallSiteEntry
&Prev
= CallSites
.back();
355 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
356 // Extend the range of the previous entry.
357 Prev
.EndLabel
= Site
.EndLabel
;
362 // Otherwise, create a new call-site.
363 CallSites
.push_back(Site
);
366 // If some instruction between the previous try-range and the end of the
367 // function may throw, create a call-site entry with no landing pad for the
368 // region following the try-range.
370 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
371 CallSites
.push_back(Site
);
375 unsigned SizeSites
= CallSites
.size() * (sizeof(int32_t) + // Site start.
376 sizeof(int32_t) + // Site length.
377 sizeof(int32_t)); // Landing pad.
378 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
379 SizeSites
+= MCAsmInfo::getULEB128Size(CallSites
[i
].Action
);
381 unsigned SizeTypes
= TypeInfos
.size() * TD
->getPointerSize();
383 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
384 // Call-site table length
385 MCAsmInfo::getULEB128Size(SizeSites
) +
386 SizeSites
+ SizeActions
+ SizeTypes
;
388 // Begin the exception table.
389 JCE
->emitAlignmentWithFill(4, 0);
390 // Asm->EOL("Padding");
392 unsigned char* DwarfExceptionTable
= (unsigned char*)JCE
->getCurrentPCValue();
395 JCE
->emitByte(dwarf::DW_EH_PE_omit
);
396 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
397 JCE
->emitByte(dwarf::DW_EH_PE_absptr
);
398 // Asm->EOL("TType format (DW_EH_PE_absptr)");
399 JCE
->emitULEB128Bytes(TypeOffset
);
400 // Asm->EOL("TType base offset");
401 JCE
->emitByte(dwarf::DW_EH_PE_udata4
);
402 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
403 JCE
->emitULEB128Bytes(SizeSites
);
404 // Asm->EOL("Call-site table length");
406 // Emit the landing pad site information.
407 for (unsigned i
= 0; i
< CallSites
.size(); ++i
) {
408 CallSiteEntry
&S
= CallSites
[i
];
409 intptr_t BeginLabelPtr
= 0;
410 intptr_t EndLabelPtr
= 0;
413 BeginLabelPtr
= (intptr_t)StartFunction
;
416 BeginLabelPtr
= JCE
->getLabelAddress(S
.BeginLabel
);
417 JCE
->emitInt32(BeginLabelPtr
- (intptr_t)StartFunction
);
420 // Asm->EOL("Region start");
423 EndLabelPtr
= (intptr_t)EndFunction
;
425 EndLabelPtr
= JCE
->getLabelAddress(S
.EndLabel
);
427 JCE
->emitInt32(EndLabelPtr
- BeginLabelPtr
);
428 //Asm->EOL("Region length");
433 unsigned PadLabelPtr
= JCE
->getLabelAddress(S
.PadLabel
);
434 JCE
->emitInt32(PadLabelPtr
- (intptr_t)StartFunction
);
436 // Asm->EOL("Landing pad");
438 JCE
->emitULEB128Bytes(S
.Action
);
439 // Asm->EOL("Action");
443 for (unsigned I
= 0, N
= Actions
.size(); I
!= N
; ++I
) {
444 ActionEntry
&Action
= Actions
[I
];
446 JCE
->emitSLEB128Bytes(Action
.ValueForTypeID
);
447 //Asm->EOL("TypeInfo index");
448 JCE
->emitSLEB128Bytes(Action
.NextAction
);
449 //Asm->EOL("Next action");
452 // Emit the type ids.
453 for (unsigned M
= TypeInfos
.size(); M
; --M
) {
454 const GlobalVariable
*GV
= TypeInfos
[M
- 1];
457 if (TD
->getPointerSize() == sizeof(int32_t))
458 JCE
->emitInt32((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
460 JCE
->emitInt64((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
462 if (TD
->getPointerSize() == sizeof(int32_t))
467 // Asm->EOL("TypeInfo");
470 // Emit the filter typeids.
471 for (unsigned j
= 0, M
= FilterIds
.size(); j
< M
; ++j
) {
472 unsigned TypeID
= FilterIds
[j
];
473 JCE
->emitULEB128Bytes(TypeID
);
474 //Asm->EOL("Filter TypeInfo index");
477 JCE
->emitAlignmentWithFill(4, 0);
479 return DwarfExceptionTable
;
483 JITDwarfEmitter::EmitCommonEHFrame(const Function
* Personality
) const {
484 unsigned PointerSize
= TD
->getPointerSize();
485 int stackGrowth
= stackGrowthDirection
== TargetFrameLowering::StackGrowsUp
?
486 PointerSize
: -PointerSize
;
488 unsigned char* StartCommonPtr
= (unsigned char*)JCE
->getCurrentPCValue();
489 // EH Common Frame header
490 JCE
->allocateSpace(4, 0);
491 unsigned char* FrameCommonBeginPtr
= (unsigned char*)JCE
->getCurrentPCValue();
492 JCE
->emitInt32((int)0);
493 JCE
->emitByte(dwarf::DW_CIE_VERSION
);
494 JCE
->emitString(Personality
? "zPLR" : "zR");
495 JCE
->emitULEB128Bytes(1);
496 JCE
->emitSLEB128Bytes(stackGrowth
);
497 JCE
->emitByte(RI
->getDwarfRegNum(RI
->getRARegister(), true));
500 // Augmentation Size: 3 small ULEBs of one byte each, and the personality
501 // function which size is PointerSize.
502 JCE
->emitULEB128Bytes(3 + PointerSize
);
504 // We set the encoding of the personality as direct encoding because we use
505 // the function pointer. The encoding is not relative because the current
506 // PC value may be bigger than the personality function pointer.
507 if (PointerSize
== 4) {
508 JCE
->emitByte(dwarf::DW_EH_PE_sdata4
);
509 JCE
->emitInt32(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
511 JCE
->emitByte(dwarf::DW_EH_PE_sdata8
);
512 JCE
->emitInt64(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
515 // LSDA encoding: This must match the encoding used in EmitEHFrame ()
516 if (PointerSize
== 4)
517 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
519 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata8
);
520 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
522 JCE
->emitULEB128Bytes(1);
523 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
526 std::vector
<MachineMove
> Moves
;
527 TFI
->getInitialFrameState(Moves
);
528 EmitFrameMoves(0, Moves
);
530 JCE
->emitAlignmentWithFill(PointerSize
, dwarf::DW_CFA_nop
);
532 JCE
->emitInt32At((uintptr_t*)StartCommonPtr
,
533 (uintptr_t)((unsigned char*)JCE
->getCurrentPCValue() -
534 FrameCommonBeginPtr
));
536 return StartCommonPtr
;
541 JITDwarfEmitter::EmitEHFrame(const Function
* Personality
,
542 unsigned char* StartCommonPtr
,
543 unsigned char* StartFunction
,
544 unsigned char* EndFunction
,
545 unsigned char* ExceptionTable
) const {
546 unsigned PointerSize
= TD
->getPointerSize();
549 unsigned char* StartEHPtr
= (unsigned char*)JCE
->getCurrentPCValue();
550 JCE
->allocateSpace(4, 0);
551 unsigned char* FrameBeginPtr
= (unsigned char*)JCE
->getCurrentPCValue();
553 JCE
->emitInt32(FrameBeginPtr
- StartCommonPtr
);
554 JCE
->emitInt32(StartFunction
- (unsigned char*)JCE
->getCurrentPCValue());
555 JCE
->emitInt32(EndFunction
- StartFunction
);
557 // If there is a personality and landing pads then point to the language
558 // specific data area in the exception table.
560 JCE
->emitULEB128Bytes(PointerSize
== 4 ? 4 : 8);
562 if (PointerSize
== 4) {
563 if (!MMI
->getLandingPads().empty())
564 JCE
->emitInt32(ExceptionTable
-(unsigned char*)JCE
->getCurrentPCValue());
566 JCE
->emitInt32((int)0);
568 if (!MMI
->getLandingPads().empty())
569 JCE
->emitInt64(ExceptionTable
-(unsigned char*)JCE
->getCurrentPCValue());
571 JCE
->emitInt64((int)0);
574 JCE
->emitULEB128Bytes(0);
577 // Indicate locations of function specific callee saved registers in
579 EmitFrameMoves((intptr_t)StartFunction
, MMI
->getFrameMoves());
581 JCE
->emitAlignmentWithFill(PointerSize
, dwarf::DW_CFA_nop
);
583 // Indicate the size of the table
584 JCE
->emitInt32At((uintptr_t*)StartEHPtr
,
585 (uintptr_t)((unsigned char*)JCE
->getCurrentPCValue() -
588 // Double zeroes for the unwind runtime
589 if (PointerSize
== 8) {