//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

// Given a special op, return the address skip amount (in units of
// DWARF2_LINE_MIN_INSN_LENGTH.
#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)

// The maximum address skip amount that can be encoded with a special op.
#define MAX_SPECIAL_ADDR_DELTA         SPECIAL_ADDR(255)

// First special line opcode - leave room for the standard opcodes.
// Note: If you want to change this, you'll have to update the
// "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
#define DWARF2_LINE_OPCODE_BASE         13

// Minimum line offset in a special line info. opcode.  This value
// was chosen to give a reasonable range of values.
#define DWARF2_LINE_BASE                -5

// Range of line offsets in a special line info. opcode.
#define DWARF2_LINE_RANGE               14

static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
  unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
  if (MinInsnLength == 1)
    return AddrDelta;
  if (AddrDelta % MinInsnLength != 0) {
    // TODO: report this error, but really only once.
    ;
  }
  return AddrDelta / MinInsnLength;
}

//
// This is called when an instruction is assembled into the specified section
// and if there is information from the last .loc directive that has yet to have
// a line entry made for it is made.
//
void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
  if (!MCOS->getContext().getDwarfLocSeen())
    return;

  // Create a symbol at in the current section for use in the line entry.
  MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol();
  // Set the value of the symbol to use for the MCLineEntry.
  MCOS->EmitLabel(LineSym);

  // Get the current .loc info saved in the context.
  const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();

  // Create a (local) line entry with the symbol and the current .loc info.
  MCLineEntry LineEntry(LineSym, DwarfLoc);

  // clear DwarfLocSeen saying the current .loc info is now used.
  MCOS->getContext().ClearDwarfLocSeen();

  // Get the MCLineSection for this section, if one does not exist for this
  // section create it.
  const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
    MCOS->getContext().getMCLineSections();
  MCLineSection *LineSection = MCLineSections.lookup(Section);
  if (!LineSection) {
    // Create a new MCLineSection.  This will be deleted after the dwarf line
    // table is created using it by iterating through the MCLineSections
    // DenseMap.
    LineSection = new MCLineSection;
    // Save a pointer to the new LineSection into the MCLineSections DenseMap.
    MCOS->getContext().addMCLineSection(Section, LineSection);
  }

  // Add the line entry to this section's entries.
  LineSection->addLineEntry(LineEntry,
                            MCOS->getContext().getDwarfCompileUnitID());
}

//
// This helper routine returns an expression of End - Start + IntVal .
//
static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
                                                  const MCSymbol &Start,
                                                  const MCSymbol &End,
                                                  int IntVal) {
  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
  const MCExpr *Res =
    MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext());
  const MCExpr *RHS =
    MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext());
  const MCExpr *Res1 =
    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
  const MCExpr *Res2 =
    MCConstantExpr::Create(IntVal, MCOS.getContext());
  const MCExpr *Res3 =
    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
  return Res3;
}

//
// This emits the Dwarf line table for the specified section from the entries
// in the LineSection.
//
static inline void EmitDwarfLineTable(MCStreamer *MCOS,
                                      const MCSection *Section,
                                      const MCLineSection *LineSection,
                                      unsigned CUID) {
  // This LineSection does not contain any LineEntry for the given Compile Unit.
  if (!LineSection->containEntriesForID(CUID))
    return;

  unsigned FileNum = 1;
  unsigned LastLine = 1;
  unsigned Column = 0;
  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
  unsigned Isa = 0;
  MCSymbol *LastLabel = NULL;

  // Loop through each MCLineEntry and encode the dwarf line number table.
  for (MCLineSection::const_iterator
         it = LineSection->getMCLineEntries(CUID).begin(),
         ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) {

    if (FileNum != it->getFileNum()) {
      FileNum = it->getFileNum();
      MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
      MCOS->EmitULEB128IntValue(FileNum);
    }
    if (Column != it->getColumn()) {
      Column = it->getColumn();
      MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
      MCOS->EmitULEB128IntValue(Column);
    }
    if (Isa != it->getIsa()) {
      Isa = it->getIsa();
      MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
      MCOS->EmitULEB128IntValue(Isa);
    }
    if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
      Flags = it->getFlags();
      MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
    }
    if (it->getFlags() & DWARF2_FLAG_BASIC_BLOCK)
      MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
    if (it->getFlags() & DWARF2_FLAG_PROLOGUE_END)
      MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
    if (it->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
      MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);

    int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine;
    MCSymbol *Label = it->getLabel();

    // At this point we want to emit/create the sequence to encode the delta in
    // line numbers and the increment of the address from the previous Label
    // and the current Label.
    const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
    MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
                                   asmInfo->getPointerSize());

    LastLine = it->getLine();
    LastLabel = Label;
  }

  // Emit a DW_LNE_end_sequence for the end of the section.
  // Using the pointer Section create a temporary label at the end of the
  // section and use that and the LastLabel to compute the address delta
  // and use INT64_MAX as the line delta which is the signal that this is
  // actually a DW_LNE_end_sequence.

  // Switch to the section to be able to create a symbol at its end.
  // TODO: keep track of the last subsection so that this symbol appears in the
  // correct place.
  MCOS->SwitchSection(Section);

  MCContext &context = MCOS->getContext();
  // Create a symbol at the end of the section.
  MCSymbol *SectionEnd = context.CreateTempSymbol();
  // Set the value of the symbol, as we are at the end of the section.
  MCOS->EmitLabel(SectionEnd);

  // Switch back the dwarf line section.
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());

  const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
  MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
                                 asmInfo->getPointerSize());
}

//
// This emits the Dwarf file and the line tables.
//
const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
  MCContext &context = MCOS->getContext();
  // Switch to the section where the table will be emitted into.
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());

  const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
    MCOS->getContext().getMCLineTableSymbols();
  // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
  // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
  // Handle Compile Unit 0, the line table start symbol is the section symbol.
  const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
  // Handle the rest of the Compile Units.
  for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
    EmitCU(MCOS, Is);

  // Now delete the MCLineSections that were created in MCLineEntry::Make()
  // and used to emit the line table.
  const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
    MCOS->getContext().getMCLineSections();
  for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it =
       MCLineSections.begin(), ie = MCLineSections.end(); it != ie;
       ++it)
    delete it->second;

  return LineStartSym;
}

const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
  MCContext &context = MCOS->getContext();

  // Create a symbol at the beginning of the line table.
  MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
  if (!LineStartSym)
    LineStartSym = context.CreateTempSymbol();
  // Set the value of the symbol, as we are at the start of the line table.
  MCOS->EmitLabel(LineStartSym);

  // Create a symbol for the end of the section (to be set when we get there).
  MCSymbol *LineEndSym = context.CreateTempSymbol();

  // The first 4 bytes is the total length of the information for this
  // compilation unit (not including these 4 bytes for the length).
  MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym,4),
                     4);

  // Next 2 bytes is the Version, which is Dwarf 2.
  MCOS->EmitIntValue(2, 2);

  // Create a symbol for the end of the prologue (to be set when we get there).
  MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end

  // Length of the prologue, is the next 4 bytes.  Which is the start of the
  // section to the end of the prologue.  Not including the 4 bytes for the
  // total length, the 2 bytes for the version, and these 4 bytes for the
  // length of the prologue.
  MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
                                           (4 + 2 + 4)), 4);

  // Parameters of the state machine, are next.
  MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1);
  MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
  MCOS->EmitIntValue(DWARF2_LINE_BASE, 1);
  MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1);
  MCOS->EmitIntValue(DWARF2_LINE_OPCODE_BASE, 1);

  // Standard opcode lengths
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_copy
  MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_pc
  MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_line
  MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_file
  MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_column
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_negate_stmt
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_basic_block
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_const_add_pc
  MCOS->EmitIntValue(1, 1); // length of DW_LNS_fixed_advance_pc
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_prologue_end
  MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_epilogue_begin
  MCOS->EmitIntValue(1, 1); // DW_LNS_set_isa

  // Put out the directory and file tables.

  // First the directory table.
  const SmallVectorImpl<StringRef> &MCDwarfDirs =
    context.getMCDwarfDirs(CUID);
  for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
    MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
    MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
  }
  MCOS->EmitIntValue(0, 1); // Terminate the directory list

  // Second the file table.
  const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
    MCOS->getContext().getMCDwarfFiles(CUID);
  for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
    MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
    MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
    // the Directory num
    MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
    MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
    MCOS->EmitIntValue(0, 1); // filesize (always 0)
  }
  MCOS->EmitIntValue(0, 1); // Terminate the file list

  // This is the end of the prologue, so set the value of the symbol at the
  // end of the prologue (that was used in a previous expression).
  MCOS->EmitLabel(ProEndSym);

  // Put out the line tables.
  const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
    MCOS->getContext().getMCLineSections();
  const std::vector<const MCSection *> &MCLineSectionOrder =
    MCOS->getContext().getMCLineSectionOrder();
  for (std::vector<const MCSection*>::const_iterator it =
         MCLineSectionOrder.begin(), ie = MCLineSectionOrder.end(); it != ie;
       ++it) {
    const MCSection *Sec = *it;
    const MCLineSection *Line = MCLineSections.lookup(Sec);
    EmitDwarfLineTable(MCOS, Sec, Line, CUID);
  }

  if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines()
      && MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
    // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
    // it requires:
    // total_length >= prologue_length + 10
    // We are 4 bytes short, since we have total_length = 51 and
    // prologue_length = 45

    // The regular end_sequence should be sufficient.
    MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
  }

  // This is the end of the section, so set the value of the symbol at the end
  // of this section (that was used in a previous expression).
  MCOS->EmitLabel(LineEndSym);

  return LineStartSym;
}

/// Utility function to emit the encoding to a streamer.
void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta,
                           uint64_t AddrDelta) {
  MCContext &Context = MCOS->getContext();
  SmallString<256> Tmp;
  raw_svector_ostream OS(Tmp);
  MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OS);
  MCOS->EmitBytes(OS.str());
}

/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta,
                             uint64_t AddrDelta, raw_ostream &OS) {
  uint64_t Temp, Opcode;
  bool NeedCopy = false;

  // Scale the address delta by the minimum instruction length.
  AddrDelta = ScaleAddrDelta(Context, AddrDelta);

  // A LineDelta of INT64_MAX is a signal that this is actually a
  // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
  // end_sequence to emit the matrix entry.
  if (LineDelta == INT64_MAX) {
    if (AddrDelta == MAX_SPECIAL_ADDR_DELTA)
      OS << char(dwarf::DW_LNS_const_add_pc);
    else {
      OS << char(dwarf::DW_LNS_advance_pc);
      encodeULEB128(AddrDelta, OS);
    }
    OS << char(dwarf::DW_LNS_extended_op);
    OS << char(1);
    OS << char(dwarf::DW_LNE_end_sequence);
    return;
  }

  // Bias the line delta by the base.
  Temp = LineDelta - DWARF2_LINE_BASE;

  // If the line increment is out of range of a special opcode, we must encode
  // it with DW_LNS_advance_line.
  if (Temp >= DWARF2_LINE_RANGE) {
    OS << char(dwarf::DW_LNS_advance_line);
    encodeSLEB128(LineDelta, OS);

    LineDelta = 0;
    Temp = 0 - DWARF2_LINE_BASE;
    NeedCopy = true;
  }

  // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
  if (LineDelta == 0 && AddrDelta == 0) {
    OS << char(dwarf::DW_LNS_copy);
    return;
  }

  // Bias the opcode by the special opcode base.
  Temp += DWARF2_LINE_OPCODE_BASE;

  // Avoid overflow when addr_delta is large.
  if (AddrDelta < 256 + MAX_SPECIAL_ADDR_DELTA) {
    // Try using a special opcode.
    Opcode = Temp + AddrDelta * DWARF2_LINE_RANGE;
    if (Opcode <= 255) {
      OS << char(Opcode);
      return;
    }

    // Try using DW_LNS_const_add_pc followed by special op.
    Opcode = Temp + (AddrDelta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
    if (Opcode <= 255) {
      OS << char(dwarf::DW_LNS_const_add_pc);
      OS << char(Opcode);
      return;
    }
  }

  // Otherwise use DW_LNS_advance_pc.
  OS << char(dwarf::DW_LNS_advance_pc);
  encodeULEB128(AddrDelta, OS);

  if (NeedCopy)
    OS << char(dwarf::DW_LNS_copy);
  else
    OS << char(Temp);
}

void MCDwarfFile::print(raw_ostream &OS) const {
  OS << '"' << getName() << '"';
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCDwarfFile::dump() const {
  print(dbgs());
}
#endif

// Utility function to write a tuple for .debug_abbrev.
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
  MCOS->EmitULEB128IntValue(Name);
  MCOS->EmitULEB128IntValue(Form);
}

// When generating dwarf for assembly source files this emits
// the data for .debug_abbrev section which contains three DIEs.
static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
  MCContext &context = MCOS->getContext();
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());

  // DW_TAG_compile_unit DIE abbrev (1).
  MCOS->EmitULEB128IntValue(1);
  MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
  MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
  EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
  EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
  EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
  EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
  EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
  StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
  if (!DwarfDebugFlags.empty())
    EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
  EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
  EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
  EmitAbbrev(MCOS, 0, 0);

  // DW_TAG_label DIE abbrev (2).
  MCOS->EmitULEB128IntValue(2);
  MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label);
  MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
  EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
  EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
  EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
  EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
  EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
  EmitAbbrev(MCOS, 0, 0);

  // DW_TAG_unspecified_parameters DIE abbrev (3).
  MCOS->EmitULEB128IntValue(3);
  MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters);
  MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1);
  EmitAbbrev(MCOS, 0, 0);

  // Terminate the abbreviations for this compilation unit.
  MCOS->EmitIntValue(0, 1);
}

// When generating dwarf for assembly source files this emits the data for
// .debug_aranges section.  Which contains a header and a table of pairs of
// PointerSize'ed values for the address and size of section(s) with line table
// entries (just the default .text in our case) and a terminating pair of zeros.
static void EmitGenDwarfAranges(MCStreamer *MCOS,
                                const MCSymbol *InfoSectionSymbol) {
  MCContext &context = MCOS->getContext();

  // Create a symbol at the end of the section that we are creating the dwarf
  // debugging info to use later in here as part of the expression to calculate
  // the size of the section for the table.
  MCOS->SwitchSection(context.getGenDwarfSection());
  MCSymbol *SectionEndSym = context.CreateTempSymbol();
  MCOS->EmitLabel(SectionEndSym);
  context.setGenDwarfSectionEndSym(SectionEndSym);

  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());

  // This will be the length of the .debug_aranges section, first account for
  // the size of each item in the header (see below where we emit these items).
  int Length = 4 + 2 + 4 + 1 + 1;

  // Figure the padding after the header before the table of address and size
  // pairs who's values are PointerSize'ed.
  const MCAsmInfo *asmInfo = context.getAsmInfo();
  int AddrSize = asmInfo->getPointerSize();
  int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
  if (Pad == 2 * AddrSize)
    Pad = 0;
  Length += Pad;

  // Add the size of the pair of PointerSize'ed values for the address and size
  // of the one default .text section we have in the table.
  Length += 2 * AddrSize;
  // And the pair of terminating zeros.
  Length += 2 * AddrSize;


  // Emit the header for this section.
  // The 4 byte length not including the 4 byte value for the length.
  MCOS->EmitIntValue(Length - 4, 4);
  // The 2 byte version, which is 2.
  MCOS->EmitIntValue(2, 2);
  // The 4 byte offset to the compile unit in the .debug_info from the start
  // of the .debug_info.
  if (InfoSectionSymbol)
    MCOS->EmitSymbolValue(InfoSectionSymbol, 4);
  else
    MCOS->EmitIntValue(0, 4);
  // The 1 byte size of an address.
  MCOS->EmitIntValue(AddrSize, 1);
  // The 1 byte size of a segment descriptor, we use a value of zero.
  MCOS->EmitIntValue(0, 1);
  // Align the header with the padding if needed, before we put out the table.
  for(int i = 0; i < Pad; i++)
    MCOS->EmitIntValue(0, 1);

  // Now emit the table of pairs of PointerSize'ed values for the section(s)
  // address and size, in our case just the one default .text section.
  const MCExpr *Addr = MCSymbolRefExpr::Create(
    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
  const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
    *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0);
  MCOS->EmitAbsValue(Addr, AddrSize);
  MCOS->EmitAbsValue(Size, AddrSize);

  // And finally the pair of terminating zeros.
  MCOS->EmitIntValue(0, AddrSize);
  MCOS->EmitIntValue(0, AddrSize);
}

// When generating dwarf for assembly source files this emits the data for
// .debug_info section which contains three parts.  The header, the compile_unit
// DIE and a list of label DIEs.
static void EmitGenDwarfInfo(MCStreamer *MCOS,
                             const MCSymbol *AbbrevSectionSymbol,
                             const MCSymbol *LineSectionSymbol) {
  MCContext &context = MCOS->getContext();

  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());

  // Create a symbol at the start and end of this section used in here for the
  // expression to calculate the length in the header.
  MCSymbol *InfoStart = context.CreateTempSymbol();
  MCOS->EmitLabel(InfoStart);
  MCSymbol *InfoEnd = context.CreateTempSymbol();

  // First part: the header.

  // The 4 byte total length of the information for this compilation unit, not
  // including these 4 bytes.
  const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
  MCOS->EmitAbsValue(Length, 4);

  // The 2 byte DWARF version, which is 2.
  MCOS->EmitIntValue(2, 2);

  // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
  // it is at the start of that section so this is zero.
  if (AbbrevSectionSymbol) {
    MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
  } else {
    MCOS->EmitIntValue(0, 4);
  }

  const MCAsmInfo *asmInfo = context.getAsmInfo();
  int AddrSize = asmInfo->getPointerSize();
  // The 1 byte size of an address.
  MCOS->EmitIntValue(AddrSize, 1);

  // Second part: the compile_unit DIE.

  // The DW_TAG_compile_unit DIE abbrev (1).
  MCOS->EmitULEB128IntValue(1);

  // DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
  // which is at the start of that section so this is zero.
  if (LineSectionSymbol) {
    MCOS->EmitSymbolValue(LineSectionSymbol, 4);
  } else {
    MCOS->EmitIntValue(0, 4);
  }

  // AT_low_pc, the first address of the default .text section.
  const MCExpr *Start = MCSymbolRefExpr::Create(
    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
  MCOS->EmitAbsValue(Start, AddrSize);

  // AT_high_pc, the last address of the default .text section.
  const MCExpr *End = MCSymbolRefExpr::Create(
    context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context);
  MCOS->EmitAbsValue(End, AddrSize);

  // AT_name, the name of the source file.  Reconstruct from the first directory
  // and file table entries.
  const SmallVectorImpl<StringRef> &MCDwarfDirs =
    context.getMCDwarfDirs();
  if (MCDwarfDirs.size() > 0) {
    MCOS->EmitBytes(MCDwarfDirs[0]);
    MCOS->EmitBytes("/");
  }
  const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
    MCOS->getContext().getMCDwarfFiles();
  MCOS->EmitBytes(MCDwarfFiles[1]->getName());
  MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.

  // AT_comp_dir, the working directory the assembly was done in.
  MCOS->EmitBytes(context.getCompilationDir());
  MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.

  // AT_APPLE_flags, the command line arguments of the assembler tool.
  StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
  if (!DwarfDebugFlags.empty()){
    MCOS->EmitBytes(DwarfDebugFlags);
    MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  }

  // AT_producer, the version of the assembler tool.
  StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
  if (!DwarfDebugProducer.empty()){
    MCOS->EmitBytes(DwarfDebugProducer);
  }
  else {
    MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
    MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
    MCOS->EmitBytes(StringRef(")"));
  }
  MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.

  // AT_language, a 4 byte value.  We use DW_LANG_Mips_Assembler as the dwarf2
  // draft has no standard code for assembler.
  MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2);

  // Third part: the list of label DIEs.

  // Loop on saved info for dwarf labels and create the DIEs for them.
  const std::vector<const MCGenDwarfLabelEntry *> &Entries =
    MCOS->getContext().getMCGenDwarfLabelEntries();
  for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
       Entries.begin(), ie = Entries.end(); it != ie;
       ++it) {
    const MCGenDwarfLabelEntry *Entry = *it;

    // The DW_TAG_label DIE abbrev (2).
    MCOS->EmitULEB128IntValue(2);

    // AT_name, of the label without any leading underbar.
    MCOS->EmitBytes(Entry->getName());
    MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.

    // AT_decl_file, index into the file table.
    MCOS->EmitIntValue(Entry->getFileNumber(), 4);

    // AT_decl_line, source line number.
    MCOS->EmitIntValue(Entry->getLineNumber(), 4);

    // AT_low_pc, start address of the label.
    const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry->getLabel(),
                                             MCSymbolRefExpr::VK_None, context);
    MCOS->EmitAbsValue(AT_low_pc, AddrSize);

    // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
    MCOS->EmitIntValue(0, 1);

    // The DW_TAG_unspecified_parameters DIE abbrev (3).
    MCOS->EmitULEB128IntValue(3);

    // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
    MCOS->EmitIntValue(0, 1);
  }
  // Deallocate the MCGenDwarfLabelEntry classes that saved away the info
  // for the dwarf labels.
  for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
       Entries.begin(), ie = Entries.end(); it != ie;
       ++it) {
    const MCGenDwarfLabelEntry *Entry = *it;
    delete Entry;
  }

  // Add the NULL DIE terminating the Compile Unit DIE's.
  MCOS->EmitIntValue(0, 1);

  // Now set the value of the symbol at the end of the info section.
  MCOS->EmitLabel(InfoEnd);
}

//
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
  // Create the dwarf sections in this order (.debug_line already created).
  MCContext &context = MCOS->getContext();
  const MCAsmInfo *AsmInfo = context.getAsmInfo();
  bool CreateDwarfSectionSymbols =
      AsmInfo->doesDwarfUseRelocationsAcrossSections();
  if (!CreateDwarfSectionSymbols)
    LineSectionSymbol = NULL;
  MCSymbol *AbbrevSectionSymbol = NULL;
  MCSymbol *InfoSectionSymbol = NULL;
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
  if (CreateDwarfSectionSymbols) {
    InfoSectionSymbol = context.CreateTempSymbol();
    MCOS->EmitLabel(InfoSectionSymbol);
  }
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
  if (CreateDwarfSectionSymbols) {
    AbbrevSectionSymbol = context.CreateTempSymbol();
    MCOS->EmitLabel(AbbrevSectionSymbol);
  }
  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());

  // If there are no line table entries then do not emit any section contents.
  if (context.getMCLineSections().empty())
    return;

  // Output the data for .debug_aranges section.
  EmitGenDwarfAranges(MCOS, InfoSectionSymbol);

  // Output the data for .debug_abbrev section.
  EmitGenDwarfAbbrev(MCOS);

  // Output the data for .debug_info section.
  EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
}

//
// When generating dwarf for assembly source files this is called when symbol
// for a label is created.  If this symbol is not a temporary and is in the
// section that dwarf is being generated for, save the needed info to create
// a dwarf label.
//
void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
                                     SourceMgr &SrcMgr, SMLoc &Loc) {
  // We won't create dwarf labels for temporary symbols or symbols not in
  // the default text.
  if (Symbol->isTemporary())
    return;
  MCContext &context = MCOS->getContext();
  if (context.getGenDwarfSection() != MCOS->getCurrentSection().first)
    return;

  // The dwarf label's name does not have the symbol name's leading
  // underbar if any.
  StringRef Name = Symbol->getName();
  if (Name.startswith("_"))
    Name = Name.substr(1, Name.size()-1);

  // Get the dwarf file number to be used for the dwarf label.
  unsigned FileNumber = context.getGenDwarfFileNumber();

  // Finding the line number is the expensive part which is why we just don't
  // pass it in as for some symbols we won't create a dwarf label.
  int CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
  unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);

  // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
  // values so that they don't have things like an ARM thumb bit from the
  // original symbol. So when used they won't get a low bit set after
  // relocation.
  MCSymbol *Label = context.CreateTempSymbol();
  MCOS->EmitLabel(Label);

  // Create and entry for the info and add it to the other entries.
  MCGenDwarfLabelEntry *Entry =
    new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label);
  MCOS->getContext().addMCGenDwarfLabelEntry(Entry);
}

static int getDataAlignmentFactor(MCStreamer &streamer) {
  MCContext &context = streamer.getContext();
  const MCAsmInfo *asmInfo = context.getAsmInfo();
  int size = asmInfo->getCalleeSaveStackSlotSize();
  if (asmInfo->isStackGrowthDirectionUp())
    return size;
  else
    return -size;
}

static unsigned getSizeForEncoding(MCStreamer &streamer,
                                   unsigned symbolEncoding) {
  MCContext &context = streamer.getContext();
  unsigned format = symbolEncoding & 0x0f;
  switch (format) {
  default: llvm_unreachable("Unknown Encoding");
  case dwarf::DW_EH_PE_absptr:
  case dwarf::DW_EH_PE_signed:
    return context.getAsmInfo()->getPointerSize();
  case dwarf::DW_EH_PE_udata2:
  case dwarf::DW_EH_PE_sdata2:
    return 2;
  case dwarf::DW_EH_PE_udata4:
  case dwarf::DW_EH_PE_sdata4:
    return 4;
  case dwarf::DW_EH_PE_udata8:
  case dwarf::DW_EH_PE_sdata8:
    return 8;
  }
}

static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol,
                       unsigned symbolEncoding, bool isEH,
                       const char *comment = 0) {
  MCContext &context = streamer.getContext();
  const MCAsmInfo *asmInfo = context.getAsmInfo();
  const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
                                                 symbolEncoding,
                                                 streamer);
  unsigned size = getSizeForEncoding(streamer, symbolEncoding);
  if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment);
  if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
    streamer.EmitAbsValue(v, size);
  else
    streamer.EmitValue(v, size);
}

static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
                            unsigned symbolEncoding) {
  MCContext &context = streamer.getContext();
  const MCAsmInfo *asmInfo = context.getAsmInfo();
  const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
                                                         symbolEncoding,
                                                         streamer);
  unsigned size = getSizeForEncoding(streamer, symbolEncoding);
  streamer.EmitValue(v, size);
}

namespace {
  class FrameEmitterImpl {
    int CFAOffset;
    int CIENum;
    bool UsingCFI;
    bool IsEH;
    const MCSymbol *SectionStart;
  public:
    FrameEmitterImpl(bool usingCFI, bool isEH)
      : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
        SectionStart(0) {}

    void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }

    /// EmitCompactUnwind - Emit the unwind information in a compact way.
    void EmitCompactUnwind(MCStreamer &streamer,
                           const MCDwarfFrameInfo &frame);

    const MCSymbol &EmitCIE(MCStreamer &streamer,
                            const MCSymbol *personality,
                            unsigned personalityEncoding,
                            const MCSymbol *lsda,
                            bool IsSignalFrame,
                            unsigned lsdaEncoding);
    MCSymbol *EmitFDE(MCStreamer &streamer,
                      const MCSymbol &cieStart,
                      const MCDwarfFrameInfo &frame);
    void EmitCFIInstructions(MCStreamer &streamer,
                             ArrayRef<MCCFIInstruction> Instrs,
                             MCSymbol *BaseLabel);
    void EmitCFIInstruction(MCStreamer &Streamer,
                            const MCCFIInstruction &Instr);
  };

} // end anonymous namespace

static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
                             StringRef Prefix) {
  if (Streamer.isVerboseAsm()) {
    const char *EncStr;
    switch (Encoding) {
    default: EncStr = "<unknown encoding>"; break;
    case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break;
    case dwarf::DW_EH_PE_omit:   EncStr = "omit"; break;
    case dwarf::DW_EH_PE_pcrel:  EncStr = "pcrel"; break;
    case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break;
    case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break;
    case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break;
    case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break;
    case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
      EncStr = "pcrel udata4";
      break;
    case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
      EncStr = "pcrel sdata4";
      break;
    case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
      EncStr = "pcrel udata8";
      break;
    case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
      EncStr = "screl sdata8";
      break;
    case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4:
      EncStr = "indirect pcrel udata4";
      break;
    case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4:
      EncStr = "indirect pcrel sdata4";
      break;
    case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8:
      EncStr = "indirect pcrel udata8";
      break;
    case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8:
      EncStr = "indirect pcrel sdata8";
      break;
    }

    Streamer.AddComment(Twine(Prefix) + " = " + EncStr);
  }

  Streamer.EmitIntValue(Encoding, 1);
}

void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
                                          const MCCFIInstruction &Instr) {
  int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
  bool VerboseAsm = Streamer.isVerboseAsm();

  switch (Instr.getOperation()) {
  case MCCFIInstruction::OpRegister: {
    unsigned Reg1 = Instr.getRegister();
    unsigned Reg2 = Instr.getRegister2();
    if (VerboseAsm) {
      Streamer.AddComment("DW_CFA_register");
      Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1));
      Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2));
    }
    Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
    Streamer.EmitULEB128IntValue(Reg1);
    Streamer.EmitULEB128IntValue(Reg2);
    return;
  }
  case MCCFIInstruction::OpWindowSave: {
    Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
    return;
  }
  case MCCFIInstruction::OpUndefined: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) {
      Streamer.AddComment("DW_CFA_undefined");
      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    }
    Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
    Streamer.EmitULEB128IntValue(Reg);
    return;
  }
  case MCCFIInstruction::OpAdjustCfaOffset:
  case MCCFIInstruction::OpDefCfaOffset: {
    const bool IsRelative =
      Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;

    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa_offset");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);

    if (IsRelative)
      CFAOffset += Instr.getOffset();
    else
      CFAOffset = -Instr.getOffset();

    if (VerboseAsm)
      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
    Streamer.EmitULEB128IntValue(CFAOffset);

    return;
  }
  case MCCFIInstruction::OpDefCfa: {
    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);

    if (VerboseAsm)
      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
    Streamer.EmitULEB128IntValue(Instr.getRegister());

    CFAOffset = -Instr.getOffset();

    if (VerboseAsm)
      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
    Streamer.EmitULEB128IntValue(CFAOffset);

    return;
  }

  case MCCFIInstruction::OpDefCfaRegister: {
    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa_register");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);

    if (VerboseAsm)
      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
    Streamer.EmitULEB128IntValue(Instr.getRegister());

    return;
  }

  case MCCFIInstruction::OpOffset:
  case MCCFIInstruction::OpRelOffset: {
    const bool IsRelative =
      Instr.getOperation() == MCCFIInstruction::OpRelOffset;

    unsigned Reg = Instr.getRegister();
    int Offset = Instr.getOffset();
    if (IsRelative)
      Offset -= CFAOffset;
    Offset = Offset / dataAlignmentFactor;

    if (Offset < 0) {
      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
      Streamer.EmitULEB128IntValue(Reg);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitSLEB128IntValue(Offset);
    } else if (Reg < 64) {
      if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
                                          Twine(Reg) + ")");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitULEB128IntValue(Offset);
    } else {
      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
      Streamer.EmitULEB128IntValue(Reg);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitULEB128IntValue(Offset);
    }
    return;
  }
  case MCCFIInstruction::OpRememberState:
    if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
    Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
    return;
  case MCCFIInstruction::OpRestoreState:
    if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
    Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
    return;
  case MCCFIInstruction::OpSameValue: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
    Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
    if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    Streamer.EmitULEB128IntValue(Reg);
    return;
  }
  case MCCFIInstruction::OpRestore: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) {
      Streamer.AddComment("DW_CFA_restore");
      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    }
    Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
    return;
  }
  case MCCFIInstruction::OpEscape:
    if (VerboseAsm) Streamer.AddComment("Escape bytes");
    Streamer.EmitBytes(Instr.getValues());
    return;
  }
  llvm_unreachable("Unhandled case in switch");
}

/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer,
                                           ArrayRef<MCCFIInstruction> Instrs,
                                           MCSymbol *BaseLabel) {
  for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
    const MCCFIInstruction &Instr = Instrs[i];
    MCSymbol *Label = Instr.getLabel();
    // Throw out move if the label is invalid.
    if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.

    // Advance row if new location.
    if (BaseLabel && Label) {
      MCSymbol *ThisSym = Label;
      if (ThisSym != BaseLabel) {
        if (streamer.isVerboseAsm()) streamer.AddComment("DW_CFA_advance_loc4");
        streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
        BaseLabel = ThisSym;
      }
    }

    EmitCFIInstruction(streamer, Instr);
  }
}

/// EmitCompactUnwind - Emit the unwind information in a compact way.
void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
                                         const MCDwarfFrameInfo &Frame) {
  MCContext &Context = Streamer.getContext();
  const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
  bool VerboseAsm = Streamer.isVerboseAsm();

  // range-start range-length  compact-unwind-enc personality-func   lsda
  //  _foo       LfooEnd-_foo  0x00000023          0                 0
  //  _bar       LbarEnd-_bar  0x00000025         __gxx_personality  except_tab1
  //
  //   .section __LD,__compact_unwind,regular,debug
  //
  //   # compact unwind for _foo
  //   .quad _foo
  //   .set L1,LfooEnd-_foo
  //   .long L1
  //   .long 0x01010001
  //   .quad 0
  //   .quad 0
  //
  //   # compact unwind for _bar
  //   .quad _bar
  //   .set L2,LbarEnd-_bar
  //   .long L2
  //   .long 0x01020011
  //   .quad __gxx_personality
  //   .quad except_tab1

  uint32_t Encoding = Frame.CompactUnwindEncoding;
  if (!Encoding) return;
  bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());

  // The encoding needs to know we have an LSDA.
  if (!DwarfEHFrameOnly && Frame.Lsda)
    Encoding |= 0x40000000;

  // Range Start
  unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI);
  unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
  if (VerboseAsm) Streamer.AddComment("Range Start");
  Streamer.EmitSymbolValue(Frame.Function, Size);

  // Range Length
  const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
                                              *Frame.End, 0);
  if (VerboseAsm) Streamer.AddComment("Range Length");
  Streamer.EmitAbsValue(Range, 4);

  // Compact Encoding
  Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
  if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" +
                                      Twine::utohexstr(Encoding));
  Streamer.EmitIntValue(Encoding, Size);

  // Personality Function
  Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr);
  if (VerboseAsm) Streamer.AddComment("Personality Function");
  if (!DwarfEHFrameOnly && Frame.Personality)
    Streamer.EmitSymbolValue(Frame.Personality, Size);
  else
    Streamer.EmitIntValue(0, Size); // No personality fn

  // LSDA
  Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
  if (VerboseAsm) Streamer.AddComment("LSDA");
  if (!DwarfEHFrameOnly && Frame.Lsda)
    Streamer.EmitSymbolValue(Frame.Lsda, Size);
  else
    Streamer.EmitIntValue(0, Size); // No LSDA
}

const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
                                          const MCSymbol *personality,
                                          unsigned personalityEncoding,
                                          const MCSymbol *lsda,
                                          bool IsSignalFrame,
                                          unsigned lsdaEncoding) {
  MCContext &context = streamer.getContext();
  const MCRegisterInfo *MRI = context.getRegisterInfo();
  const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
  bool verboseAsm = streamer.isVerboseAsm();

  MCSymbol *sectionStart;
  if (MOFI->isFunctionEHFrameSymbolPrivate() || !IsEH)
    sectionStart = context.CreateTempSymbol();
  else
    sectionStart = context.GetOrCreateSymbol(Twine("EH_frame") + Twine(CIENum));

  streamer.EmitLabel(sectionStart);
  CIENum++;

  MCSymbol *sectionEnd = context.CreateTempSymbol();

  // Length
  const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
                                               *sectionEnd, 4);
  if (verboseAsm) streamer.AddComment("CIE Length");
  streamer.EmitAbsValue(Length, 4);

  // CIE ID
  unsigned CIE_ID = IsEH ? 0 : -1;
  if (verboseAsm) streamer.AddComment("CIE ID Tag");
  streamer.EmitIntValue(CIE_ID, 4);

  // Version
  if (verboseAsm) streamer.AddComment("DW_CIE_VERSION");
  streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);

  // Augmentation String
  SmallString<8> Augmentation;
  if (IsEH) {
    if (verboseAsm) streamer.AddComment("CIE Augmentation");
    Augmentation += "z";
    if (personality)
      Augmentation += "P";
    if (lsda)
      Augmentation += "L";
    Augmentation += "R";
    if (IsSignalFrame)
      Augmentation += "S";
    streamer.EmitBytes(Augmentation.str());
  }
  streamer.EmitIntValue(0, 1);

  // Code Alignment Factor
  if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor");
  streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());

  // Data Alignment Factor
  if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor");
  streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer));

  // Return Address Register
  if (verboseAsm) streamer.AddComment("CIE Return Address Column");
  streamer.EmitULEB128IntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true));

  // Augmentation Data Length (optional)

  unsigned augmentationLength = 0;
  if (IsEH) {
    if (personality) {
      // Personality Encoding
      augmentationLength += 1;
      // Personality
      augmentationLength += getSizeForEncoding(streamer, personalityEncoding);
    }
    if (lsda)
      augmentationLength += 1;
    // Encoding of the FDE pointers
    augmentationLength += 1;

    if (verboseAsm) streamer.AddComment("Augmentation Size");
    streamer.EmitULEB128IntValue(augmentationLength);

    // Augmentation Data (optional)
    if (personality) {
      // Personality Encoding
      EmitEncodingByte(streamer, personalityEncoding,
                       "Personality Encoding");
      // Personality
      if (verboseAsm) streamer.AddComment("Personality");
      EmitPersonality(streamer, *personality, personalityEncoding);
    }

    if (lsda)
      EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding");

    // Encoding of the FDE pointers
    EmitEncodingByte(streamer, MOFI->getFDEEncoding(UsingCFI),
                     "FDE Encoding");
  }

  // Initial Instructions

  const MCAsmInfo *MAI = context.getAsmInfo();
  const std::vector<MCCFIInstruction> &Instructions =
      MAI->getInitialFrameState();
  EmitCFIInstructions(streamer, Instructions, NULL);

  // Padding
  streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());

  streamer.EmitLabel(sectionEnd);
  return *sectionStart;
}

MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
                                    const MCSymbol &cieStart,
                                    const MCDwarfFrameInfo &frame) {
  MCContext &context = streamer.getContext();
  MCSymbol *fdeStart = context.CreateTempSymbol();
  MCSymbol *fdeEnd = context.CreateTempSymbol();
  const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
  bool verboseAsm = streamer.isVerboseAsm();

  if (IsEH && frame.Function && !MOFI->isFunctionEHFrameSymbolPrivate()) {
    MCSymbol *EHSym =
      context.GetOrCreateSymbol(frame.Function->getName() + Twine(".eh"));
    streamer.EmitEHSymAttributes(frame.Function, EHSym);
    streamer.EmitLabel(EHSym);
  }

  // Length
  const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
  if (verboseAsm) streamer.AddComment("FDE Length");
  streamer.EmitAbsValue(Length, 4);

  streamer.EmitLabel(fdeStart);

  // CIE Pointer
  const MCAsmInfo *asmInfo = context.getAsmInfo();
  if (IsEH) {
    const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
                                                 0);
    if (verboseAsm) streamer.AddComment("FDE CIE Offset");
    streamer.EmitAbsValue(offset, 4);
  } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
    const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
                                                 cieStart, 0);
    streamer.EmitAbsValue(offset, 4);
  } else {
    streamer.EmitSymbolValue(&cieStart, 4);
  }

  // PC Begin
  unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI)
                             : (unsigned)dwarf::DW_EH_PE_absptr;
  unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
  EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location");

  // PC Range
  const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
                                              *frame.End, 0);
  if (verboseAsm) streamer.AddComment("FDE address range");
  streamer.EmitAbsValue(Range, PCSize);

  if (IsEH) {
    // Augmentation Data Length
    unsigned augmentationLength = 0;

    if (frame.Lsda)
      augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);

    if (verboseAsm) streamer.AddComment("Augmentation size");
    streamer.EmitULEB128IntValue(augmentationLength);

    // Augmentation Data
    if (frame.Lsda)
      EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true,
                    "Language Specific Data Area");
  }

  // Call Frame Instructions
  EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);

  // Padding
  streamer.EmitValueToAlignment(PCSize);

  return fdeEnd;
}

namespace {
  struct CIEKey {
    static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
    static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }

    CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
           unsigned LsdaEncoding_, bool IsSignalFrame_) :
      Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
      LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
    }
    const MCSymbol* Personality;
    unsigned PersonalityEncoding;
    unsigned LsdaEncoding;
    bool IsSignalFrame;
  };
}

namespace llvm {
  template <>
  struct DenseMapInfo<CIEKey> {
    static CIEKey getEmptyKey() {
      return CIEKey::getEmptyKey();
    }
    static CIEKey getTombstoneKey() {
      return CIEKey::getTombstoneKey();
    }
    static unsigned getHashValue(const CIEKey &Key) {
      return static_cast<unsigned>(hash_combine(Key.Personality,
                                                Key.PersonalityEncoding,
                                                Key.LsdaEncoding,
                                                Key.IsSignalFrame));
    }
    static bool isEqual(const CIEKey &LHS,
                        const CIEKey &RHS) {
      return LHS.Personality == RHS.Personality &&
        LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
        LHS.LsdaEncoding == RHS.LsdaEncoding &&
        LHS.IsSignalFrame == RHS.IsSignalFrame;
    }
  };
}

void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
                               bool UsingCFI, bool IsEH) {
  Streamer.generateCompactUnwindEncodings(MAB);

  MCContext &Context = Streamer.getContext();
  const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
  FrameEmitterImpl Emitter(UsingCFI, IsEH);
  ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();

  // Emit the compact unwind info if available.
  if (IsEH && MOFI->getCompactUnwindSection()) {
    bool SectionEmitted = false;
    for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
      const MCDwarfFrameInfo &Frame = FrameArray[i];
      if (Frame.CompactUnwindEncoding == 0) continue;
      if (!SectionEmitted) {
        Streamer.SwitchSection(MOFI->getCompactUnwindSection());
        Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
        SectionEmitted = true;
      }
      Emitter.EmitCompactUnwind(Streamer, Frame);
    }
  }

  const MCSection &Section =
    IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
           *MOFI->getDwarfFrameSection();
  Streamer.SwitchSection(&Section);
  MCSymbol *SectionStart = Context.CreateTempSymbol();
  Streamer.EmitLabel(SectionStart);
  Emitter.setSectionStart(SectionStart);

  MCSymbol *FDEEnd = NULL;
  DenseMap<CIEKey, const MCSymbol*> CIEStarts;

  const MCSymbol *DummyDebugKey = NULL;
  for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
    const MCDwarfFrameInfo &Frame = FrameArray[i];
    CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
               Frame.LsdaEncoding, Frame.IsSignalFrame);
    const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
    if (!CIEStart)
      CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
                                  Frame.PersonalityEncoding, Frame.Lsda,
                                  Frame.IsSignalFrame,
                                  Frame.LsdaEncoding);

    FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);

    if (i != n - 1)
      Streamer.EmitLabel(FDEEnd);
  }

  Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
  if (FDEEnd)
    Streamer.EmitLabel(FDEEnd);
}

void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
                                         uint64_t AddrDelta) {
  MCContext &Context = Streamer.getContext();
  SmallString<256> Tmp;
  raw_svector_ostream OS(Tmp);
  MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS);
  Streamer.EmitBytes(OS.str());
}

void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context,
                                           uint64_t AddrDelta,
                                           raw_ostream &OS) {
  // Scale the address delta by the minimum instruction length.
  AddrDelta = ScaleAddrDelta(Context, AddrDelta);

  if (AddrDelta == 0) {
  } else if (isUIntN(6, AddrDelta)) {
    uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
    OS << Opcode;
  } else if (isUInt<8>(AddrDelta)) {
    OS << uint8_t(dwarf::DW_CFA_advance_loc1);
    OS << uint8_t(AddrDelta);
  } else if (isUInt<16>(AddrDelta)) {
    // FIXME: check what is the correct behavior on a big endian machine.
    OS << uint8_t(dwarf::DW_CFA_advance_loc2);
    OS << uint8_t( AddrDelta       & 0xff);
    OS << uint8_t((AddrDelta >> 8) & 0xff);
  } else {
    // FIXME: check what is the correct behavior on a big endian machine.
    assert(isUInt<32>(AddrDelta));
    OS << uint8_t(dwarf::DW_CFA_advance_loc4);
    OS << uint8_t( AddrDelta        & 0xff);
    OS << uint8_t((AddrDelta >> 8)  & 0xff);
    OS << uint8_t((AddrDelta >> 16) & 0xff);
    OS << uint8_t((AddrDelta >> 24) & 0xff);

  }
}
