1 //===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
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 #include "llvm/MC/MCAsmInfo.h"
11 #include "llvm/MC/MCDwarf.h"
12 #include "llvm/MC/MCStreamer.h"
13 #include "llvm/MC/MCSymbol.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCObjectWriter.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Target/TargetAsmInfo.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/Twine.h"
27 // Given a special op, return the address skip amount (in units of
28 // DWARF2_LINE_MIN_INSN_LENGTH.
29 #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
31 // The maximum address skip amount that can be encoded with a special op.
32 #define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
34 // First special line opcode - leave room for the standard opcodes.
35 // Note: If you want to change this, you'll have to update the
36 // "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
37 #define DWARF2_LINE_OPCODE_BASE 13
39 // Minimum line offset in a special line info. opcode. This value
40 // was chosen to give a reasonable range of values.
41 #define DWARF2_LINE_BASE -5
43 // Range of line offsets in a special line info. opcode.
44 #define DWARF2_LINE_RANGE 14
46 // Define the architecture-dependent minimum instruction length (in bytes).
47 // This value should be rather too small than too big.
48 #define DWARF2_LINE_MIN_INSN_LENGTH 1
50 // Note: when DWARF2_LINE_MIN_INSN_LENGTH == 1 which is the current setting,
51 // this routine is a nop and will be optimized away.
52 static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta
) {
53 if (DWARF2_LINE_MIN_INSN_LENGTH
== 1)
55 if (AddrDelta
% DWARF2_LINE_MIN_INSN_LENGTH
!= 0) {
56 // TODO: report this error, but really only once.
59 return AddrDelta
/ DWARF2_LINE_MIN_INSN_LENGTH
;
63 // This is called when an instruction is assembled into the specified section
64 // and if there is information from the last .loc directive that has yet to have
65 // a line entry made for it is made.
67 void MCLineEntry::Make(MCStreamer
*MCOS
, const MCSection
*Section
) {
68 if (!MCOS
->getContext().getDwarfLocSeen())
71 // Create a symbol at in the current section for use in the line entry.
72 MCSymbol
*LineSym
= MCOS
->getContext().CreateTempSymbol();
73 // Set the value of the symbol to use for the MCLineEntry.
74 MCOS
->EmitLabel(LineSym
);
76 // Get the current .loc info saved in the context.
77 const MCDwarfLoc
&DwarfLoc
= MCOS
->getContext().getCurrentDwarfLoc();
79 // Create a (local) line entry with the symbol and the current .loc info.
80 MCLineEntry
LineEntry(LineSym
, DwarfLoc
);
82 // clear DwarfLocSeen saying the current .loc info is now used.
83 MCOS
->getContext().ClearDwarfLocSeen();
85 // Get the MCLineSection for this section, if one does not exist for this
87 const DenseMap
<const MCSection
*, MCLineSection
*> &MCLineSections
=
88 MCOS
->getContext().getMCLineSections();
89 MCLineSection
*LineSection
= MCLineSections
.lookup(Section
);
91 // Create a new MCLineSection. This will be deleted after the dwarf line
92 // table is created using it by iterating through the MCLineSections
94 LineSection
= new MCLineSection
;
95 // Save a pointer to the new LineSection into the MCLineSections DenseMap.
96 MCOS
->getContext().addMCLineSection(Section
, LineSection
);
99 // Add the line entry to this section's entries.
100 LineSection
->addLineEntry(LineEntry
);
104 // This helper routine returns an expression of End - Start + IntVal .
106 static inline const MCExpr
*MakeStartMinusEndExpr(const MCStreamer
&MCOS
,
107 const MCSymbol
&Start
,
110 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
112 MCSymbolRefExpr::Create(&End
, Variant
, MCOS
.getContext());
114 MCSymbolRefExpr::Create(&Start
, Variant
, MCOS
.getContext());
116 MCBinaryExpr::Create(MCBinaryExpr::Sub
, Res
, RHS
, MCOS
.getContext());
118 MCConstantExpr::Create(IntVal
, MCOS
.getContext());
120 MCBinaryExpr::Create(MCBinaryExpr::Sub
, Res1
, Res2
, MCOS
.getContext());
125 // This emits the Dwarf line table for the specified section from the entries
126 // in the LineSection.
128 static inline void EmitDwarfLineTable(MCStreamer
*MCOS
,
129 const MCSection
*Section
,
130 const MCLineSection
*LineSection
) {
131 unsigned FileNum
= 1;
132 unsigned LastLine
= 1;
134 unsigned Flags
= DWARF2_LINE_DEFAULT_IS_STMT
? DWARF2_FLAG_IS_STMT
: 0;
136 MCSymbol
*LastLabel
= NULL
;
138 // Loop through each MCLineEntry and encode the dwarf line number table.
139 for (MCLineSection::const_iterator
140 it
= LineSection
->getMCLineEntries()->begin(),
141 ie
= LineSection
->getMCLineEntries()->end(); it
!= ie
; ++it
) {
143 if (FileNum
!= it
->getFileNum()) {
144 FileNum
= it
->getFileNum();
145 MCOS
->EmitIntValue(dwarf::DW_LNS_set_file
, 1);
146 MCOS
->EmitULEB128IntValue(FileNum
);
148 if (Column
!= it
->getColumn()) {
149 Column
= it
->getColumn();
150 MCOS
->EmitIntValue(dwarf::DW_LNS_set_column
, 1);
151 MCOS
->EmitULEB128IntValue(Column
);
153 if (Isa
!= it
->getIsa()) {
155 MCOS
->EmitIntValue(dwarf::DW_LNS_set_isa
, 1);
156 MCOS
->EmitULEB128IntValue(Isa
);
158 if ((it
->getFlags() ^ Flags
) & DWARF2_FLAG_IS_STMT
) {
159 Flags
= it
->getFlags();
160 MCOS
->EmitIntValue(dwarf::DW_LNS_negate_stmt
, 1);
162 if (it
->getFlags() & DWARF2_FLAG_BASIC_BLOCK
)
163 MCOS
->EmitIntValue(dwarf::DW_LNS_set_basic_block
, 1);
164 if (it
->getFlags() & DWARF2_FLAG_PROLOGUE_END
)
165 MCOS
->EmitIntValue(dwarf::DW_LNS_set_prologue_end
, 1);
166 if (it
->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN
)
167 MCOS
->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin
, 1);
169 int64_t LineDelta
= static_cast<int64_t>(it
->getLine()) - LastLine
;
170 MCSymbol
*Label
= it
->getLabel();
172 // At this point we want to emit/create the sequence to encode the delta in
173 // line numbers and the increment of the address from the previous Label
174 // and the current Label.
175 MCOS
->EmitDwarfAdvanceLineAddr(LineDelta
, LastLabel
, Label
);
177 LastLine
= it
->getLine();
181 // Emit a DW_LNE_end_sequence for the end of the section.
182 // Using the pointer Section create a temporary label at the end of the
183 // section and use that and the LastLabel to compute the address delta
184 // and use INT64_MAX as the line delta which is the signal that this is
185 // actually a DW_LNE_end_sequence.
187 // Switch to the section to be able to create a symbol at its end.
188 MCOS
->SwitchSection(Section
);
190 MCContext
&context
= MCOS
->getContext();
191 // Create a symbol at the end of the section.
192 MCSymbol
*SectionEnd
= context
.CreateTempSymbol();
193 // Set the value of the symbol, as we are at the end of the section.
194 MCOS
->EmitLabel(SectionEnd
);
196 // Switch back the the dwarf line section.
197 MCOS
->SwitchSection(context
.getTargetAsmInfo().getDwarfLineSection());
199 MCOS
->EmitDwarfAdvanceLineAddr(INT64_MAX
, LastLabel
, SectionEnd
);
203 // This emits the Dwarf file and the line tables.
205 void MCDwarfFileTable::Emit(MCStreamer
*MCOS
) {
206 MCContext
&context
= MCOS
->getContext();
207 // Switch to the section where the table will be emitted into.
208 MCOS
->SwitchSection(context
.getTargetAsmInfo().getDwarfLineSection());
210 // Create a symbol at the beginning of this section.
211 MCSymbol
*LineStartSym
= context
.CreateTempSymbol();
212 // Set the value of the symbol, as we are at the start of the section.
213 MCOS
->EmitLabel(LineStartSym
);
215 // Create a symbol for the end of the section (to be set when we get there).
216 MCSymbol
*LineEndSym
= context
.CreateTempSymbol();
218 // The first 4 bytes is the total length of the information for this
219 // compilation unit (not including these 4 bytes for the length).
220 MCOS
->EmitAbsValue(MakeStartMinusEndExpr(*MCOS
, *LineStartSym
, *LineEndSym
,4),
223 // Next 2 bytes is the Version, which is Dwarf 2.
224 MCOS
->EmitIntValue(2, 2);
226 // Create a symbol for the end of the prologue (to be set when we get there).
227 MCSymbol
*ProEndSym
= context
.CreateTempSymbol(); // Lprologue_end
229 // Length of the prologue, is the next 4 bytes. Which is the start of the
230 // section to the end of the prologue. Not including the 4 bytes for the
231 // total length, the 2 bytes for the version, and these 4 bytes for the
232 // length of the prologue.
233 MCOS
->EmitAbsValue(MakeStartMinusEndExpr(*MCOS
, *LineStartSym
, *ProEndSym
,
237 // Parameters of the state machine, are next.
238 MCOS
->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH
, 1);
239 MCOS
->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT
, 1);
240 MCOS
->EmitIntValue(DWARF2_LINE_BASE
, 1);
241 MCOS
->EmitIntValue(DWARF2_LINE_RANGE
, 1);
242 MCOS
->EmitIntValue(DWARF2_LINE_OPCODE_BASE
, 1);
244 // Standard opcode lengths
245 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_copy
246 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_advance_pc
247 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_advance_line
248 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_set_file
249 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_set_column
250 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_negate_stmt
251 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_basic_block
252 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_const_add_pc
253 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_fixed_advance_pc
254 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_prologue_end
255 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_epilogue_begin
256 MCOS
->EmitIntValue(1, 1); // DW_LNS_set_isa
258 // Put out the directory and file tables.
260 // First the directory table.
261 const std::vector
<StringRef
> &MCDwarfDirs
=
262 context
.getMCDwarfDirs();
263 for (unsigned i
= 0; i
< MCDwarfDirs
.size(); i
++) {
264 MCOS
->EmitBytes(MCDwarfDirs
[i
], 0); // the DirectoryName
265 MCOS
->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
267 MCOS
->EmitIntValue(0, 1); // Terminate the directory list
269 // Second the file table.
270 const std::vector
<MCDwarfFile
*> &MCDwarfFiles
=
271 MCOS
->getContext().getMCDwarfFiles();
272 for (unsigned i
= 1; i
< MCDwarfFiles
.size(); i
++) {
273 MCOS
->EmitBytes(MCDwarfFiles
[i
]->getName(), 0); // FileName
274 MCOS
->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
276 MCOS
->EmitULEB128IntValue(MCDwarfFiles
[i
]->getDirIndex());
277 MCOS
->EmitIntValue(0, 1); // last modification timestamp (always 0)
278 MCOS
->EmitIntValue(0, 1); // filesize (always 0)
280 MCOS
->EmitIntValue(0, 1); // Terminate the file list
282 // This is the end of the prologue, so set the value of the symbol at the
283 // end of the prologue (that was used in a previous expression).
284 MCOS
->EmitLabel(ProEndSym
);
286 // Put out the line tables.
287 const DenseMap
<const MCSection
*, MCLineSection
*> &MCLineSections
=
288 MCOS
->getContext().getMCLineSections();
289 const std::vector
<const MCSection
*> &MCLineSectionOrder
=
290 MCOS
->getContext().getMCLineSectionOrder();
291 for (std::vector
<const MCSection
*>::const_iterator it
=
292 MCLineSectionOrder
.begin(), ie
= MCLineSectionOrder
.end(); it
!= ie
;
294 const MCSection
*Sec
= *it
;
295 const MCLineSection
*Line
= MCLineSections
.lookup(Sec
);
296 EmitDwarfLineTable(MCOS
, Sec
, Line
);
298 // Now delete the MCLineSections that were created in MCLineEntry::Make()
299 // and used to emit the line table.
303 if (MCOS
->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
304 && MCLineSectionOrder
.begin() == MCLineSectionOrder
.end()) {
305 // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
307 // total_length >= prologue_length + 10
308 // We are 4 bytes short, since we have total_length = 51 and
309 // prologue_length = 45
311 // The regular end_sequence should be sufficient.
312 MCDwarfLineAddr::Emit(MCOS
, INT64_MAX
, 0);
315 // This is the end of the section, so set the value of the symbol at the end
316 // of this section (that was used in a previous expression).
317 MCOS
->EmitLabel(LineEndSym
);
320 /// Utility function to write the encoding to an object writer.
321 void MCDwarfLineAddr::Write(MCObjectWriter
*OW
, int64_t LineDelta
,
322 uint64_t AddrDelta
) {
323 SmallString
<256> Tmp
;
324 raw_svector_ostream
OS(Tmp
);
325 MCDwarfLineAddr::Encode(LineDelta
, AddrDelta
, OS
);
326 OW
->WriteBytes(OS
.str());
329 /// Utility function to emit the encoding to a streamer.
330 void MCDwarfLineAddr::Emit(MCStreamer
*MCOS
, int64_t LineDelta
,
331 uint64_t AddrDelta
) {
332 SmallString
<256> Tmp
;
333 raw_svector_ostream
OS(Tmp
);
334 MCDwarfLineAddr::Encode(LineDelta
, AddrDelta
, OS
);
335 MCOS
->EmitBytes(OS
.str(), /*AddrSpace=*/0);
338 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
339 void MCDwarfLineAddr::Encode(int64_t LineDelta
, uint64_t AddrDelta
,
341 uint64_t Temp
, Opcode
;
342 bool NeedCopy
= false;
344 // Scale the address delta by the minimum instruction length.
345 AddrDelta
= ScaleAddrDelta(AddrDelta
);
347 // A LineDelta of INT64_MAX is a signal that this is actually a
348 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
349 // end_sequence to emit the matrix entry.
350 if (LineDelta
== INT64_MAX
) {
351 if (AddrDelta
== MAX_SPECIAL_ADDR_DELTA
)
352 OS
<< char(dwarf::DW_LNS_const_add_pc
);
354 OS
<< char(dwarf::DW_LNS_advance_pc
);
355 MCObjectWriter::EncodeULEB128(AddrDelta
, OS
);
357 OS
<< char(dwarf::DW_LNS_extended_op
);
359 OS
<< char(dwarf::DW_LNE_end_sequence
);
363 // Bias the line delta by the base.
364 Temp
= LineDelta
- DWARF2_LINE_BASE
;
366 // If the line increment is out of range of a special opcode, we must encode
367 // it with DW_LNS_advance_line.
368 if (Temp
>= DWARF2_LINE_RANGE
) {
369 OS
<< char(dwarf::DW_LNS_advance_line
);
371 raw_svector_ostream
OSE(Tmp
);
372 MCObjectWriter::EncodeSLEB128(LineDelta
, OSE
);
376 Temp
= 0 - DWARF2_LINE_BASE
;
380 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
381 if (LineDelta
== 0 && AddrDelta
== 0) {
382 OS
<< char(dwarf::DW_LNS_copy
);
386 // Bias the opcode by the special opcode base.
387 Temp
+= DWARF2_LINE_OPCODE_BASE
;
389 // Avoid overflow when addr_delta is large.
390 if (AddrDelta
< 256 + MAX_SPECIAL_ADDR_DELTA
) {
391 // Try using a special opcode.
392 Opcode
= Temp
+ AddrDelta
* DWARF2_LINE_RANGE
;
398 // Try using DW_LNS_const_add_pc followed by special op.
399 Opcode
= Temp
+ (AddrDelta
- MAX_SPECIAL_ADDR_DELTA
) * DWARF2_LINE_RANGE
;
401 OS
<< char(dwarf::DW_LNS_const_add_pc
);
407 // Otherwise use DW_LNS_advance_pc.
408 OS
<< char(dwarf::DW_LNS_advance_pc
);
410 raw_svector_ostream
OSE(Tmp
);
411 MCObjectWriter::EncodeULEB128(AddrDelta
, OSE
);
415 OS
<< char(dwarf::DW_LNS_copy
);
420 void MCDwarfFile::print(raw_ostream
&OS
) const {
421 OS
<< '"' << getName() << '"';
424 void MCDwarfFile::dump() const {
428 static int getDataAlignmentFactor(MCStreamer
&streamer
) {
429 MCContext
&context
= streamer
.getContext();
430 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
431 int size
= asmInfo
.getPointerSize();
432 if (asmInfo
.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp
)
438 static unsigned getSizeForEncoding(MCStreamer
&streamer
,
439 unsigned symbolEncoding
) {
440 MCContext
&context
= streamer
.getContext();
441 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
442 unsigned format
= symbolEncoding
& 0x0f;
445 assert(0 && "Unknown Encoding");
446 case dwarf::DW_EH_PE_absptr
:
447 case dwarf::DW_EH_PE_signed
:
448 return asmInfo
.getPointerSize();
449 case dwarf::DW_EH_PE_udata2
:
450 case dwarf::DW_EH_PE_sdata2
:
452 case dwarf::DW_EH_PE_udata4
:
453 case dwarf::DW_EH_PE_sdata4
:
455 case dwarf::DW_EH_PE_udata8
:
456 case dwarf::DW_EH_PE_sdata8
:
461 static void EmitSymbol(MCStreamer
&streamer
, const MCSymbol
&symbol
,
462 unsigned symbolEncoding
, const char *comment
= 0) {
463 MCContext
&context
= streamer
.getContext();
464 const MCAsmInfo
&asmInfo
= context
.getAsmInfo();
465 const MCExpr
*v
= asmInfo
.getExprForFDESymbol(&symbol
,
468 unsigned size
= getSizeForEncoding(streamer
, symbolEncoding
);
469 if (streamer
.isVerboseAsm() && comment
) streamer
.AddComment(comment
);
470 streamer
.EmitAbsValue(v
, size
);
473 static void EmitPersonality(MCStreamer
&streamer
, const MCSymbol
&symbol
,
474 unsigned symbolEncoding
) {
475 MCContext
&context
= streamer
.getContext();
476 const MCAsmInfo
&asmInfo
= context
.getAsmInfo();
477 const MCExpr
*v
= asmInfo
.getExprForPersonalitySymbol(&symbol
,
480 unsigned size
= getSizeForEncoding(streamer
, symbolEncoding
);
481 streamer
.EmitValue(v
, size
);
484 static const MachineLocation
TranslateMachineLocation(
485 const TargetAsmInfo
&AsmInfo
,
486 const MachineLocation
&Loc
) {
487 unsigned Reg
= Loc
.getReg() == MachineLocation::VirtualFP
?
488 MachineLocation::VirtualFP
:
489 unsigned(AsmInfo
.getDwarfRegNum(Loc
.getReg(), true));
490 const MachineLocation
&NewLoc
= Loc
.isReg() ?
491 MachineLocation(Reg
) : MachineLocation(Reg
, Loc
.getOffset());
496 class FrameEmitterImpl
{
501 const MCSymbol
*SectionStart
;
503 FrameEmitterImpl(bool usingCFI
, bool isEH
, const MCSymbol
*sectionStart
) :
504 CFAOffset(0), CIENum(0), UsingCFI(usingCFI
), IsEH(isEH
),
505 SectionStart(sectionStart
) {
508 /// EmitCompactUnwind - Emit the unwind information in a compact way. If
509 /// we're successful, return 'true'. Otherwise, return 'false' and it will
510 /// emit the normal CIE and FDE.
511 bool EmitCompactUnwind(MCStreamer
&streamer
,
512 const MCDwarfFrameInfo
&frame
);
514 const MCSymbol
&EmitCIE(MCStreamer
&streamer
,
515 const MCSymbol
*personality
,
516 unsigned personalityEncoding
,
517 const MCSymbol
*lsda
,
518 unsigned lsdaEncoding
);
519 MCSymbol
*EmitFDE(MCStreamer
&streamer
,
520 const MCSymbol
&cieStart
,
521 const MCDwarfFrameInfo
&frame
);
522 void EmitCFIInstructions(MCStreamer
&streamer
,
523 const std::vector
<MCCFIInstruction
> &Instrs
,
524 MCSymbol
*BaseLabel
);
525 void EmitCFIInstruction(MCStreamer
&Streamer
,
526 const MCCFIInstruction
&Instr
);
529 } // end anonymous namespace
531 static void EmitEncodingByte(MCStreamer
&Streamer
, unsigned Encoding
,
533 if (Streamer
.isVerboseAsm()) {
534 const char *EncStr
= 0;
536 default: EncStr
= "<unknown encoding>";
537 case dwarf::DW_EH_PE_absptr
: EncStr
= "absptr";
538 case dwarf::DW_EH_PE_omit
: EncStr
= "omit";
539 case dwarf::DW_EH_PE_pcrel
: EncStr
= "pcrel";
540 case dwarf::DW_EH_PE_udata4
: EncStr
= "udata4";
541 case dwarf::DW_EH_PE_udata8
: EncStr
= "udata8";
542 case dwarf::DW_EH_PE_sdata4
: EncStr
= "sdata4";
543 case dwarf::DW_EH_PE_sdata8
: EncStr
= "sdata8";
544 case dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_udata4
: EncStr
= "pcrel udata4";
545 case dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_sdata4
: EncStr
= "pcrel sdata4";
546 case dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_udata8
: EncStr
= "pcrel udata8";
547 case dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_sdata8
: EncStr
= "pcrel sdata8";
548 case dwarf::DW_EH_PE_indirect
|dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_udata4
:
549 EncStr
= "indirect pcrel udata4";
550 case dwarf::DW_EH_PE_indirect
|dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_sdata4
:
551 EncStr
= "indirect pcrel sdata4";
552 case dwarf::DW_EH_PE_indirect
|dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_udata8
:
553 EncStr
= "indirect pcrel udata8";
554 case dwarf::DW_EH_PE_indirect
|dwarf::DW_EH_PE_pcrel
|dwarf::DW_EH_PE_sdata8
:
555 EncStr
= "indirect pcrel sdata8";
558 Streamer
.AddComment(Twine(Prefix
) + " = " + EncStr
);
561 Streamer
.EmitIntValue(Encoding
, 1);
564 void FrameEmitterImpl::EmitCFIInstruction(MCStreamer
&Streamer
,
565 const MCCFIInstruction
&Instr
) {
566 int dataAlignmentFactor
= getDataAlignmentFactor(Streamer
);
567 bool VerboseAsm
= Streamer
.isVerboseAsm();
569 switch (Instr
.getOperation()) {
570 case MCCFIInstruction::Move
:
571 case MCCFIInstruction::RelMove
: {
572 const MachineLocation
&Dst
= Instr
.getDestination();
573 const MachineLocation
&Src
= Instr
.getSource();
574 const bool IsRelative
= Instr
.getOperation() == MCCFIInstruction::RelMove
;
577 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
578 if (Src
.getReg() == MachineLocation::VirtualFP
) {
579 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_def_cfa_offset");
580 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa_offset
, 1);
582 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_def_cfa");
583 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa
, 1);
584 if (VerboseAsm
) Streamer
.AddComment(Twine("Reg ") +
585 Twine(Src
.getReg()));
586 Streamer
.EmitULEB128IntValue(Src
.getReg());
590 CFAOffset
+= Src
.getOffset();
592 CFAOffset
= -Src
.getOffset();
594 if (VerboseAsm
) Streamer
.AddComment(Twine("Offset " + Twine(CFAOffset
)));
595 Streamer
.EmitULEB128IntValue(CFAOffset
);
599 if (Src
.isReg() && Src
.getReg() == MachineLocation::VirtualFP
) {
600 assert(Dst
.isReg() && "Machine move not supported yet.");
601 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_def_cfa_register");
602 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa_register
, 1);
603 if (VerboseAsm
) Streamer
.AddComment(Twine("Reg ") + Twine(Dst
.getReg()));
604 Streamer
.EmitULEB128IntValue(Dst
.getReg());
608 unsigned Reg
= Src
.getReg();
609 int Offset
= Dst
.getOffset();
612 Offset
= Offset
/ dataAlignmentFactor
;
615 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_offset_extended_sf");
616 Streamer
.EmitIntValue(dwarf::DW_CFA_offset_extended_sf
, 1);
617 if (VerboseAsm
) Streamer
.AddComment(Twine("Reg ") + Twine(Reg
));
618 Streamer
.EmitULEB128IntValue(Reg
);
619 if (VerboseAsm
) Streamer
.AddComment(Twine("Offset ") + Twine(Offset
));
620 Streamer
.EmitSLEB128IntValue(Offset
);
621 } else if (Reg
< 64) {
622 if (VerboseAsm
) Streamer
.AddComment(Twine("DW_CFA_offset + Reg(") +
624 Streamer
.EmitIntValue(dwarf::DW_CFA_offset
+ Reg
, 1);
625 if (VerboseAsm
) Streamer
.AddComment(Twine("Offset ") + Twine(Offset
));
626 Streamer
.EmitULEB128IntValue(Offset
);
628 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_offset_extended");
629 Streamer
.EmitIntValue(dwarf::DW_CFA_offset_extended
, 1);
630 if (VerboseAsm
) Streamer
.AddComment(Twine("Reg ") + Twine(Reg
));
631 Streamer
.EmitULEB128IntValue(Reg
);
632 if (VerboseAsm
) Streamer
.AddComment(Twine("Offset ") + Twine(Offset
));
633 Streamer
.EmitULEB128IntValue(Offset
);
637 case MCCFIInstruction::Remember
:
638 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_remember_state");
639 Streamer
.EmitIntValue(dwarf::DW_CFA_remember_state
, 1);
641 case MCCFIInstruction::Restore
:
642 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_restore_state");
643 Streamer
.EmitIntValue(dwarf::DW_CFA_restore_state
, 1);
645 case MCCFIInstruction::SameValue
: {
646 unsigned Reg
= Instr
.getDestination().getReg();
647 if (VerboseAsm
) Streamer
.AddComment("DW_CFA_same_value");
648 Streamer
.EmitIntValue(dwarf::DW_CFA_same_value
, 1);
649 if (VerboseAsm
) Streamer
.AddComment(Twine("Reg ") + Twine(Reg
));
650 Streamer
.EmitULEB128IntValue(Reg
);
654 llvm_unreachable("Unhandled case in switch");
657 /// EmitFrameMoves - Emit frame instructions to describe the layout of the
659 void FrameEmitterImpl::EmitCFIInstructions(MCStreamer
&streamer
,
660 const std::vector
<MCCFIInstruction
> &Instrs
,
661 MCSymbol
*BaseLabel
) {
662 for (unsigned i
= 0, N
= Instrs
.size(); i
< N
; ++i
) {
663 const MCCFIInstruction
&Instr
= Instrs
[i
];
664 MCSymbol
*Label
= Instr
.getLabel();
665 // Throw out move if the label is invalid.
666 if (Label
&& !Label
->isDefined()) continue; // Not emitted, in dead code.
668 // Advance row if new location.
669 if (BaseLabel
&& Label
) {
670 MCSymbol
*ThisSym
= Label
;
671 if (ThisSym
!= BaseLabel
) {
672 if (streamer
.isVerboseAsm()) streamer
.AddComment("DW_CFA_advance_loc4");
673 streamer
.EmitDwarfAdvanceFrameAddr(BaseLabel
, ThisSym
);
678 EmitCFIInstruction(streamer
, Instr
);
682 /// EmitCompactUnwind - Emit the unwind information in a compact way. If we're
683 /// successful, return 'true'. Otherwise, return 'false' and it will emit the
684 /// normal CIE and FDE.
685 bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer
&Streamer
,
686 const MCDwarfFrameInfo
&Frame
) {
690 MCContext
&Context
= Streamer
.getContext();
691 const TargetAsmInfo
&TAI
= Context
.getTargetAsmInfo();
692 bool VerboseAsm
= Streamer
.isVerboseAsm();
694 // range-start range-length compact-unwind-enc personality-func lsda
695 // _foo LfooEnd-_foo 0x00000023 0 0
696 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
698 // .section __LD,__compact_unwind,regular,debug
700 // # compact unwind for _foo
702 // .set L1,LfooEnd-_foo
708 // # compact unwind for _bar
710 // .set L2,LbarEnd-_bar
713 // .quad __gxx_personality
717 TAI
.getCompactUnwindEncoding(Frame
.Instructions
,
718 getDataAlignmentFactor(Streamer
), IsEH
);
719 if (!Encoding
) return false;
721 Streamer
.SwitchSection(TAI
.getCompactUnwindSection());
724 unsigned FDEEncoding
= TAI
.getFDEEncoding(UsingCFI
);
725 unsigned Size
= getSizeForEncoding(Streamer
, FDEEncoding
);
726 if (VerboseAsm
) Streamer
.AddComment("Range Start");
727 Streamer
.EmitSymbolValue(Frame
.Function
, Size
);
730 const MCExpr
*Range
= MakeStartMinusEndExpr(Streamer
, *Frame
.Begin
,
732 if (VerboseAsm
) Streamer
.AddComment("Range Length");
733 Streamer
.EmitAbsValue(Range
, 4);
736 Size
= getSizeForEncoding(Streamer
, dwarf::DW_EH_PE_udata4
);
737 if (VerboseAsm
) Streamer
.AddComment(Twine("Compact Unwind Encoding: 0x") +
738 Twine(llvm::utohexstr(Encoding
)));
739 Streamer
.EmitIntValue(Encoding
, Size
);
741 // Personality Function
742 Size
= getSizeForEncoding(Streamer
, Frame
.PersonalityEncoding
);
743 if (VerboseAsm
) Streamer
.AddComment("Personality Function");
744 if (Frame
.Personality
)
745 Streamer
.EmitSymbolValue(Frame
.Personality
, Size
);
747 Streamer
.EmitIntValue(0, Size
); // No personality fn
750 Size
= getSizeForEncoding(Streamer
, Frame
.LsdaEncoding
);
751 if (VerboseAsm
) Streamer
.AddComment("LSDA");
753 Streamer
.EmitSymbolValue(Frame
.Lsda
, Size
);
755 Streamer
.EmitIntValue(0, Size
); // No LSDA
761 const MCSymbol
&FrameEmitterImpl::EmitCIE(MCStreamer
&streamer
,
762 const MCSymbol
*personality
,
763 unsigned personalityEncoding
,
764 const MCSymbol
*lsda
,
765 unsigned lsdaEncoding
) {
766 MCContext
&context
= streamer
.getContext();
767 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
768 bool verboseAsm
= streamer
.isVerboseAsm();
770 MCSymbol
*sectionStart
;
771 if (asmInfo
.isFunctionEHFrameSymbolPrivate() || !IsEH
)
772 sectionStart
= context
.CreateTempSymbol();
774 sectionStart
= context
.GetOrCreateSymbol(Twine("EH_frame") + Twine(CIENum
));
776 streamer
.EmitLabel(sectionStart
);
779 MCSymbol
*sectionEnd
= context
.CreateTempSymbol();
782 const MCExpr
*Length
= MakeStartMinusEndExpr(streamer
, *sectionStart
,
784 if (verboseAsm
) streamer
.AddComment("CIE Length");
785 streamer
.EmitAbsValue(Length
, 4);
788 unsigned CIE_ID
= IsEH
? 0 : -1;
789 if (verboseAsm
) streamer
.AddComment("CIE ID Tag");
790 streamer
.EmitIntValue(CIE_ID
, 4);
793 if (verboseAsm
) streamer
.AddComment("DW_CIE_VERSION");
794 streamer
.EmitIntValue(dwarf::DW_CIE_VERSION
, 1);
796 // Augmentation String
797 SmallString
<8> Augmentation
;
799 if (verboseAsm
) streamer
.AddComment("CIE Augmentation");
806 streamer
.EmitBytes(Augmentation
.str(), 0);
808 streamer
.EmitIntValue(0, 1);
810 // Code Alignment Factor
811 if (verboseAsm
) streamer
.AddComment("CIE Code Alignment Factor");
812 streamer
.EmitULEB128IntValue(1);
814 // Data Alignment Factor
815 if (verboseAsm
) streamer
.AddComment("CIE Data Alignment Factor");
816 streamer
.EmitSLEB128IntValue(getDataAlignmentFactor(streamer
));
818 // Return Address Register
819 if (verboseAsm
) streamer
.AddComment("CIE Return Address Column");
820 streamer
.EmitULEB128IntValue(asmInfo
.getDwarfRARegNum(true));
822 // Augmentation Data Length (optional)
824 unsigned augmentationLength
= 0;
827 // Personality Encoding
828 augmentationLength
+= 1;
830 augmentationLength
+= getSizeForEncoding(streamer
, personalityEncoding
);
833 augmentationLength
+= 1;
834 // Encoding of the FDE pointers
835 augmentationLength
+= 1;
837 if (verboseAsm
) streamer
.AddComment("Augmentation Size");
838 streamer
.EmitULEB128IntValue(augmentationLength
);
840 // Augmentation Data (optional)
842 // Personality Encoding
843 EmitEncodingByte(streamer
, personalityEncoding
,
844 "Personality Encoding");
846 if (verboseAsm
) streamer
.AddComment("Personality");
847 EmitPersonality(streamer
, *personality
, personalityEncoding
);
851 EmitEncodingByte(streamer
, lsdaEncoding
, "LSDA Encoding");
853 // Encoding of the FDE pointers
854 EmitEncodingByte(streamer
, asmInfo
.getFDEEncoding(UsingCFI
),
858 // Initial Instructions
860 const std::vector
<MachineMove
> &Moves
= asmInfo
.getInitialFrameState();
861 std::vector
<MCCFIInstruction
> Instructions
;
863 for (int i
= 0, n
= Moves
.size(); i
!= n
; ++i
) {
864 MCSymbol
*Label
= Moves
[i
].getLabel();
865 const MachineLocation
&Dst
=
866 TranslateMachineLocation(asmInfo
, Moves
[i
].getDestination());
867 const MachineLocation
&Src
=
868 TranslateMachineLocation(asmInfo
, Moves
[i
].getSource());
869 MCCFIInstruction
Inst(Label
, Dst
, Src
);
870 Instructions
.push_back(Inst
);
873 EmitCFIInstructions(streamer
, Instructions
, NULL
);
876 streamer
.EmitValueToAlignment(IsEH
? 4 : asmInfo
.getPointerSize());
878 streamer
.EmitLabel(sectionEnd
);
879 return *sectionStart
;
882 MCSymbol
*FrameEmitterImpl::EmitFDE(MCStreamer
&streamer
,
883 const MCSymbol
&cieStart
,
884 const MCDwarfFrameInfo
&frame
) {
885 MCContext
&context
= streamer
.getContext();
886 MCSymbol
*fdeStart
= context
.CreateTempSymbol();
887 MCSymbol
*fdeEnd
= context
.CreateTempSymbol();
888 const TargetAsmInfo
&TAsmInfo
= context
.getTargetAsmInfo();
889 bool verboseAsm
= streamer
.isVerboseAsm();
891 if (!TAsmInfo
.isFunctionEHFrameSymbolPrivate() && IsEH
) {
893 context
.GetOrCreateSymbol(frame
.Function
->getName() + Twine(".eh"));
894 streamer
.EmitEHSymAttributes(frame
.Function
, EHSym
);
895 streamer
.EmitLabel(EHSym
);
899 const MCExpr
*Length
= MakeStartMinusEndExpr(streamer
, *fdeStart
, *fdeEnd
, 0);
900 if (verboseAsm
) streamer
.AddComment("FDE Length");
901 streamer
.EmitAbsValue(Length
, 4);
903 streamer
.EmitLabel(fdeStart
);
906 const MCAsmInfo
&asmInfo
= context
.getAsmInfo();
908 const MCExpr
*offset
= MakeStartMinusEndExpr(streamer
, cieStart
, *fdeStart
,
910 if (verboseAsm
) streamer
.AddComment("FDE CIE Offset");
911 streamer
.EmitAbsValue(offset
, 4);
912 } else if (!asmInfo
.doesDwarfRequireRelocationForSectionOffset()) {
913 const MCExpr
*offset
= MakeStartMinusEndExpr(streamer
, *SectionStart
,
915 streamer
.EmitAbsValue(offset
, 4);
917 streamer
.EmitSymbolValue(&cieStart
, 4);
920 unsigned fdeEncoding
= TAsmInfo
.getFDEEncoding(UsingCFI
);
921 unsigned size
= getSizeForEncoding(streamer
, fdeEncoding
);
924 unsigned PCBeginEncoding
= IsEH
? fdeEncoding
:
925 (unsigned)dwarf::DW_EH_PE_absptr
;
926 unsigned PCBeginSize
= getSizeForEncoding(streamer
, PCBeginEncoding
);
927 EmitSymbol(streamer
, *frame
.Begin
, PCBeginEncoding
, "FDE initial location");
930 const MCExpr
*Range
= MakeStartMinusEndExpr(streamer
, *frame
.Begin
,
932 if (verboseAsm
) streamer
.AddComment("FDE address range");
933 streamer
.EmitAbsValue(Range
, size
);
936 // Augmentation Data Length
937 unsigned augmentationLength
= 0;
940 augmentationLength
+= getSizeForEncoding(streamer
, frame
.LsdaEncoding
);
942 if (verboseAsm
) streamer
.AddComment("Augmentation size");
943 streamer
.EmitULEB128IntValue(augmentationLength
);
947 EmitSymbol(streamer
, *frame
.Lsda
, frame
.LsdaEncoding
,
948 "Language Specific Data Area");
951 // Call Frame Instructions
953 EmitCFIInstructions(streamer
, frame
.Instructions
, frame
.Begin
);
956 streamer
.EmitValueToAlignment(PCBeginSize
);
963 static const CIEKey
getEmptyKey() { return CIEKey(0, 0, -1); }
964 static const CIEKey
getTombstoneKey() { return CIEKey(0, -1, 0); }
966 CIEKey(const MCSymbol
* Personality_
, unsigned PersonalityEncoding_
,
967 unsigned LsdaEncoding_
) : Personality(Personality_
),
968 PersonalityEncoding(PersonalityEncoding_
),
969 LsdaEncoding(LsdaEncoding_
) {
971 const MCSymbol
* Personality
;
972 unsigned PersonalityEncoding
;
973 unsigned LsdaEncoding
;
979 struct DenseMapInfo
<CIEKey
> {
980 static CIEKey
getEmptyKey() {
981 return CIEKey::getEmptyKey();
983 static CIEKey
getTombstoneKey() {
984 return CIEKey::getTombstoneKey();
986 static unsigned getHashValue(const CIEKey
&Key
) {
988 ID
.AddPointer(Key
.Personality
);
989 ID
.AddInteger(Key
.PersonalityEncoding
);
990 ID
.AddInteger(Key
.LsdaEncoding
);
991 return ID
.ComputeHash();
993 static bool isEqual(const CIEKey
&LHS
,
995 return LHS
.Personality
== RHS
.Personality
&&
996 LHS
.PersonalityEncoding
== RHS
.PersonalityEncoding
&&
997 LHS
.LsdaEncoding
== RHS
.LsdaEncoding
;
1002 void MCDwarfFrameEmitter::Emit(MCStreamer
&Streamer
,
1005 MCContext
&Context
= Streamer
.getContext();
1006 const TargetAsmInfo
&AsmInfo
= Context
.getTargetAsmInfo();
1007 const MCSection
&Section
= IsEH
? *AsmInfo
.getEHFrameSection() :
1008 *AsmInfo
.getDwarfFrameSection();
1009 Streamer
.SwitchSection(&Section
);
1010 MCSymbol
*SectionStart
= Context
.CreateTempSymbol();
1011 Streamer
.EmitLabel(SectionStart
);
1013 MCSymbol
*FDEEnd
= NULL
;
1014 DenseMap
<CIEKey
, const MCSymbol
*> CIEStarts
;
1015 FrameEmitterImpl
Emitter(UsingCFI
, IsEH
, SectionStart
);
1017 const MCSymbol
*DummyDebugKey
= NULL
;
1018 for (unsigned i
= 0, n
= Streamer
.getNumFrameInfos(); i
< n
; ++i
) {
1019 const MCDwarfFrameInfo
&Frame
= Streamer
.getFrameInfo(i
);
1020 if (IsEH
&& AsmInfo
.getCompactUnwindSection() &&
1021 Emitter
.EmitCompactUnwind(Streamer
, Frame
))
1024 CIEKey
Key(Frame
.Personality
, Frame
.PersonalityEncoding
,
1025 Frame
.LsdaEncoding
);
1026 const MCSymbol
*&CIEStart
= IsEH
? CIEStarts
[Key
] : DummyDebugKey
;
1028 CIEStart
= &Emitter
.EmitCIE(Streamer
, Frame
.Personality
,
1029 Frame
.PersonalityEncoding
, Frame
.Lsda
,
1030 Frame
.LsdaEncoding
);
1032 FDEEnd
= Emitter
.EmitFDE(Streamer
, *CIEStart
, Frame
);
1035 Streamer
.EmitLabel(FDEEnd
);
1038 Streamer
.EmitValueToAlignment(AsmInfo
.getPointerSize());
1040 Streamer
.EmitLabel(FDEEnd
);
1043 void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer
&Streamer
,
1044 uint64_t AddrDelta
) {
1045 SmallString
<256> Tmp
;
1046 raw_svector_ostream
OS(Tmp
);
1047 MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta
, OS
);
1048 Streamer
.EmitBytes(OS
.str(), /*AddrSpace=*/0);
1051 void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta
,
1053 // FIXME: Assumes the code alignment factor is 1.
1054 if (AddrDelta
== 0) {
1055 } else if (isUIntN(6, AddrDelta
)) {
1056 uint8_t Opcode
= dwarf::DW_CFA_advance_loc
| AddrDelta
;
1058 } else if (isUInt
<8>(AddrDelta
)) {
1059 OS
<< uint8_t(dwarf::DW_CFA_advance_loc1
);
1060 OS
<< uint8_t(AddrDelta
);
1061 } else if (isUInt
<16>(AddrDelta
)) {
1062 // FIXME: check what is the correct behavior on a big endian machine.
1063 OS
<< uint8_t(dwarf::DW_CFA_advance_loc2
);
1064 OS
<< uint8_t( AddrDelta
& 0xff);
1065 OS
<< uint8_t((AddrDelta
>> 8) & 0xff);
1067 // FIXME: check what is the correct behavior on a big endian machine.
1068 assert(isUInt
<32>(AddrDelta
));
1069 OS
<< uint8_t(dwarf::DW_CFA_advance_loc4
);
1070 OS
<< uint8_t( AddrDelta
& 0xff);
1071 OS
<< uint8_t((AddrDelta
>> 8) & 0xff);
1072 OS
<< uint8_t((AddrDelta
>> 16) & 0xff);
1073 OS
<< uint8_t((AddrDelta
>> 24) & 0xff);