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/ADT/FoldingSet.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCDwarf.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCStreamer.h"
15 #include "llvm/MC/MCSymbol.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/Target/TargetAsmBackend.h"
24 #include "llvm/Target/TargetAsmInfo.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
)
54 if (DWARF2_LINE_MIN_INSN_LENGTH
== 1)
56 if (AddrDelta
% DWARF2_LINE_MIN_INSN_LENGTH
!= 0) {
57 // TODO: report this error, but really only once.
60 return AddrDelta
/ DWARF2_LINE_MIN_INSN_LENGTH
;
64 // This is called when an instruction is assembled into the specified section
65 // and if there is information from the last .loc directive that has yet to have
66 // a line entry made for it is made.
68 void MCLineEntry::Make(MCStreamer
*MCOS
, const MCSection
*Section
) {
69 if (!MCOS
->getContext().getDwarfLocSeen())
72 // Create a symbol at in the current section for use in the line entry.
73 MCSymbol
*LineSym
= MCOS
->getContext().CreateTempSymbol();
74 // Set the value of the symbol to use for the MCLineEntry.
75 MCOS
->EmitLabel(LineSym
);
77 // Get the current .loc info saved in the context.
78 const MCDwarfLoc
&DwarfLoc
= MCOS
->getContext().getCurrentDwarfLoc();
80 // Create a (local) line entry with the symbol and the current .loc info.
81 MCLineEntry
LineEntry(LineSym
, DwarfLoc
);
83 // clear DwarfLocSeen saying the current .loc info is now used.
84 MCOS
->getContext().ClearDwarfLocSeen();
86 // Get the MCLineSection for this section, if one does not exist for this
88 const DenseMap
<const MCSection
*, MCLineSection
*> &MCLineSections
=
89 MCOS
->getContext().getMCLineSections();
90 MCLineSection
*LineSection
= MCLineSections
.lookup(Section
);
92 // Create a new MCLineSection. This will be deleted after the dwarf line
93 // table is created using it by iterating through the MCLineSections
95 LineSection
= new MCLineSection
;
96 // Save a pointer to the new LineSection into the MCLineSections DenseMap.
97 MCOS
->getContext().addMCLineSection(Section
, LineSection
);
100 // Add the line entry to this section's entries.
101 LineSection
->addLineEntry(LineEntry
);
105 // This helper routine returns an expression of End - Start + IntVal .
107 static inline const MCExpr
*MakeStartMinusEndExpr(const MCStreamer
&MCOS
,
108 const MCSymbol
&Start
,
111 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
113 MCSymbolRefExpr::Create(&End
, Variant
, MCOS
.getContext());
115 MCSymbolRefExpr::Create(&Start
, Variant
, MCOS
.getContext());
117 MCBinaryExpr::Create(MCBinaryExpr::Sub
, Res
, RHS
, MCOS
.getContext());
119 MCConstantExpr::Create(IntVal
, MCOS
.getContext());
121 MCBinaryExpr::Create(MCBinaryExpr::Sub
, Res1
, Res2
, MCOS
.getContext());
126 // This emits the Dwarf line table for the specified section from the entries
127 // in the LineSection.
129 static inline void EmitDwarfLineTable(MCStreamer
*MCOS
,
130 const MCSection
*Section
,
131 const MCLineSection
*LineSection
) {
132 unsigned FileNum
= 1;
133 unsigned LastLine
= 1;
135 unsigned Flags
= DWARF2_LINE_DEFAULT_IS_STMT
? DWARF2_FLAG_IS_STMT
: 0;
137 MCSymbol
*LastLabel
= NULL
;
139 // Loop through each MCLineEntry and encode the dwarf line number table.
140 for (MCLineSection::const_iterator
141 it
= LineSection
->getMCLineEntries()->begin(),
142 ie
= LineSection
->getMCLineEntries()->end(); it
!= ie
; ++it
) {
144 if (FileNum
!= it
->getFileNum()) {
145 FileNum
= it
->getFileNum();
146 MCOS
->EmitIntValue(dwarf::DW_LNS_set_file
, 1);
147 MCOS
->EmitULEB128IntValue(FileNum
);
149 if (Column
!= it
->getColumn()) {
150 Column
= it
->getColumn();
151 MCOS
->EmitIntValue(dwarf::DW_LNS_set_column
, 1);
152 MCOS
->EmitULEB128IntValue(Column
);
154 if (Isa
!= it
->getIsa()) {
156 MCOS
->EmitIntValue(dwarf::DW_LNS_set_isa
, 1);
157 MCOS
->EmitULEB128IntValue(Isa
);
159 if ((it
->getFlags() ^ Flags
) & DWARF2_FLAG_IS_STMT
) {
160 Flags
= it
->getFlags();
161 MCOS
->EmitIntValue(dwarf::DW_LNS_negate_stmt
, 1);
163 if (it
->getFlags() & DWARF2_FLAG_BASIC_BLOCK
)
164 MCOS
->EmitIntValue(dwarf::DW_LNS_set_basic_block
, 1);
165 if (it
->getFlags() & DWARF2_FLAG_PROLOGUE_END
)
166 MCOS
->EmitIntValue(dwarf::DW_LNS_set_prologue_end
, 1);
167 if (it
->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN
)
168 MCOS
->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin
, 1);
170 int64_t LineDelta
= static_cast<int64_t>(it
->getLine()) - LastLine
;
171 MCSymbol
*Label
= it
->getLabel();
173 // At this point we want to emit/create the sequence to encode the delta in
174 // line numbers and the increment of the address from the previous Label
175 // and the current Label.
176 MCOS
->EmitDwarfAdvanceLineAddr(LineDelta
, LastLabel
, Label
);
178 LastLine
= it
->getLine();
182 // Emit a DW_LNE_end_sequence for the end of the section.
183 // Using the pointer Section create a temporary label at the end of the
184 // section and use that and the LastLabel to compute the address delta
185 // and use INT64_MAX as the line delta which is the signal that this is
186 // actually a DW_LNE_end_sequence.
188 // Switch to the section to be able to create a symbol at its end.
189 MCOS
->SwitchSection(Section
);
191 MCContext
&context
= MCOS
->getContext();
192 // Create a symbol at the end of the section.
193 MCSymbol
*SectionEnd
= context
.CreateTempSymbol();
194 // Set the value of the symbol, as we are at the end of the section.
195 MCOS
->EmitLabel(SectionEnd
);
197 // Switch back the the dwarf line section.
198 MCOS
->SwitchSection(context
.getTargetAsmInfo().getDwarfLineSection());
200 MCOS
->EmitDwarfAdvanceLineAddr(INT64_MAX
, LastLabel
, SectionEnd
);
204 // This emits the Dwarf file and the line tables.
206 void MCDwarfFileTable::Emit(MCStreamer
*MCOS
) {
207 MCContext
&context
= MCOS
->getContext();
208 // Switch to the section where the table will be emitted into.
209 MCOS
->SwitchSection(context
.getTargetAsmInfo().getDwarfLineSection());
211 // Create a symbol at the beginning of this section.
212 MCSymbol
*LineStartSym
= context
.CreateTempSymbol();
213 // Set the value of the symbol, as we are at the start of the section.
214 MCOS
->EmitLabel(LineStartSym
);
216 // Create a symbol for the end of the section (to be set when we get there).
217 MCSymbol
*LineEndSym
= context
.CreateTempSymbol();
219 // The first 4 bytes is the total length of the information for this
220 // compilation unit (not including these 4 bytes for the length).
221 MCOS
->EmitAbsValue(MakeStartMinusEndExpr(*MCOS
, *LineStartSym
, *LineEndSym
,4),
224 // Next 2 bytes is the Version, which is Dwarf 2.
225 MCOS
->EmitIntValue(2, 2);
227 // Create a symbol for the end of the prologue (to be set when we get there).
228 MCSymbol
*ProEndSym
= context
.CreateTempSymbol(); // Lprologue_end
230 // Length of the prologue, is the next 4 bytes. Which is the start of the
231 // section to the end of the prologue. Not including the 4 bytes for the
232 // total length, the 2 bytes for the version, and these 4 bytes for the
233 // length of the prologue.
234 MCOS
->EmitAbsValue(MakeStartMinusEndExpr(*MCOS
, *LineStartSym
, *ProEndSym
,
238 // Parameters of the state machine, are next.
239 MCOS
->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH
, 1);
240 MCOS
->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT
, 1);
241 MCOS
->EmitIntValue(DWARF2_LINE_BASE
, 1);
242 MCOS
->EmitIntValue(DWARF2_LINE_RANGE
, 1);
243 MCOS
->EmitIntValue(DWARF2_LINE_OPCODE_BASE
, 1);
245 // Standard opcode lengths
246 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_copy
247 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_advance_pc
248 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_advance_line
249 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_set_file
250 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_set_column
251 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_negate_stmt
252 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_basic_block
253 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_const_add_pc
254 MCOS
->EmitIntValue(1, 1); // length of DW_LNS_fixed_advance_pc
255 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_prologue_end
256 MCOS
->EmitIntValue(0, 1); // length of DW_LNS_set_epilogue_begin
257 MCOS
->EmitIntValue(1, 1); // DW_LNS_set_isa
259 // Put out the directory and file tables.
261 // First the directory table.
262 const std::vector
<StringRef
> &MCDwarfDirs
=
263 context
.getMCDwarfDirs();
264 for (unsigned i
= 0; i
< MCDwarfDirs
.size(); i
++) {
265 MCOS
->EmitBytes(MCDwarfDirs
[i
], 0); // the DirectoryName
266 MCOS
->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
268 MCOS
->EmitIntValue(0, 1); // Terminate the directory list
270 // Second the file table.
271 const std::vector
<MCDwarfFile
*> &MCDwarfFiles
=
272 MCOS
->getContext().getMCDwarfFiles();
273 for (unsigned i
= 1; i
< MCDwarfFiles
.size(); i
++) {
274 MCOS
->EmitBytes(MCDwarfFiles
[i
]->getName(), 0); // FileName
275 MCOS
->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
277 MCOS
->EmitULEB128IntValue(MCDwarfFiles
[i
]->getDirIndex());
278 MCOS
->EmitIntValue(0, 1); // last modification timestamp (always 0)
279 MCOS
->EmitIntValue(0, 1); // filesize (always 0)
281 MCOS
->EmitIntValue(0, 1); // Terminate the file list
283 // This is the end of the prologue, so set the value of the symbol at the
284 // end of the prologue (that was used in a previous expression).
285 MCOS
->EmitLabel(ProEndSym
);
287 // Put out the line tables.
288 const DenseMap
<const MCSection
*, MCLineSection
*> &MCLineSections
=
289 MCOS
->getContext().getMCLineSections();
290 const std::vector
<const MCSection
*> &MCLineSectionOrder
=
291 MCOS
->getContext().getMCLineSectionOrder();
292 for (std::vector
<const MCSection
*>::const_iterator it
=
293 MCLineSectionOrder
.begin(), ie
= MCLineSectionOrder
.end(); it
!= ie
;
295 const MCSection
*Sec
= *it
;
296 const MCLineSection
*Line
= MCLineSections
.lookup(Sec
);
297 EmitDwarfLineTable(MCOS
, Sec
, Line
);
299 // Now delete the MCLineSections that were created in MCLineEntry::Make()
300 // and used to emit the line table.
304 if (MCOS
->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
305 && MCLineSectionOrder
.begin() == MCLineSectionOrder
.end()) {
306 // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
308 // total_length >= prologue_length + 10
309 // We are 4 bytes short, since we have total_length = 51 and
310 // prologue_length = 45
312 // The regular end_sequence should be sufficient.
313 MCDwarfLineAddr::Emit(MCOS
, INT64_MAX
, 0);
316 // This is the end of the section, so set the value of the symbol at the end
317 // of this section (that was used in a previous expression).
318 MCOS
->EmitLabel(LineEndSym
);
321 /// Utility function to write the encoding to an object writer.
322 void MCDwarfLineAddr::Write(MCObjectWriter
*OW
, int64_t LineDelta
,
323 uint64_t AddrDelta
) {
324 SmallString
<256> Tmp
;
325 raw_svector_ostream
OS(Tmp
);
326 MCDwarfLineAddr::Encode(LineDelta
, AddrDelta
, OS
);
327 OW
->WriteBytes(OS
.str());
330 /// Utility function to emit the encoding to a streamer.
331 void MCDwarfLineAddr::Emit(MCStreamer
*MCOS
, int64_t LineDelta
,
332 uint64_t AddrDelta
) {
333 SmallString
<256> Tmp
;
334 raw_svector_ostream
OS(Tmp
);
335 MCDwarfLineAddr::Encode(LineDelta
, AddrDelta
, OS
);
336 MCOS
->EmitBytes(OS
.str(), /*AddrSpace=*/0);
339 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
340 void MCDwarfLineAddr::Encode(int64_t LineDelta
, uint64_t AddrDelta
,
342 uint64_t Temp
, Opcode
;
343 bool NeedCopy
= false;
345 // Scale the address delta by the minimum instruction length.
346 AddrDelta
= ScaleAddrDelta(AddrDelta
);
348 // A LineDelta of INT64_MAX is a signal that this is actually a
349 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
350 // end_sequence to emit the matrix entry.
351 if (LineDelta
== INT64_MAX
) {
352 if (AddrDelta
== MAX_SPECIAL_ADDR_DELTA
)
353 OS
<< char(dwarf::DW_LNS_const_add_pc
);
355 OS
<< char(dwarf::DW_LNS_advance_pc
);
357 raw_svector_ostream
OSE(Tmp
);
358 MCObjectWriter::EncodeULEB128(AddrDelta
, OSE
);
361 OS
<< char(dwarf::DW_LNS_extended_op
);
363 OS
<< char(dwarf::DW_LNE_end_sequence
);
367 // Bias the line delta by the base.
368 Temp
= LineDelta
- DWARF2_LINE_BASE
;
370 // If the line increment is out of range of a special opcode, we must encode
371 // it with DW_LNS_advance_line.
372 if (Temp
>= DWARF2_LINE_RANGE
) {
373 OS
<< char(dwarf::DW_LNS_advance_line
);
375 raw_svector_ostream
OSE(Tmp
);
376 MCObjectWriter::EncodeSLEB128(LineDelta
, OSE
);
380 Temp
= 0 - DWARF2_LINE_BASE
;
384 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
385 if (LineDelta
== 0 && AddrDelta
== 0) {
386 OS
<< char(dwarf::DW_LNS_copy
);
390 // Bias the opcode by the special opcode base.
391 Temp
+= DWARF2_LINE_OPCODE_BASE
;
393 // Avoid overflow when addr_delta is large.
394 if (AddrDelta
< 256 + MAX_SPECIAL_ADDR_DELTA
) {
395 // Try using a special opcode.
396 Opcode
= Temp
+ AddrDelta
* DWARF2_LINE_RANGE
;
402 // Try using DW_LNS_const_add_pc followed by special op.
403 Opcode
= Temp
+ (AddrDelta
- MAX_SPECIAL_ADDR_DELTA
) * DWARF2_LINE_RANGE
;
405 OS
<< char(dwarf::DW_LNS_const_add_pc
);
411 // Otherwise use DW_LNS_advance_pc.
412 OS
<< char(dwarf::DW_LNS_advance_pc
);
414 raw_svector_ostream
OSE(Tmp
);
415 MCObjectWriter::EncodeULEB128(AddrDelta
, OSE
);
419 OS
<< char(dwarf::DW_LNS_copy
);
424 void MCDwarfFile::print(raw_ostream
&OS
) const {
425 OS
<< '"' << getName() << '"';
428 void MCDwarfFile::dump() const {
432 static int getDataAlignmentFactor(MCStreamer
&streamer
) {
433 MCContext
&context
= streamer
.getContext();
434 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
435 int size
= asmInfo
.getPointerSize();
436 if (asmInfo
.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp
)
442 static void EmitSymbol(MCStreamer
&streamer
, const MCSymbol
&symbol
,
443 unsigned symbolEncoding
) {
444 MCContext
&context
= streamer
.getContext();
445 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
446 unsigned format
= symbolEncoding
& 0x0f;
447 unsigned application
= symbolEncoding
& 0x70;
451 assert(0 && "Unknown Encoding");
452 case dwarf::DW_EH_PE_absptr
:
453 case dwarf::DW_EH_PE_signed
:
454 size
= asmInfo
.getPointerSize();
456 case dwarf::DW_EH_PE_udata2
:
457 case dwarf::DW_EH_PE_sdata2
:
460 case dwarf::DW_EH_PE_udata4
:
461 case dwarf::DW_EH_PE_sdata4
:
464 case dwarf::DW_EH_PE_udata8
:
465 case dwarf::DW_EH_PE_sdata8
:
469 switch (application
) {
471 assert(0 && "Unknown Encoding");
474 streamer
.EmitSymbolValue(&symbol
, size
);
476 case dwarf::DW_EH_PE_pcrel
:
477 streamer
.EmitPCRelSymbolValue(&symbol
, size
);
482 static const MachineLocation
TranslateMachineLocation(
483 const TargetAsmInfo
&AsmInfo
,
484 const MachineLocation
&Loc
) {
485 unsigned Reg
= Loc
.getReg() == MachineLocation::VirtualFP
?
486 MachineLocation::VirtualFP
:
487 unsigned(AsmInfo
.getDwarfRegNum(Loc
.getReg(), true));
488 const MachineLocation
&NewLoc
= Loc
.isReg() ?
489 MachineLocation(Reg
) : MachineLocation(Reg
, Loc
.getOffset());
494 class FrameEmitterImpl
{
498 FrameEmitterImpl() : CFAOffset(0) {
501 const MCSymbol
&EmitCIE(MCStreamer
&streamer
,
502 const MCSymbol
*personality
,
503 unsigned personalityEncoding
,
504 const MCSymbol
*lsda
,
505 unsigned lsdaEncoding
);
506 MCSymbol
*EmitFDE(MCStreamer
&streamer
,
507 const MCSymbol
&cieStart
,
508 const MCDwarfFrameInfo
&frame
);
509 void EmitCFIInstructions(MCStreamer
&streamer
,
510 const std::vector
<MCCFIInstruction
> &Instrs
,
511 MCSymbol
*BaseLabel
);
512 void EmitCFIInstruction(MCStreamer
&Streamer
,
513 const MCCFIInstruction
&Instr
);
517 void FrameEmitterImpl::EmitCFIInstruction(MCStreamer
&Streamer
,
518 const MCCFIInstruction
&Instr
) {
519 int dataAlignmentFactor
= getDataAlignmentFactor(Streamer
);
521 switch (Instr
.getOperation()) {
522 case MCCFIInstruction::Move
:
523 case MCCFIInstruction::RelMove
: {
524 const MachineLocation
&Dst
= Instr
.getDestination();
525 const MachineLocation
&Src
= Instr
.getSource();
526 const bool IsRelative
= Instr
.getOperation() == MCCFIInstruction::RelMove
;
529 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
530 assert(!Src
.isReg() && "Machine move not supported yet.");
532 if (Src
.getReg() == MachineLocation::VirtualFP
) {
533 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa_offset
, 1);
535 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa
, 1);
536 Streamer
.EmitULEB128IntValue(Src
.getReg());
540 CFAOffset
+= Src
.getOffset();
542 CFAOffset
= -Src
.getOffset();
544 Streamer
.EmitULEB128IntValue(CFAOffset
, 1);
548 if (Src
.isReg() && Src
.getReg() == MachineLocation::VirtualFP
) {
549 assert(Dst
.isReg() && "Machine move not supported yet.");
550 Streamer
.EmitIntValue(dwarf::DW_CFA_def_cfa_register
, 1);
551 Streamer
.EmitULEB128IntValue(Dst
.getReg());
555 unsigned Reg
= Src
.getReg();
557 int Offset
= Dst
.getOffset();
560 Offset
= Offset
/ dataAlignmentFactor
;
563 Streamer
.EmitIntValue(dwarf::DW_CFA_offset_extended_sf
, 1);
564 Streamer
.EmitULEB128IntValue(Reg
);
565 Streamer
.EmitSLEB128IntValue(Offset
);
566 } else if (Reg
< 64) {
567 Streamer
.EmitIntValue(dwarf::DW_CFA_offset
+ Reg
, 1);
568 Streamer
.EmitULEB128IntValue(Offset
, 1);
570 Streamer
.EmitIntValue(dwarf::DW_CFA_offset_extended
, 1);
571 Streamer
.EmitULEB128IntValue(Reg
, 1);
572 Streamer
.EmitULEB128IntValue(Offset
, 1);
576 case MCCFIInstruction::Remember
:
577 Streamer
.EmitIntValue(dwarf::DW_CFA_remember_state
, 1);
579 case MCCFIInstruction::Restore
:
580 Streamer
.EmitIntValue(dwarf::DW_CFA_restore_state
, 1);
582 case MCCFIInstruction::SameValue
: {
583 unsigned Reg
= Instr
.getDestination().getReg();
584 Streamer
.EmitIntValue(dwarf::DW_CFA_same_value
, 1);
585 Streamer
.EmitULEB128IntValue(Reg
, 1);
589 llvm_unreachable("Unhandled case in switch");
592 /// EmitFrameMoves - Emit frame instructions to describe the layout of the
594 void FrameEmitterImpl::EmitCFIInstructions(MCStreamer
&streamer
,
595 const std::vector
<MCCFIInstruction
> &Instrs
,
596 MCSymbol
*BaseLabel
) {
597 for (unsigned i
= 0, N
= Instrs
.size(); i
< N
; ++i
) {
598 const MCCFIInstruction
&Instr
= Instrs
[i
];
599 MCSymbol
*Label
= Instr
.getLabel();
600 // Throw out move if the label is invalid.
601 if (Label
&& !Label
->isDefined()) continue; // Not emitted, in dead code.
603 // Advance row if new location.
604 if (BaseLabel
&& Label
) {
605 MCSymbol
*ThisSym
= Label
;
606 if (ThisSym
!= BaseLabel
) {
607 streamer
.EmitDwarfAdvanceFrameAddr(BaseLabel
, ThisSym
);
612 EmitCFIInstruction(streamer
, Instr
);
616 const MCSymbol
&FrameEmitterImpl::EmitCIE(MCStreamer
&streamer
,
617 const MCSymbol
*personality
,
618 unsigned personalityEncoding
,
619 const MCSymbol
*lsda
,
620 unsigned lsdaEncoding
) {
621 MCContext
&context
= streamer
.getContext();
622 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
623 const MCSection
§ion
= *asmInfo
.getEHFrameSection();
624 streamer
.SwitchSection(§ion
);
625 MCSymbol
*sectionStart
= streamer
.getContext().CreateTempSymbol();
626 MCSymbol
*sectionEnd
= streamer
.getContext().CreateTempSymbol();
629 const MCExpr
*Length
= MakeStartMinusEndExpr(streamer
, *sectionStart
,
631 streamer
.EmitLabel(sectionStart
);
632 streamer
.EmitValue(Length
, 4);
635 streamer
.EmitIntValue(0, 4);
638 streamer
.EmitIntValue(dwarf::DW_CIE_VERSION
, 1);
640 // Augmentation String
641 SmallString
<8> Augmentation
;
648 streamer
.EmitBytes(Augmentation
.str(), 0);
649 streamer
.EmitIntValue(0, 1);
651 // Code Alignment Factor
652 streamer
.EmitULEB128IntValue(1);
654 // Data Alignment Factor
655 streamer
.EmitSLEB128IntValue(getDataAlignmentFactor(streamer
));
657 // Return Address Register
658 streamer
.EmitULEB128IntValue(asmInfo
.getDwarfRARegNum(true));
660 // Augmentation Data Length (optional)
661 MCSymbol
*augmentationStart
= streamer
.getContext().CreateTempSymbol();
662 MCSymbol
*augmentationEnd
= streamer
.getContext().CreateTempSymbol();
663 const MCExpr
*augmentationLength
= MakeStartMinusEndExpr(streamer
,
665 *augmentationEnd
, 0);
666 streamer
.EmitULEB128Value(augmentationLength
);
668 // Augmentation Data (optional)
669 streamer
.EmitLabel(augmentationStart
);
671 // Personality Encoding
672 streamer
.EmitIntValue(personalityEncoding
, 1);
674 EmitSymbol(streamer
, *personality
, personalityEncoding
);
678 streamer
.EmitIntValue(lsdaEncoding
, 1);
680 // Encoding of the FDE pointers
681 streamer
.EmitIntValue(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
, 1);
682 streamer
.EmitLabel(augmentationEnd
);
684 // Initial Instructions
686 const std::vector
<MachineMove
> Moves
= asmInfo
.getInitialFrameState();
687 std::vector
<MCCFIInstruction
> Instructions
;
689 for (int i
= 0, n
= Moves
.size(); i
!= n
; ++i
) {
690 MCSymbol
*Label
= Moves
[i
].getLabel();
691 const MachineLocation
&Dst
=
692 TranslateMachineLocation(asmInfo
, Moves
[i
].getDestination());
693 const MachineLocation
&Src
=
694 TranslateMachineLocation(asmInfo
, Moves
[i
].getSource());
695 MCCFIInstruction
Inst(Label
, Dst
, Src
);
696 Instructions
.push_back(Inst
);
699 EmitCFIInstructions(streamer
, Instructions
, NULL
);
702 streamer
.EmitValueToAlignment(4);
704 streamer
.EmitLabel(sectionEnd
);
705 return *sectionStart
;
708 MCSymbol
*FrameEmitterImpl::EmitFDE(MCStreamer
&streamer
,
709 const MCSymbol
&cieStart
,
710 const MCDwarfFrameInfo
&frame
) {
711 MCContext
&context
= streamer
.getContext();
712 MCSymbol
*fdeStart
= context
.CreateTempSymbol();
713 MCSymbol
*fdeEnd
= context
.CreateTempSymbol();
716 const MCExpr
*Length
= MakeStartMinusEndExpr(streamer
, *fdeStart
, *fdeEnd
, 0);
717 streamer
.EmitValue(Length
, 4);
719 streamer
.EmitLabel(fdeStart
);
721 const MCExpr
*offset
= MakeStartMinusEndExpr(streamer
, cieStart
, *fdeStart
,
723 streamer
.EmitValue(offset
, 4);
726 streamer
.EmitPCRelSymbolValue(frame
.Begin
, 4);
729 const MCExpr
*Range
= MakeStartMinusEndExpr(streamer
, *frame
.Begin
,
731 streamer
.EmitValue(Range
, 4);
733 // Augmentation Data Length
734 MCSymbol
*augmentationStart
= streamer
.getContext().CreateTempSymbol();
735 MCSymbol
*augmentationEnd
= streamer
.getContext().CreateTempSymbol();
736 const MCExpr
*augmentationLength
= MakeStartMinusEndExpr(streamer
,
738 *augmentationEnd
, 0);
739 streamer
.EmitULEB128Value(augmentationLength
);
742 streamer
.EmitLabel(augmentationStart
);
744 EmitSymbol(streamer
, *frame
.Lsda
, frame
.LsdaEncoding
);
745 streamer
.EmitLabel(augmentationEnd
);
746 // Call Frame Instructions
748 EmitCFIInstructions(streamer
, frame
.Instructions
, frame
.Begin
);
751 streamer
.EmitValueToAlignment(4);
758 static const CIEKey
getEmptyKey() { return CIEKey(0, 0, -1); }
759 static const CIEKey
getTombstoneKey() { return CIEKey(0, -1, 0); }
761 CIEKey(const MCSymbol
* Personality_
, unsigned PersonalityEncoding_
,
762 unsigned LsdaEncoding_
) : Personality(Personality_
),
763 PersonalityEncoding(PersonalityEncoding_
),
764 LsdaEncoding(LsdaEncoding_
) {
766 const MCSymbol
* Personality
;
767 unsigned PersonalityEncoding
;
768 unsigned LsdaEncoding
;
774 struct DenseMapInfo
<CIEKey
> {
775 static CIEKey
getEmptyKey() {
776 return CIEKey::getEmptyKey();
778 static CIEKey
getTombstoneKey() {
779 return CIEKey::getTombstoneKey();
781 static unsigned getHashValue(const CIEKey
&Key
) {
783 ID
.AddPointer(Key
.Personality
);
784 ID
.AddInteger(Key
.PersonalityEncoding
);
785 ID
.AddInteger(Key
.LsdaEncoding
);
786 return ID
.ComputeHash();
788 static bool isEqual(const CIEKey
&LHS
,
790 return LHS
.Personality
== RHS
.Personality
&&
791 LHS
.PersonalityEncoding
== RHS
.PersonalityEncoding
&&
792 LHS
.LsdaEncoding
== RHS
.LsdaEncoding
;
797 void MCDwarfFrameEmitter::Emit(MCStreamer
&streamer
) {
798 const MCContext
&context
= streamer
.getContext();
799 const TargetAsmInfo
&asmInfo
= context
.getTargetAsmInfo();
800 MCSymbol
*fdeEnd
= NULL
;
801 DenseMap
<CIEKey
, const MCSymbol
*> CIEStarts
;
802 FrameEmitterImpl Emitter
;
804 for (unsigned i
= 0, n
= streamer
.getNumFrameInfos(); i
< n
; ++i
) {
805 const MCDwarfFrameInfo
&frame
= streamer
.getFrameInfo(i
);
806 CIEKey
key(frame
.Personality
, frame
.PersonalityEncoding
,
808 const MCSymbol
*&cieStart
= CIEStarts
[key
];
810 cieStart
= &Emitter
.EmitCIE(streamer
, frame
.Personality
,
811 frame
.PersonalityEncoding
, frame
.Lsda
,
813 fdeEnd
= Emitter
.EmitFDE(streamer
, *cieStart
, frame
);
815 streamer
.EmitLabel(fdeEnd
);
818 streamer
.EmitValueToAlignment(asmInfo
.getPointerSize());
820 streamer
.EmitLabel(fdeEnd
);
823 void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer
&Streamer
,
824 uint64_t AddrDelta
) {
825 SmallString
<256> Tmp
;
826 raw_svector_ostream
OS(Tmp
);
827 MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta
, OS
);
828 Streamer
.EmitBytes(OS
.str(), /*AddrSpace=*/0);
831 void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta
,
833 // FIXME: Assumes the code alignment factor is 1.
834 if (AddrDelta
== 0) {
835 } else if (isUIntN(6, AddrDelta
)) {
836 uint8_t Opcode
= dwarf::DW_CFA_advance_loc
| AddrDelta
;
838 } else if (isUInt
<8>(AddrDelta
)) {
839 OS
<< uint8_t(dwarf::DW_CFA_advance_loc1
);
840 OS
<< uint8_t(AddrDelta
);
841 } else if (isUInt
<16>(AddrDelta
)) {
842 // FIXME: check what is the correct behavior on a big endian machine.
843 OS
<< uint8_t(dwarf::DW_CFA_advance_loc2
);
844 OS
<< uint8_t( AddrDelta
& 0xff);
845 OS
<< uint8_t((AddrDelta
>> 8) & 0xff);
847 // FIXME: check what is the correct behavior on a big endian machine.
848 assert(isUInt
<32>(AddrDelta
));
849 OS
<< uint8_t(dwarf::DW_CFA_advance_loc4
);
850 OS
<< uint8_t( AddrDelta
& 0xff);
851 OS
<< uint8_t((AddrDelta
>> 8) & 0xff);
852 OS
<< uint8_t((AddrDelta
>> 16) & 0xff);
853 OS
<< uint8_t((AddrDelta
>> 24) & 0xff);