MCDwarf.cpp revision add294455944cd3f545a04692525c3dc4bfc5894
1//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
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"
25using namespace llvm;
26
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)
30
31// The maximum address skip amount that can be encoded with a special op.
32#define MAX_SPECIAL_ADDR_DELTA		SPECIAL_ADDR(255)
33
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
38
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
42
43// Range of line offsets in a special line info. opcode.
44# define DWARF2_LINE_RANGE		14
45
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
49
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.
52static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta)
53{
54  if (DWARF2_LINE_MIN_INSN_LENGTH == 1)
55    return AddrDelta;
56  if (AddrDelta % DWARF2_LINE_MIN_INSN_LENGTH != 0) {
57    // TODO: report this error, but really only once.
58    ;
59  }
60  return AddrDelta / DWARF2_LINE_MIN_INSN_LENGTH;
61}
62
63//
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.
67//
68void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
69  if (!MCOS->getContext().getDwarfLocSeen())
70    return;
71
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);
76
77  // Get the current .loc info saved in the context.
78  const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
79
80  // Create a (local) line entry with the symbol and the current .loc info.
81  MCLineEntry LineEntry(LineSym, DwarfLoc);
82
83  // clear DwarfLocSeen saying the current .loc info is now used.
84  MCOS->getContext().ClearDwarfLocSeen();
85
86  // Get the MCLineSection for this section, if one does not exist for this
87  // section create it.
88  const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
89    MCOS->getContext().getMCLineSections();
90  MCLineSection *LineSection = MCLineSections.lookup(Section);
91  if (!LineSection) {
92    // Create a new MCLineSection.  This will be deleted after the dwarf line
93    // table is created using it by iterating through the MCLineSections
94    // DenseMap.
95    LineSection = new MCLineSection;
96    // Save a pointer to the new LineSection into the MCLineSections DenseMap.
97    MCOS->getContext().addMCLineSection(Section, LineSection);
98  }
99
100  // Add the line entry to this section's entries.
101  LineSection->addLineEntry(LineEntry);
102}
103
104//
105// This helper routine returns an expression of End - Start + IntVal .
106//
107static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
108                                                  const MCSymbol &Start,
109                                                  const MCSymbol &End,
110                                                  int IntVal) {
111  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
112  const MCExpr *Res =
113    MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext());
114  const MCExpr *RHS =
115    MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext());
116  const MCExpr *Res1 =
117    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
118  const MCExpr *Res2 =
119    MCConstantExpr::Create(IntVal, MCOS.getContext());
120  const MCExpr *Res3 =
121    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
122  return Res3;
123}
124
125//
126// This emits the Dwarf line table for the specified section from the entries
127// in the LineSection.
128//
129static inline void EmitDwarfLineTable(MCStreamer *MCOS,
130                                      const MCSection *Section,
131                                      const MCLineSection *LineSection) {
132  unsigned FileNum = 1;
133  unsigned LastLine = 1;
134  unsigned Column = 0;
135  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
136  unsigned Isa = 0;
137  MCSymbol *LastLabel = NULL;
138
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) {
143
144    if (FileNum != it->getFileNum()) {
145      FileNum = it->getFileNum();
146      MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
147      MCOS->EmitULEB128IntValue(FileNum);
148    }
149    if (Column != it->getColumn()) {
150      Column = it->getColumn();
151      MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
152      MCOS->EmitULEB128IntValue(Column);
153    }
154    if (Isa != it->getIsa()) {
155      Isa = it->getIsa();
156      MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
157      MCOS->EmitULEB128IntValue(Isa);
158    }
159    if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
160      Flags = it->getFlags();
161      MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
162    }
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);
169
170    int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine;
171    MCSymbol *Label = it->getLabel();
172
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);
177
178    LastLine = it->getLine();
179    LastLabel = Label;
180  }
181
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.
187
188  // Switch to the section to be able to create a symbol at its end.
189  MCOS->SwitchSection(Section);
190
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);
196
197  // Switch back the the dwarf line section.
198  MCOS->SwitchSection(context.getTargetAsmInfo().getDwarfLineSection());
199
200  MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd);
201}
202
203//
204// This emits the Dwarf file and the line tables.
205//
206void 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());
210
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);
215
216  // Create a symbol for the end of the section (to be set when we get there).
217  MCSymbol *LineEndSym = context.CreateTempSymbol();
218
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),
222                     4);
223
224  // Next 2 bytes is the Version, which is Dwarf 2.
225  MCOS->EmitIntValue(2, 2);
226
227  // Create a symbol for the end of the prologue (to be set when we get there).
228  MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end
229
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,
235                                        (4 + 2 + 4)),
236                  4, 0);
237
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);
244
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
258
259  // Put out the directory and file tables.
260
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
267  }
268  MCOS->EmitIntValue(0, 1); // Terminate the directory list
269
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
276    // the Directory num
277    MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
278    MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
279    MCOS->EmitIntValue(0, 1); // filesize (always 0)
280  }
281  MCOS->EmitIntValue(0, 1); // Terminate the file list
282
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);
286
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;
294       ++it) {
295    const MCSection *Sec = *it;
296    const MCLineSection *Line = MCLineSections.lookup(Sec);
297    EmitDwarfLineTable(MCOS, Sec, Line);
298
299    // Now delete the MCLineSections that were created in MCLineEntry::Make()
300    // and used to emit the line table.
301    delete Line;
302  }
303
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
307    // it requires:
308    // total_length >= prologue_length + 10
309    // We are 4 bytes short, since we have total_length = 51 and
310    // prologue_length = 45
311
312    // The regular end_sequence should be sufficient.
313    MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
314  }
315
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);
319}
320
321/// Utility function to write the encoding to an object writer.
322void 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());
328}
329
330/// Utility function to emit the encoding to a streamer.
331void 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);
337}
338
339/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
340void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
341                             raw_ostream &OS) {
342  uint64_t Temp, Opcode;
343  bool NeedCopy = false;
344
345  // Scale the address delta by the minimum instruction length.
346  AddrDelta = ScaleAddrDelta(AddrDelta);
347
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);
354    else {
355      OS << char(dwarf::DW_LNS_advance_pc);
356      SmallString<32> Tmp;
357      raw_svector_ostream OSE(Tmp);
358      MCObjectWriter::EncodeULEB128(AddrDelta, OSE);
359      OS << OSE.str();
360    }
361    OS << char(dwarf::DW_LNS_extended_op);
362    OS << char(1);
363    OS << char(dwarf::DW_LNE_end_sequence);
364    return;
365  }
366
367  // Bias the line delta by the base.
368  Temp = LineDelta - DWARF2_LINE_BASE;
369
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);
374    SmallString<32> Tmp;
375    raw_svector_ostream OSE(Tmp);
376    MCObjectWriter::EncodeSLEB128(LineDelta, OSE);
377    OS << OSE.str();
378
379    LineDelta = 0;
380    Temp = 0 - DWARF2_LINE_BASE;
381    NeedCopy = true;
382  }
383
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);
387    return;
388  }
389
390  // Bias the opcode by the special opcode base.
391  Temp += DWARF2_LINE_OPCODE_BASE;
392
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;
397    if (Opcode <= 255) {
398      OS << char(Opcode);
399      return;
400    }
401
402    // Try using DW_LNS_const_add_pc followed by special op.
403    Opcode = Temp + (AddrDelta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
404    if (Opcode <= 255) {
405      OS << char(dwarf::DW_LNS_const_add_pc);
406      OS << char(Opcode);
407      return;
408    }
409  }
410
411  // Otherwise use DW_LNS_advance_pc.
412  OS << char(dwarf::DW_LNS_advance_pc);
413  SmallString<32> Tmp;
414  raw_svector_ostream OSE(Tmp);
415  MCObjectWriter::EncodeULEB128(AddrDelta, OSE);
416  OS << OSE.str();
417
418  if (NeedCopy)
419    OS << char(dwarf::DW_LNS_copy);
420  else
421    OS << char(Temp);
422}
423
424void MCDwarfFile::print(raw_ostream &OS) const {
425  OS << '"' << getName() << '"';
426}
427
428void MCDwarfFile::dump() const {
429  print(dbgs());
430}
431
432static 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)
437    return size;
438 else
439   return -size;
440}
441
442static unsigned getSizeForEncoding(MCStreamer &streamer,
443                                   unsigned symbolEncoding) {
444  MCContext &context = streamer.getContext();
445  const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
446  unsigned format = symbolEncoding & 0x0f;
447  switch (format) {
448  default:
449    assert(0 && "Unknown Encoding");
450  case dwarf::DW_EH_PE_absptr:
451  case dwarf::DW_EH_PE_signed:
452    return asmInfo.getPointerSize();
453  case dwarf::DW_EH_PE_udata2:
454  case dwarf::DW_EH_PE_sdata2:
455    return 2;
456  case dwarf::DW_EH_PE_udata4:
457  case dwarf::DW_EH_PE_sdata4:
458    return 4;
459  case dwarf::DW_EH_PE_udata8:
460  case dwarf::DW_EH_PE_sdata8:
461    return 8;
462  }
463}
464
465static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
466                       unsigned symbolEncoding) {
467  unsigned size = getSizeForEncoding(streamer, symbolEncoding);
468  unsigned application = symbolEncoding & 0x70;
469  switch (application) {
470  default:
471    assert(0 && "Unknown Encoding");
472    break;
473  case 0:
474    streamer.EmitSymbolValue(&symbol, size);
475    break;
476  case dwarf::DW_EH_PE_pcrel:
477    streamer.EmitPCRelSymbolValue(&symbol, size);
478    break;
479  }
480}
481
482static 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());
490  return NewLoc;
491}
492
493namespace {
494  class FrameEmitterImpl {
495    int CFAOffset;
496
497  public:
498    FrameEmitterImpl() : CFAOffset(0) {
499    }
500
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);
514  };
515}
516
517void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
518                                          const MCCFIInstruction &Instr) {
519  int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
520
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;
527
528    // If advancing cfa.
529    if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
530      assert(!Src.isReg() && "Machine move not supported yet.");
531
532      if (Src.getReg() == MachineLocation::VirtualFP) {
533        Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
534      } else {
535        Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
536        Streamer.EmitULEB128IntValue(Src.getReg());
537      }
538
539      if (IsRelative)
540        CFAOffset += Src.getOffset();
541      else
542        CFAOffset = -Src.getOffset();
543
544      Streamer.EmitULEB128IntValue(CFAOffset);
545      return;
546    }
547
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());
552      return;
553    }
554
555    unsigned Reg = Src.getReg();
556
557    int Offset = Dst.getOffset();
558    if (IsRelative)
559      Offset -= CFAOffset;
560    Offset = Offset / dataAlignmentFactor;
561
562    if (Offset < 0) {
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);
569    } else {
570      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
571      Streamer.EmitULEB128IntValue(Reg);
572      Streamer.EmitULEB128IntValue(Offset);
573    }
574    return;
575  }
576  case MCCFIInstruction::Remember:
577    Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
578    return;
579  case MCCFIInstruction::Restore:
580    Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
581    return;
582  case MCCFIInstruction::SameValue: {
583    unsigned Reg = Instr.getDestination().getReg();
584    Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
585    Streamer.EmitULEB128IntValue(Reg);
586    return;
587  }
588  }
589  llvm_unreachable("Unhandled case in switch");
590}
591
592/// EmitFrameMoves - Emit frame instructions to describe the layout of the
593/// frame.
594void 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.
602
603    // Advance row if new location.
604    if (BaseLabel && Label) {
605      MCSymbol *ThisSym = Label;
606      if (ThisSym != BaseLabel) {
607        streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
608        BaseLabel = ThisSym;
609      }
610    }
611
612    EmitCFIInstruction(streamer, Instr);
613  }
614}
615
616const 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 &section = *asmInfo.getEHFrameSection();
624  streamer.SwitchSection(&section);
625  MCSymbol *sectionStart = streamer.getContext().CreateTempSymbol();
626  MCSymbol *sectionEnd = streamer.getContext().CreateTempSymbol();
627
628  // Length
629  const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
630                                               *sectionEnd, 4);
631  streamer.EmitLabel(sectionStart);
632  streamer.EmitValue(Length, 4);
633
634  // CIE ID
635  streamer.EmitIntValue(0, 4);
636
637  // Version
638  streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
639
640  // Augmentation String
641  SmallString<8> Augmentation;
642  Augmentation += "z";
643  if (personality)
644    Augmentation += "P";
645  if (lsda)
646    Augmentation += "L";
647  Augmentation += "R";
648  streamer.EmitBytes(Augmentation.str(), 0);
649  streamer.EmitIntValue(0, 1);
650
651  // Code Alignment Factor
652  streamer.EmitULEB128IntValue(1);
653
654  // Data Alignment Factor
655  streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer));
656
657  // Return Address Register
658  streamer.EmitULEB128IntValue(asmInfo.getDwarfRARegNum(true));
659
660  // Augmentation Data Length (optional)
661  MCSymbol *augmentationStart = streamer.getContext().CreateTempSymbol();
662  MCSymbol *augmentationEnd = streamer.getContext().CreateTempSymbol();
663  const MCExpr *augmentationLength = MakeStartMinusEndExpr(streamer,
664                                                           *augmentationStart,
665                                                           *augmentationEnd, 0);
666  streamer.EmitULEB128Value(augmentationLength);
667
668  // Augmentation Data (optional)
669  streamer.EmitLabel(augmentationStart);
670  if (personality) {
671    // Personality Encoding
672    streamer.EmitIntValue(personalityEncoding, 1);
673    // Personality
674    EmitSymbol(streamer, *personality, personalityEncoding);
675  }
676  if (lsda) {
677    // LSDA Encoding
678    streamer.EmitIntValue(lsdaEncoding, 1);
679  }
680  // Encoding of the FDE pointers
681  streamer.EmitIntValue(asmInfo.getFDEEncoding(), 1);
682  streamer.EmitLabel(augmentationEnd);
683
684  // Initial Instructions
685
686  const std::vector<MachineMove> Moves = asmInfo.getInitialFrameState();
687  std::vector<MCCFIInstruction> Instructions;
688
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);
697  }
698
699  EmitCFIInstructions(streamer, Instructions, NULL);
700
701  // Padding
702  streamer.EmitValueToAlignment(4);
703
704  streamer.EmitLabel(sectionEnd);
705  return *sectionStart;
706}
707
708MCSymbol *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();
714  const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
715
716  // Length
717  const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
718  streamer.EmitValue(Length, 4);
719
720  streamer.EmitLabel(fdeStart);
721  // CIE Pointer
722  const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
723                                               0);
724  streamer.EmitValue(offset, 4);
725  unsigned fdeEncoding = asmInfo.getFDEEncoding();
726  unsigned size = getSizeForEncoding(streamer, fdeEncoding);
727
728  // PC Begin
729  streamer.EmitPCRelSymbolValue(frame.Begin, size);
730
731  // PC Range
732  const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
733                                              *frame.End, 0);
734  streamer.EmitValue(Range, size);
735
736  // Augmentation Data Length
737  MCSymbol *augmentationStart = streamer.getContext().CreateTempSymbol();
738  MCSymbol *augmentationEnd = streamer.getContext().CreateTempSymbol();
739  const MCExpr *augmentationLength = MakeStartMinusEndExpr(streamer,
740                                                           *augmentationStart,
741                                                           *augmentationEnd, 0);
742  streamer.EmitULEB128Value(augmentationLength);
743
744  // Augmentation Data
745  streamer.EmitLabel(augmentationStart);
746  if (frame.Lsda)
747    EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding);
748  streamer.EmitLabel(augmentationEnd);
749  // Call Frame Instructions
750
751  EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
752
753  // Padding
754  streamer.EmitValueToAlignment(4);
755
756  return fdeEnd;
757}
758
759namespace {
760  struct CIEKey {
761    static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1); }
762    static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0); }
763
764    CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
765           unsigned LsdaEncoding_) : Personality(Personality_),
766                                     PersonalityEncoding(PersonalityEncoding_),
767                                     LsdaEncoding(LsdaEncoding_) {
768    }
769    const MCSymbol* Personality;
770    unsigned PersonalityEncoding;
771    unsigned LsdaEncoding;
772  };
773}
774
775namespace llvm {
776  template <>
777  struct DenseMapInfo<CIEKey> {
778    static CIEKey getEmptyKey() {
779      return CIEKey::getEmptyKey();
780    }
781    static CIEKey getTombstoneKey() {
782      return CIEKey::getTombstoneKey();
783    }
784    static unsigned getHashValue(const CIEKey &Key) {
785      FoldingSetNodeID ID;
786      ID.AddPointer(Key.Personality);
787      ID.AddInteger(Key.PersonalityEncoding);
788      ID.AddInteger(Key.LsdaEncoding);
789      return ID.ComputeHash();
790    }
791    static bool isEqual(const CIEKey &LHS,
792                        const CIEKey &RHS) {
793      return LHS.Personality == RHS.Personality &&
794        LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
795        LHS.LsdaEncoding == RHS.LsdaEncoding;
796    }
797  };
798}
799
800void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) {
801  const MCContext &context = streamer.getContext();
802  const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
803  MCSymbol *fdeEnd = NULL;
804  DenseMap<CIEKey, const MCSymbol*> CIEStarts;
805  FrameEmitterImpl Emitter;
806
807  for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
808    const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
809    CIEKey key(frame.Personality, frame.PersonalityEncoding,
810               frame.LsdaEncoding);
811    const MCSymbol *&cieStart = CIEStarts[key];
812    if (!cieStart)
813      cieStart = &Emitter.EmitCIE(streamer, frame.Personality,
814                                  frame.PersonalityEncoding, frame.Lsda,
815                                  frame.LsdaEncoding);
816    fdeEnd = Emitter.EmitFDE(streamer, *cieStart, frame);
817    if (i != n - 1)
818      streamer.EmitLabel(fdeEnd);
819  }
820
821  streamer.EmitValueToAlignment(asmInfo.getPointerSize());
822  if (fdeEnd)
823    streamer.EmitLabel(fdeEnd);
824}
825
826void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
827                                         uint64_t AddrDelta) {
828  SmallString<256> Tmp;
829  raw_svector_ostream OS(Tmp);
830  MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS);
831  Streamer.EmitBytes(OS.str(), /*AddrSpace=*/0);
832}
833
834void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta,
835                                           raw_ostream &OS) {
836  // FIXME: Assumes the code alignment factor is 1.
837  if (AddrDelta == 0) {
838  } else if (isUIntN(6, AddrDelta)) {
839    uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
840    OS << Opcode;
841  } else if (isUInt<8>(AddrDelta)) {
842    OS << uint8_t(dwarf::DW_CFA_advance_loc1);
843    OS << uint8_t(AddrDelta);
844  } else if (isUInt<16>(AddrDelta)) {
845    // FIXME: check what is the correct behavior on a big endian machine.
846    OS << uint8_t(dwarf::DW_CFA_advance_loc2);
847    OS << uint8_t( AddrDelta       & 0xff);
848    OS << uint8_t((AddrDelta >> 8) & 0xff);
849  } else {
850    // FIXME: check what is the correct behavior on a big endian machine.
851    assert(isUInt<32>(AddrDelta));
852    OS << uint8_t(dwarf::DW_CFA_advance_loc4);
853    OS << uint8_t( AddrDelta        & 0xff);
854    OS << uint8_t((AddrDelta >> 8)  & 0xff);
855    OS << uint8_t((AddrDelta >> 16) & 0xff);
856    OS << uint8_t((AddrDelta >> 24) & 0xff);
857
858  }
859}
860