Home | History | Annotate | Download | only in MC
      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/MC/MCDwarf.h"
     11 #include "llvm/ADT/Hashing.h"
     12 #include "llvm/ADT/STLExtras.h"
     13 #include "llvm/ADT/SmallString.h"
     14 #include "llvm/ADT/Twine.h"
     15 #include "llvm/Config/config.h"
     16 #include "llvm/MC/MCAsmInfo.h"
     17 #include "llvm/MC/MCContext.h"
     18 #include "llvm/MC/MCExpr.h"
     19 #include "llvm/MC/MCObjectFileInfo.h"
     20 #include "llvm/MC/MCObjectStreamer.h"
     21 #include "llvm/MC/MCRegisterInfo.h"
     22 #include "llvm/MC/MCSection.h"
     23 #include "llvm/MC/MCSymbol.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Support/ErrorHandling.h"
     26 #include "llvm/Support/LEB128.h"
     27 #include "llvm/Support/Path.h"
     28 #include "llvm/Support/SourceMgr.h"
     29 #include "llvm/Support/raw_ostream.h"
     30 using namespace llvm;
     31 
     32 // Given a special op, return the address skip amount (in units of
     33 // DWARF2_LINE_MIN_INSN_LENGTH.
     34 #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
     35 
     36 // The maximum address skip amount that can be encoded with a special op.
     37 #define MAX_SPECIAL_ADDR_DELTA         SPECIAL_ADDR(255)
     38 
     39 // First special line opcode - leave room for the standard opcodes.
     40 // Note: If you want to change this, you'll have to update the
     41 // "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
     42 #define DWARF2_LINE_OPCODE_BASE         13
     43 
     44 // Minimum line offset in a special line info. opcode.  This value
     45 // was chosen to give a reasonable range of values.
     46 #define DWARF2_LINE_BASE                -5
     47 
     48 // Range of line offsets in a special line info. opcode.
     49 #define DWARF2_LINE_RANGE               14
     50 
     51 static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
     52   unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
     53   if (MinInsnLength == 1)
     54     return AddrDelta;
     55   if (AddrDelta % MinInsnLength != 0) {
     56     // TODO: report this error, but really only once.
     57     ;
     58   }
     59   return AddrDelta / MinInsnLength;
     60 }
     61 
     62 //
     63 // This is called when an instruction is assembled into the specified section
     64 // and if there is information from the last .loc directive that has yet to have
     65 // a line entry made for it is made.
     66 //
     67 void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) {
     68   if (!MCOS->getContext().getDwarfLocSeen())
     69     return;
     70 
     71   // Create a symbol at in the current section for use in the line entry.
     72   MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol();
     73   // Set the value of the symbol to use for the MCLineEntry.
     74   MCOS->EmitLabel(LineSym);
     75 
     76   // Get the current .loc info saved in the context.
     77   const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
     78 
     79   // Create a (local) line entry with the symbol and the current .loc info.
     80   MCLineEntry LineEntry(LineSym, DwarfLoc);
     81 
     82   // clear DwarfLocSeen saying the current .loc info is now used.
     83   MCOS->getContext().ClearDwarfLocSeen();
     84 
     85   // Add the line entry to this section's entries.
     86   MCOS->getContext()
     87       .getMCDwarfLineTable(MCOS->getContext().getDwarfCompileUnitID())
     88       .getMCLineSections()
     89       .addLineEntry(LineEntry, Section);
     90 }
     91 
     92 //
     93 // This helper routine returns an expression of End - Start + IntVal .
     94 //
     95 static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
     96                                                   const MCSymbol &Start,
     97                                                   const MCSymbol &End,
     98                                                   int IntVal) {
     99   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    100   const MCExpr *Res =
    101     MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext());
    102   const MCExpr *RHS =
    103     MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext());
    104   const MCExpr *Res1 =
    105     MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
    106   const MCExpr *Res2 =
    107     MCConstantExpr::Create(IntVal, MCOS.getContext());
    108   const MCExpr *Res3 =
    109     MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
    110   return Res3;
    111 }
    112 
    113 //
    114 // This emits the Dwarf line table for the specified section from the entries
    115 // in the LineSection.
    116 //
    117 static inline void
    118 EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section,
    119                    const MCLineSection::MCLineEntryCollection &LineEntries) {
    120   unsigned FileNum = 1;
    121   unsigned LastLine = 1;
    122   unsigned Column = 0;
    123   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
    124   unsigned Isa = 0;
    125   unsigned Discriminator = 0;
    126   MCSymbol *LastLabel = nullptr;
    127 
    128   // Loop through each MCLineEntry and encode the dwarf line number table.
    129   for (auto it = LineEntries.begin(),
    130             ie = LineEntries.end();
    131        it != ie; ++it) {
    132 
    133     if (FileNum != it->getFileNum()) {
    134       FileNum = it->getFileNum();
    135       MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
    136       MCOS->EmitULEB128IntValue(FileNum);
    137     }
    138     if (Column != it->getColumn()) {
    139       Column = it->getColumn();
    140       MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
    141       MCOS->EmitULEB128IntValue(Column);
    142     }
    143     if (Discriminator != it->getDiscriminator()) {
    144       Discriminator = it->getDiscriminator();
    145       unsigned Size = getULEB128Size(Discriminator);
    146       MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
    147       MCOS->EmitULEB128IntValue(Size + 1);
    148       MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1);
    149       MCOS->EmitULEB128IntValue(Discriminator);
    150     }
    151     if (Isa != it->getIsa()) {
    152       Isa = it->getIsa();
    153       MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
    154       MCOS->EmitULEB128IntValue(Isa);
    155     }
    156     if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
    157       Flags = it->getFlags();
    158       MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
    159     }
    160     if (it->getFlags() & DWARF2_FLAG_BASIC_BLOCK)
    161       MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
    162     if (it->getFlags() & DWARF2_FLAG_PROLOGUE_END)
    163       MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
    164     if (it->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
    165       MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
    166 
    167     int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine;
    168     MCSymbol *Label = it->getLabel();
    169 
    170     // At this point we want to emit/create the sequence to encode the delta in
    171     // line numbers and the increment of the address from the previous Label
    172     // and the current Label.
    173     const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
    174     MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
    175                                    asmInfo->getPointerSize());
    176 
    177     LastLine = it->getLine();
    178     LastLabel = Label;
    179   }
    180 
    181   // Emit a DW_LNE_end_sequence for the end of the section.
    182   // Using the pointer Section create a temporary label at the end of the
    183   // section and use that and the LastLabel to compute the address delta
    184   // and use INT64_MAX as the line delta which is the signal that this is
    185   // actually a DW_LNE_end_sequence.
    186 
    187   // Switch to the section to be able to create a symbol at its end.
    188   // TODO: keep track of the last subsection so that this symbol appears in the
    189   // correct place.
    190   MCOS->SwitchSection(Section);
    191 
    192   MCContext &context = MCOS->getContext();
    193   // Create a symbol at the end of the section.
    194   MCSymbol *SectionEnd = context.CreateTempSymbol();
    195   // Set the value of the symbol, as we are at the end of the section.
    196   MCOS->EmitLabel(SectionEnd);
    197 
    198   // Switch back the dwarf line section.
    199   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
    200 
    201   const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
    202   MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
    203                                  asmInfo->getPointerSize());
    204 }
    205 
    206 //
    207 // This emits the Dwarf file and the line tables.
    208 //
    209 void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS) {
    210   MCContext &context = MCOS->getContext();
    211 
    212   auto &LineTables = context.getMCDwarfLineTables();
    213 
    214   // Bail out early so we don't switch to the debug_line section needlessly and
    215   // in doing so create an unnecessary (if empty) section.
    216   if (LineTables.empty())
    217     return;
    218 
    219   // Switch to the section where the table will be emitted into.
    220   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
    221 
    222   // Handle the rest of the Compile Units.
    223   for (const auto &CUIDTablePair : LineTables)
    224     CUIDTablePair.second.EmitCU(MCOS);
    225 }
    226 
    227 void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS) const {
    228   MCOS.EmitLabel(Header.Emit(&MCOS, None).second);
    229 }
    230 
    231 std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS) const {
    232   static const char StandardOpcodeLengths[] = {
    233       0, // length of DW_LNS_copy
    234       1, // length of DW_LNS_advance_pc
    235       1, // length of DW_LNS_advance_line
    236       1, // length of DW_LNS_set_file
    237       1, // length of DW_LNS_set_column
    238       0, // length of DW_LNS_negate_stmt
    239       0, // length of DW_LNS_set_basic_block
    240       0, // length of DW_LNS_const_add_pc
    241       1, // length of DW_LNS_fixed_advance_pc
    242       0, // length of DW_LNS_set_prologue_end
    243       0, // length of DW_LNS_set_epilogue_begin
    244       1  // DW_LNS_set_isa
    245   };
    246   assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1));
    247   return Emit(MCOS, StandardOpcodeLengths);
    248 }
    249 
    250 std::pair<MCSymbol *, MCSymbol *>
    251 MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
    252                              ArrayRef<char> StandardOpcodeLengths) const {
    253 
    254   MCContext &context = MCOS->getContext();
    255 
    256   // Create a symbol at the beginning of the line table.
    257   MCSymbol *LineStartSym = Label;
    258   if (!LineStartSym)
    259     LineStartSym = context.CreateTempSymbol();
    260   // Set the value of the symbol, as we are at the start of the line table.
    261   MCOS->EmitLabel(LineStartSym);
    262 
    263   // Create a symbol for the end of the section (to be set when we get there).
    264   MCSymbol *LineEndSym = context.CreateTempSymbol();
    265 
    266   // The first 4 bytes is the total length of the information for this
    267   // compilation unit (not including these 4 bytes for the length).
    268   MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym,4),
    269                      4);
    270 
    271   // Next 2 bytes is the Version, which is Dwarf 2.
    272   MCOS->EmitIntValue(2, 2);
    273 
    274   // Create a symbol for the end of the prologue (to be set when we get there).
    275   MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end
    276 
    277   // Length of the prologue, is the next 4 bytes.  Which is the start of the
    278   // section to the end of the prologue.  Not including the 4 bytes for the
    279   // total length, the 2 bytes for the version, and these 4 bytes for the
    280   // length of the prologue.
    281   MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
    282                                            (4 + 2 + 4)), 4);
    283 
    284   // Parameters of the state machine, are next.
    285   MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1);
    286   MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
    287   MCOS->EmitIntValue(DWARF2_LINE_BASE, 1);
    288   MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1);
    289   MCOS->EmitIntValue(StandardOpcodeLengths.size() + 1, 1);
    290 
    291   // Standard opcode lengths
    292   for (char Length : StandardOpcodeLengths)
    293     MCOS->EmitIntValue(Length, 1);
    294 
    295   // Put out the directory and file tables.
    296 
    297   // First the directory table.
    298   for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
    299     MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
    300     MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
    301   }
    302   MCOS->EmitIntValue(0, 1); // Terminate the directory list
    303 
    304   // Second the file table.
    305   for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
    306     assert(!MCDwarfFiles[i].Name.empty());
    307     MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName
    308     MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
    309     // the Directory num
    310     MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex);
    311     MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
    312     MCOS->EmitIntValue(0, 1); // filesize (always 0)
    313   }
    314   MCOS->EmitIntValue(0, 1); // Terminate the file list
    315 
    316   // This is the end of the prologue, so set the value of the symbol at the
    317   // end of the prologue (that was used in a previous expression).
    318   MCOS->EmitLabel(ProEndSym);
    319 
    320   return std::make_pair(LineStartSym, LineEndSym);
    321 }
    322 
    323 void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS) const {
    324   MCSymbol *LineEndSym = Header.Emit(MCOS).second;
    325 
    326   // Put out the line tables.
    327   for (const auto &LineSec : MCLineSections.getMCLineEntries())
    328     EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
    329 
    330   if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
    331       MCLineSections.getMCLineEntries().empty()) {
    332     // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
    333     // it requires:
    334     // total_length >= prologue_length + 10
    335     // We are 4 bytes short, since we have total_length = 51 and
    336     // prologue_length = 45
    337 
    338     // The regular end_sequence should be sufficient.
    339     MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
    340   }
    341 
    342   // This is the end of the section, so set the value of the symbol at the end
    343   // of this section (that was used in a previous expression).
    344   MCOS->EmitLabel(LineEndSym);
    345 }
    346 
    347 unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName,
    348                                    unsigned FileNumber) {
    349   return Header.getFile(Directory, FileName, FileNumber);
    350 }
    351 
    352 unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory,
    353                                          StringRef &FileName,
    354                                          unsigned FileNumber) {
    355   if (Directory == CompilationDir)
    356     Directory = "";
    357   if (FileName.empty()) {
    358     FileName = "<stdin>";
    359     Directory = "";
    360   }
    361   assert(!FileName.empty());
    362   if (FileNumber == 0) {
    363     FileNumber = SourceIdMap.size() + 1;
    364     assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) &&
    365            "Don't mix autonumbered and explicit numbered line table usage");
    366     StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(
    367         (Directory + Twine('\0') + FileName).str(), FileNumber);
    368     if (Ent.getValue() != FileNumber)
    369       return Ent.getValue();
    370   }
    371   // Make space for this FileNumber in the MCDwarfFiles vector if needed.
    372   MCDwarfFiles.resize(FileNumber + 1);
    373 
    374   // Get the new MCDwarfFile slot for this FileNumber.
    375   MCDwarfFile &File = MCDwarfFiles[FileNumber];
    376 
    377   // It is an error to use see the same number more than once.
    378   if (!File.Name.empty())
    379     return 0;
    380 
    381   if (Directory.empty()) {
    382     // Separate the directory part from the basename of the FileName.
    383     StringRef tFileName = sys::path::filename(FileName);
    384     if (!tFileName.empty()) {
    385       Directory = sys::path::parent_path(FileName);
    386       if (!Directory.empty())
    387         FileName = tFileName;
    388     }
    389   }
    390 
    391   // Find or make an entry in the MCDwarfDirs vector for this Directory.
    392   // Capture directory name.
    393   unsigned DirIndex;
    394   if (Directory.empty()) {
    395     // For FileNames with no directories a DirIndex of 0 is used.
    396     DirIndex = 0;
    397   } else {
    398     DirIndex = 0;
    399     for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
    400       if (Directory == MCDwarfDirs[DirIndex])
    401         break;
    402     }
    403     if (DirIndex >= MCDwarfDirs.size())
    404       MCDwarfDirs.push_back(Directory);
    405     // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
    406     // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
    407     // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
    408     // are stored at MCDwarfFiles[FileNumber].Name .
    409     DirIndex++;
    410   }
    411 
    412   File.Name = FileName;
    413   File.DirIndex = DirIndex;
    414 
    415   // return the allocated FileNumber.
    416   return FileNumber;
    417 }
    418 
    419 /// Utility function to emit the encoding to a streamer.
    420 void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta,
    421                            uint64_t AddrDelta) {
    422   MCContext &Context = MCOS->getContext();
    423   SmallString<256> Tmp;
    424   raw_svector_ostream OS(Tmp);
    425   MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OS);
    426   MCOS->EmitBytes(OS.str());
    427 }
    428 
    429 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
    430 void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta,
    431                              uint64_t AddrDelta, raw_ostream &OS) {
    432   uint64_t Temp, Opcode;
    433   bool NeedCopy = false;
    434 
    435   // Scale the address delta by the minimum instruction length.
    436   AddrDelta = ScaleAddrDelta(Context, AddrDelta);
    437 
    438   // A LineDelta of INT64_MAX is a signal that this is actually a
    439   // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
    440   // end_sequence to emit the matrix entry.
    441   if (LineDelta == INT64_MAX) {
    442     if (AddrDelta == MAX_SPECIAL_ADDR_DELTA)
    443       OS << char(dwarf::DW_LNS_const_add_pc);
    444     else {
    445       OS << char(dwarf::DW_LNS_advance_pc);
    446       encodeULEB128(AddrDelta, OS);
    447     }
    448     OS << char(dwarf::DW_LNS_extended_op);
    449     OS << char(1);
    450     OS << char(dwarf::DW_LNE_end_sequence);
    451     return;
    452   }
    453 
    454   // Bias the line delta by the base.
    455   Temp = LineDelta - DWARF2_LINE_BASE;
    456 
    457   // If the line increment is out of range of a special opcode, we must encode
    458   // it with DW_LNS_advance_line.
    459   if (Temp >= DWARF2_LINE_RANGE) {
    460     OS << char(dwarf::DW_LNS_advance_line);
    461     encodeSLEB128(LineDelta, OS);
    462 
    463     LineDelta = 0;
    464     Temp = 0 - DWARF2_LINE_BASE;
    465     NeedCopy = true;
    466   }
    467 
    468   // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
    469   if (LineDelta == 0 && AddrDelta == 0) {
    470     OS << char(dwarf::DW_LNS_copy);
    471     return;
    472   }
    473 
    474   // Bias the opcode by the special opcode base.
    475   Temp += DWARF2_LINE_OPCODE_BASE;
    476 
    477   // Avoid overflow when addr_delta is large.
    478   if (AddrDelta < 256 + MAX_SPECIAL_ADDR_DELTA) {
    479     // Try using a special opcode.
    480     Opcode = Temp + AddrDelta * DWARF2_LINE_RANGE;
    481     if (Opcode <= 255) {
    482       OS << char(Opcode);
    483       return;
    484     }
    485 
    486     // Try using DW_LNS_const_add_pc followed by special op.
    487     Opcode = Temp + (AddrDelta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
    488     if (Opcode <= 255) {
    489       OS << char(dwarf::DW_LNS_const_add_pc);
    490       OS << char(Opcode);
    491       return;
    492     }
    493   }
    494 
    495   // Otherwise use DW_LNS_advance_pc.
    496   OS << char(dwarf::DW_LNS_advance_pc);
    497   encodeULEB128(AddrDelta, OS);
    498 
    499   if (NeedCopy)
    500     OS << char(dwarf::DW_LNS_copy);
    501   else
    502     OS << char(Temp);
    503 }
    504 
    505 // Utility function to write a tuple for .debug_abbrev.
    506 static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
    507   MCOS->EmitULEB128IntValue(Name);
    508   MCOS->EmitULEB128IntValue(Form);
    509 }
    510 
    511 // When generating dwarf for assembly source files this emits
    512 // the data for .debug_abbrev section which contains three DIEs.
    513 static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
    514   MCContext &context = MCOS->getContext();
    515   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
    516 
    517   // DW_TAG_compile_unit DIE abbrev (1).
    518   MCOS->EmitULEB128IntValue(1);
    519   MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
    520   MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
    521   EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
    522   if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1) {
    523     EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
    524   } else {
    525     EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
    526     EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
    527   }
    528   EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
    529   if (!context.getCompilationDir().empty())
    530     EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
    531   StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
    532   if (!DwarfDebugFlags.empty())
    533     EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
    534   EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
    535   EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
    536   EmitAbbrev(MCOS, 0, 0);
    537 
    538   // DW_TAG_label DIE abbrev (2).
    539   MCOS->EmitULEB128IntValue(2);
    540   MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label);
    541   MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
    542   EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
    543   EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
    544   EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
    545   EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
    546   EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
    547   EmitAbbrev(MCOS, 0, 0);
    548 
    549   // DW_TAG_unspecified_parameters DIE abbrev (3).
    550   MCOS->EmitULEB128IntValue(3);
    551   MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters);
    552   MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1);
    553   EmitAbbrev(MCOS, 0, 0);
    554 
    555   // Terminate the abbreviations for this compilation unit.
    556   MCOS->EmitIntValue(0, 1);
    557 }
    558 
    559 // When generating dwarf for assembly source files this emits the data for
    560 // .debug_aranges section. This section contains a header and a table of pairs
    561 // of PointerSize'ed values for the address and size of section(s) with line
    562 // table entries.
    563 static void EmitGenDwarfAranges(MCStreamer *MCOS,
    564                                 const MCSymbol *InfoSectionSymbol) {
    565   MCContext &context = MCOS->getContext();
    566 
    567   auto &Sections = context.getGenDwarfSectionSyms();
    568 
    569   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
    570 
    571   // This will be the length of the .debug_aranges section, first account for
    572   // the size of each item in the header (see below where we emit these items).
    573   int Length = 4 + 2 + 4 + 1 + 1;
    574 
    575   // Figure the padding after the header before the table of address and size
    576   // pairs who's values are PointerSize'ed.
    577   const MCAsmInfo *asmInfo = context.getAsmInfo();
    578   int AddrSize = asmInfo->getPointerSize();
    579   int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
    580   if (Pad == 2 * AddrSize)
    581     Pad = 0;
    582   Length += Pad;
    583 
    584   // Add the size of the pair of PointerSize'ed values for the address and size
    585   // of each section we have in the table.
    586   Length += 2 * AddrSize * Sections.size();
    587   // And the pair of terminating zeros.
    588   Length += 2 * AddrSize;
    589 
    590 
    591   // Emit the header for this section.
    592   // The 4 byte length not including the 4 byte value for the length.
    593   MCOS->EmitIntValue(Length - 4, 4);
    594   // The 2 byte version, which is 2.
    595   MCOS->EmitIntValue(2, 2);
    596   // The 4 byte offset to the compile unit in the .debug_info from the start
    597   // of the .debug_info.
    598   if (InfoSectionSymbol)
    599     MCOS->EmitSymbolValue(InfoSectionSymbol, 4);
    600   else
    601     MCOS->EmitIntValue(0, 4);
    602   // The 1 byte size of an address.
    603   MCOS->EmitIntValue(AddrSize, 1);
    604   // The 1 byte size of a segment descriptor, we use a value of zero.
    605   MCOS->EmitIntValue(0, 1);
    606   // Align the header with the padding if needed, before we put out the table.
    607   for(int i = 0; i < Pad; i++)
    608     MCOS->EmitIntValue(0, 1);
    609 
    610   // Now emit the table of pairs of PointerSize'ed values for the section
    611   // addresses and sizes.
    612   for (const auto &sec : Sections) {
    613     MCSymbol *StartSymbol = sec.second.first;
    614     MCSymbol *EndSymbol = sec.second.second;
    615     assert(StartSymbol && "StartSymbol must not be NULL");
    616     assert(EndSymbol && "EndSymbol must not be NULL");
    617 
    618     const MCExpr *Addr = MCSymbolRefExpr::Create(
    619       StartSymbol, MCSymbolRefExpr::VK_None, context);
    620     const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
    621       *StartSymbol, *EndSymbol, 0);
    622     MCOS->EmitValue(Addr, AddrSize);
    623     MCOS->EmitAbsValue(Size, AddrSize);
    624   }
    625 
    626   // And finally the pair of terminating zeros.
    627   MCOS->EmitIntValue(0, AddrSize);
    628   MCOS->EmitIntValue(0, AddrSize);
    629 }
    630 
    631 // When generating dwarf for assembly source files this emits the data for
    632 // .debug_info section which contains three parts.  The header, the compile_unit
    633 // DIE and a list of label DIEs.
    634 static void EmitGenDwarfInfo(MCStreamer *MCOS,
    635                              const MCSymbol *AbbrevSectionSymbol,
    636                              const MCSymbol *LineSectionSymbol,
    637                              const MCSymbol *RangesSectionSymbol) {
    638   MCContext &context = MCOS->getContext();
    639 
    640   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
    641 
    642   // Create a symbol at the start and end of this section used in here for the
    643   // expression to calculate the length in the header.
    644   MCSymbol *InfoStart = context.CreateTempSymbol();
    645   MCOS->EmitLabel(InfoStart);
    646   MCSymbol *InfoEnd = context.CreateTempSymbol();
    647 
    648   // First part: the header.
    649 
    650   // The 4 byte total length of the information for this compilation unit, not
    651   // including these 4 bytes.
    652   const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
    653   MCOS->EmitAbsValue(Length, 4);
    654 
    655   // The 2 byte DWARF version.
    656   MCOS->EmitIntValue(context.getDwarfVersion(), 2);
    657 
    658   // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
    659   // it is at the start of that section so this is zero.
    660   if (AbbrevSectionSymbol) {
    661     MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
    662   } else {
    663     MCOS->EmitIntValue(0, 4);
    664   }
    665 
    666   const MCAsmInfo *asmInfo = context.getAsmInfo();
    667   int AddrSize = asmInfo->getPointerSize();
    668   // The 1 byte size of an address.
    669   MCOS->EmitIntValue(AddrSize, 1);
    670 
    671   // Second part: the compile_unit DIE.
    672 
    673   // The DW_TAG_compile_unit DIE abbrev (1).
    674   MCOS->EmitULEB128IntValue(1);
    675 
    676   // DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
    677   // which is at the start of that section so this is zero.
    678   if (LineSectionSymbol) {
    679     MCOS->EmitSymbolValue(LineSectionSymbol, 4);
    680   } else {
    681     MCOS->EmitIntValue(0, 4);
    682   }
    683 
    684   if (RangesSectionSymbol) {
    685     // There are multiple sections containing code, so we must use the
    686     // .debug_ranges sections.
    687 
    688     // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
    689     // to the address range list for this compilation unit.
    690     MCOS->EmitSymbolValue(RangesSectionSymbol, 4);
    691   } else {
    692     // If we only have one non-empty code section, we can use the simpler
    693     // AT_low_pc and AT_high_pc attributes.
    694 
    695     // Find the first (and only) non-empty text section
    696     auto &Sections = context.getGenDwarfSectionSyms();
    697     const auto TextSection = Sections.begin();
    698     assert(TextSection != Sections.end() && "No text section found");
    699 
    700     MCSymbol *StartSymbol = TextSection->second.first;
    701     MCSymbol *EndSymbol = TextSection->second.second;
    702     assert(StartSymbol && "StartSymbol must not be NULL");
    703     assert(EndSymbol && "EndSymbol must not be NULL");
    704 
    705     // AT_low_pc, the first address of the default .text section.
    706     const MCExpr *Start = MCSymbolRefExpr::Create(
    707         StartSymbol, MCSymbolRefExpr::VK_None, context);
    708     MCOS->EmitValue(Start, AddrSize);
    709 
    710     // AT_high_pc, the last address of the default .text section.
    711     const MCExpr *End = MCSymbolRefExpr::Create(
    712       EndSymbol, MCSymbolRefExpr::VK_None, context);
    713     MCOS->EmitValue(End, AddrSize);
    714   }
    715 
    716   // AT_name, the name of the source file.  Reconstruct from the first directory
    717   // and file table entries.
    718   const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
    719   if (MCDwarfDirs.size() > 0) {
    720     MCOS->EmitBytes(MCDwarfDirs[0]);
    721     MCOS->EmitBytes(sys::path::get_separator());
    722   }
    723   const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
    724     MCOS->getContext().getMCDwarfFiles();
    725   MCOS->EmitBytes(MCDwarfFiles[1].Name);
    726   MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
    727 
    728   // AT_comp_dir, the working directory the assembly was done in.
    729   if (!context.getCompilationDir().empty()) {
    730     MCOS->EmitBytes(context.getCompilationDir());
    731     MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
    732   }
    733 
    734   // AT_APPLE_flags, the command line arguments of the assembler tool.
    735   StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
    736   if (!DwarfDebugFlags.empty()){
    737     MCOS->EmitBytes(DwarfDebugFlags);
    738     MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
    739   }
    740 
    741   // AT_producer, the version of the assembler tool.
    742   StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
    743   if (!DwarfDebugProducer.empty()){
    744     MCOS->EmitBytes(DwarfDebugProducer);
    745   }
    746   else {
    747     MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
    748     MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
    749     MCOS->EmitBytes(StringRef(")"));
    750   }
    751   MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
    752 
    753   // AT_language, a 4 byte value.  We use DW_LANG_Mips_Assembler as the dwarf2
    754   // draft has no standard code for assembler.
    755   MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2);
    756 
    757   // Third part: the list of label DIEs.
    758 
    759   // Loop on saved info for dwarf labels and create the DIEs for them.
    760   const std::vector<MCGenDwarfLabelEntry> &Entries =
    761       MCOS->getContext().getMCGenDwarfLabelEntries();
    762   for (const auto &Entry : Entries) {
    763     // The DW_TAG_label DIE abbrev (2).
    764     MCOS->EmitULEB128IntValue(2);
    765 
    766     // AT_name, of the label without any leading underbar.
    767     MCOS->EmitBytes(Entry.getName());
    768     MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
    769 
    770     // AT_decl_file, index into the file table.
    771     MCOS->EmitIntValue(Entry.getFileNumber(), 4);
    772 
    773     // AT_decl_line, source line number.
    774     MCOS->EmitIntValue(Entry.getLineNumber(), 4);
    775 
    776     // AT_low_pc, start address of the label.
    777     const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry.getLabel(),
    778                                              MCSymbolRefExpr::VK_None, context);
    779     MCOS->EmitValue(AT_low_pc, AddrSize);
    780 
    781     // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
    782     MCOS->EmitIntValue(0, 1);
    783 
    784     // The DW_TAG_unspecified_parameters DIE abbrev (3).
    785     MCOS->EmitULEB128IntValue(3);
    786 
    787     // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
    788     MCOS->EmitIntValue(0, 1);
    789   }
    790 
    791   // Add the NULL DIE terminating the Compile Unit DIE's.
    792   MCOS->EmitIntValue(0, 1);
    793 
    794   // Now set the value of the symbol at the end of the info section.
    795   MCOS->EmitLabel(InfoEnd);
    796 }
    797 
    798 // When generating dwarf for assembly source files this emits the data for
    799 // .debug_ranges section. We only emit one range list, which spans all of the
    800 // executable sections of this file.
    801 static void EmitGenDwarfRanges(MCStreamer *MCOS) {
    802   MCContext &context = MCOS->getContext();
    803   auto &Sections = context.getGenDwarfSectionSyms();
    804 
    805   const MCAsmInfo *AsmInfo = context.getAsmInfo();
    806   int AddrSize = AsmInfo->getPointerSize();
    807 
    808   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
    809 
    810   for (const auto sec : Sections) {
    811 
    812     MCSymbol *StartSymbol = sec.second.first;
    813     MCSymbol *EndSymbol = sec.second.second;
    814     assert(StartSymbol && "StartSymbol must not be NULL");
    815     assert(EndSymbol && "EndSymbol must not be NULL");
    816 
    817     // Emit a base address selection entry for the start of this section
    818     const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create(
    819       StartSymbol, MCSymbolRefExpr::VK_None, context);
    820     MCOS->EmitFill(AddrSize, 0xFF);
    821     MCOS->EmitValue(SectionStartAddr, AddrSize);
    822 
    823     // Emit a range list entry spanning this section
    824     const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
    825       *StartSymbol, *EndSymbol, 0);
    826     MCOS->EmitIntValue(0, AddrSize);
    827     MCOS->EmitAbsValue(SectionSize, AddrSize);
    828   }
    829 
    830   // Emit end of list entry
    831   MCOS->EmitIntValue(0, AddrSize);
    832   MCOS->EmitIntValue(0, AddrSize);
    833 }
    834 
    835 //
    836 // When generating dwarf for assembly source files this emits the Dwarf
    837 // sections.
    838 //
    839 void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
    840   MCContext &context = MCOS->getContext();
    841 
    842   // Create the dwarf sections in this order (.debug_line already created).
    843   const MCAsmInfo *AsmInfo = context.getAsmInfo();
    844   bool CreateDwarfSectionSymbols =
    845       AsmInfo->doesDwarfUseRelocationsAcrossSections();
    846   MCSymbol *LineSectionSymbol = nullptr;
    847   if (CreateDwarfSectionSymbols)
    848     LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
    849   MCSymbol *AbbrevSectionSymbol = nullptr;
    850   MCSymbol *InfoSectionSymbol = nullptr;
    851   MCSymbol *RangesSectionSymbol = NULL;
    852 
    853   // Create end symbols for each section, and remove empty sections
    854   MCOS->getContext().finalizeDwarfSections(*MCOS);
    855 
    856   // If there are no sections to generate debug info for, we don't need
    857   // to do anything
    858   if (MCOS->getContext().getGenDwarfSectionSyms().empty())
    859     return;
    860 
    861   // We only need to use the .debug_ranges section if we have multiple
    862   // code sections.
    863   const bool UseRangesSection =
    864       MCOS->getContext().getGenDwarfSectionSyms().size() > 1;
    865   CreateDwarfSectionSymbols |= UseRangesSection;
    866 
    867   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
    868   if (CreateDwarfSectionSymbols) {
    869     InfoSectionSymbol = context.CreateTempSymbol();
    870     MCOS->EmitLabel(InfoSectionSymbol);
    871   }
    872   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
    873   if (CreateDwarfSectionSymbols) {
    874     AbbrevSectionSymbol = context.CreateTempSymbol();
    875     MCOS->EmitLabel(AbbrevSectionSymbol);
    876   }
    877   if (UseRangesSection) {
    878     MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
    879     if (CreateDwarfSectionSymbols) {
    880       RangesSectionSymbol = context.CreateTempSymbol();
    881       MCOS->EmitLabel(RangesSectionSymbol);
    882     }
    883   }
    884 
    885   assert((RangesSectionSymbol != NULL) || !UseRangesSection);
    886 
    887   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
    888 
    889   // Output the data for .debug_aranges section.
    890   EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
    891 
    892   if (UseRangesSection)
    893     EmitGenDwarfRanges(MCOS);
    894 
    895   // Output the data for .debug_abbrev section.
    896   EmitGenDwarfAbbrev(MCOS);
    897 
    898   // Output the data for .debug_info section.
    899   EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
    900                    RangesSectionSymbol);
    901 }
    902 
    903 //
    904 // When generating dwarf for assembly source files this is called when symbol
    905 // for a label is created.  If this symbol is not a temporary and is in the
    906 // section that dwarf is being generated for, save the needed info to create
    907 // a dwarf label.
    908 //
    909 void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
    910                                      SourceMgr &SrcMgr, SMLoc &Loc) {
    911   // We won't create dwarf labels for temporary symbols.
    912   if (Symbol->isTemporary())
    913     return;
    914   MCContext &context = MCOS->getContext();
    915   // We won't create dwarf labels for symbols in sections that we are not
    916   // generating debug info for.
    917   if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSection().first))
    918     return;
    919 
    920   // The dwarf label's name does not have the symbol name's leading
    921   // underbar if any.
    922   StringRef Name = Symbol->getName();
    923   if (Name.startswith("_"))
    924     Name = Name.substr(1, Name.size()-1);
    925 
    926   // Get the dwarf file number to be used for the dwarf label.
    927   unsigned FileNumber = context.getGenDwarfFileNumber();
    928 
    929   // Finding the line number is the expensive part which is why we just don't
    930   // pass it in as for some symbols we won't create a dwarf label.
    931   unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
    932   unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
    933 
    934   // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
    935   // values so that they don't have things like an ARM thumb bit from the
    936   // original symbol. So when used they won't get a low bit set after
    937   // relocation.
    938   MCSymbol *Label = context.CreateTempSymbol();
    939   MCOS->EmitLabel(Label);
    940 
    941   // Create and entry for the info and add it to the other entries.
    942   MCOS->getContext().addMCGenDwarfLabelEntry(
    943       MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
    944 }
    945 
    946 static int getDataAlignmentFactor(MCStreamer &streamer) {
    947   MCContext &context = streamer.getContext();
    948   const MCAsmInfo *asmInfo = context.getAsmInfo();
    949   int size = asmInfo->getCalleeSaveStackSlotSize();
    950   if (asmInfo->isStackGrowthDirectionUp())
    951     return size;
    952   else
    953     return -size;
    954 }
    955 
    956 static unsigned getSizeForEncoding(MCStreamer &streamer,
    957                                    unsigned symbolEncoding) {
    958   MCContext &context = streamer.getContext();
    959   unsigned format = symbolEncoding & 0x0f;
    960   switch (format) {
    961   default: llvm_unreachable("Unknown Encoding");
    962   case dwarf::DW_EH_PE_absptr:
    963   case dwarf::DW_EH_PE_signed:
    964     return context.getAsmInfo()->getPointerSize();
    965   case dwarf::DW_EH_PE_udata2:
    966   case dwarf::DW_EH_PE_sdata2:
    967     return 2;
    968   case dwarf::DW_EH_PE_udata4:
    969   case dwarf::DW_EH_PE_sdata4:
    970     return 4;
    971   case dwarf::DW_EH_PE_udata8:
    972   case dwarf::DW_EH_PE_sdata8:
    973     return 8;
    974   }
    975 }
    976 
    977 static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol,
    978                        unsigned symbolEncoding, bool isEH,
    979                        const char *comment = nullptr) {
    980   MCContext &context = streamer.getContext();
    981   const MCAsmInfo *asmInfo = context.getAsmInfo();
    982   const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
    983                                                  symbolEncoding,
    984                                                  streamer);
    985   unsigned size = getSizeForEncoding(streamer, symbolEncoding);
    986   if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment);
    987   if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
    988     streamer.EmitAbsValue(v, size);
    989   else
    990     streamer.EmitValue(v, size);
    991 }
    992 
    993 static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
    994                             unsigned symbolEncoding) {
    995   MCContext &context = streamer.getContext();
    996   const MCAsmInfo *asmInfo = context.getAsmInfo();
    997   const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
    998                                                          symbolEncoding,
    999                                                          streamer);
   1000   unsigned size = getSizeForEncoding(streamer, symbolEncoding);
   1001   streamer.EmitValue(v, size);
   1002 }
   1003 
   1004 namespace {
   1005   class FrameEmitterImpl {
   1006     int CFAOffset;
   1007     int CIENum;
   1008     bool IsEH;
   1009     const MCSymbol *SectionStart;
   1010   public:
   1011     FrameEmitterImpl(bool isEH)
   1012         : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {}
   1013 
   1014     void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
   1015 
   1016     /// EmitCompactUnwind - Emit the unwind information in a compact way.
   1017     void EmitCompactUnwind(MCStreamer &streamer,
   1018                            const MCDwarfFrameInfo &frame);
   1019 
   1020     const MCSymbol &EmitCIE(MCObjectStreamer &streamer,
   1021                             const MCSymbol *personality,
   1022                             unsigned personalityEncoding,
   1023                             const MCSymbol *lsda,
   1024                             bool IsSignalFrame,
   1025                             unsigned lsdaEncoding,
   1026                             bool IsSimple);
   1027     MCSymbol *EmitFDE(MCObjectStreamer &streamer,
   1028                       const MCSymbol &cieStart,
   1029                       const MCDwarfFrameInfo &frame);
   1030     void EmitCFIInstructions(MCObjectStreamer &streamer,
   1031                              ArrayRef<MCCFIInstruction> Instrs,
   1032                              MCSymbol *BaseLabel);
   1033     void EmitCFIInstruction(MCObjectStreamer &Streamer,
   1034                             const MCCFIInstruction &Instr);
   1035   };
   1036 
   1037 } // end anonymous namespace
   1038 
   1039 static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
   1040                              StringRef Prefix) {
   1041   if (Streamer.isVerboseAsm()) {
   1042     const char *EncStr;
   1043     switch (Encoding) {
   1044     default: EncStr = "<unknown encoding>"; break;
   1045     case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break;
   1046     case dwarf::DW_EH_PE_omit:   EncStr = "omit"; break;
   1047     case dwarf::DW_EH_PE_pcrel:  EncStr = "pcrel"; break;
   1048     case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break;
   1049     case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break;
   1050     case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break;
   1051     case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break;
   1052     case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
   1053       EncStr = "pcrel udata4";
   1054       break;
   1055     case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
   1056       EncStr = "pcrel sdata4";
   1057       break;
   1058     case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
   1059       EncStr = "pcrel udata8";
   1060       break;
   1061     case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
   1062       EncStr = "screl sdata8";
   1063       break;
   1064     case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4:
   1065       EncStr = "indirect pcrel udata4";
   1066       break;
   1067     case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4:
   1068       EncStr = "indirect pcrel sdata4";
   1069       break;
   1070     case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8:
   1071       EncStr = "indirect pcrel udata8";
   1072       break;
   1073     case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8:
   1074       EncStr = "indirect pcrel sdata8";
   1075       break;
   1076     }
   1077 
   1078     Streamer.AddComment(Twine(Prefix) + " = " + EncStr);
   1079   }
   1080 
   1081   Streamer.EmitIntValue(Encoding, 1);
   1082 }
   1083 
   1084 void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
   1085                                           const MCCFIInstruction &Instr) {
   1086   int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
   1087   bool VerboseAsm = Streamer.isVerboseAsm();
   1088 
   1089   switch (Instr.getOperation()) {
   1090   case MCCFIInstruction::OpRegister: {
   1091     unsigned Reg1 = Instr.getRegister();
   1092     unsigned Reg2 = Instr.getRegister2();
   1093     if (VerboseAsm) {
   1094       Streamer.AddComment("DW_CFA_register");
   1095       Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1));
   1096       Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2));
   1097     }
   1098     Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
   1099     Streamer.EmitULEB128IntValue(Reg1);
   1100     Streamer.EmitULEB128IntValue(Reg2);
   1101     return;
   1102   }
   1103   case MCCFIInstruction::OpWindowSave: {
   1104     Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
   1105     return;
   1106   }
   1107   case MCCFIInstruction::OpUndefined: {
   1108     unsigned Reg = Instr.getRegister();
   1109     if (VerboseAsm) {
   1110       Streamer.AddComment("DW_CFA_undefined");
   1111       Streamer.AddComment(Twine("Reg ") + Twine(Reg));
   1112     }
   1113     Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
   1114     Streamer.EmitULEB128IntValue(Reg);
   1115     return;
   1116   }
   1117   case MCCFIInstruction::OpAdjustCfaOffset:
   1118   case MCCFIInstruction::OpDefCfaOffset: {
   1119     const bool IsRelative =
   1120       Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;
   1121 
   1122     if (VerboseAsm)
   1123       Streamer.AddComment("DW_CFA_def_cfa_offset");
   1124     Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
   1125 
   1126     if (IsRelative)
   1127       CFAOffset += Instr.getOffset();
   1128     else
   1129       CFAOffset = -Instr.getOffset();
   1130 
   1131     if (VerboseAsm)
   1132       Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
   1133     Streamer.EmitULEB128IntValue(CFAOffset);
   1134 
   1135     return;
   1136   }
   1137   case MCCFIInstruction::OpDefCfa: {
   1138     if (VerboseAsm)
   1139       Streamer.AddComment("DW_CFA_def_cfa");
   1140     Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
   1141 
   1142     if (VerboseAsm)
   1143       Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
   1144     Streamer.EmitULEB128IntValue(Instr.getRegister());
   1145 
   1146     CFAOffset = -Instr.getOffset();
   1147 
   1148     if (VerboseAsm)
   1149       Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
   1150     Streamer.EmitULEB128IntValue(CFAOffset);
   1151 
   1152     return;
   1153   }
   1154 
   1155   case MCCFIInstruction::OpDefCfaRegister: {
   1156     if (VerboseAsm)
   1157       Streamer.AddComment("DW_CFA_def_cfa_register");
   1158     Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
   1159 
   1160     if (VerboseAsm)
   1161       Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
   1162     Streamer.EmitULEB128IntValue(Instr.getRegister());
   1163 
   1164     return;
   1165   }
   1166 
   1167   case MCCFIInstruction::OpOffset:
   1168   case MCCFIInstruction::OpRelOffset: {
   1169     const bool IsRelative =
   1170       Instr.getOperation() == MCCFIInstruction::OpRelOffset;
   1171 
   1172     unsigned Reg = Instr.getRegister();
   1173     int Offset = Instr.getOffset();
   1174     if (IsRelative)
   1175       Offset -= CFAOffset;
   1176     Offset = Offset / dataAlignmentFactor;
   1177 
   1178     if (Offset < 0) {
   1179       if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
   1180       Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
   1181       if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
   1182       Streamer.EmitULEB128IntValue(Reg);
   1183       if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
   1184       Streamer.EmitSLEB128IntValue(Offset);
   1185     } else if (Reg < 64) {
   1186       if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
   1187                                           Twine(Reg) + ")");
   1188       Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
   1189       if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
   1190       Streamer.EmitULEB128IntValue(Offset);
   1191     } else {
   1192       if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
   1193       Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
   1194       if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
   1195       Streamer.EmitULEB128IntValue(Reg);
   1196       if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
   1197       Streamer.EmitULEB128IntValue(Offset);
   1198     }
   1199     return;
   1200   }
   1201   case MCCFIInstruction::OpRememberState:
   1202     if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
   1203     Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
   1204     return;
   1205   case MCCFIInstruction::OpRestoreState:
   1206     if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
   1207     Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
   1208     return;
   1209   case MCCFIInstruction::OpSameValue: {
   1210     unsigned Reg = Instr.getRegister();
   1211     if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
   1212     Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
   1213     if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
   1214     Streamer.EmitULEB128IntValue(Reg);
   1215     return;
   1216   }
   1217   case MCCFIInstruction::OpRestore: {
   1218     unsigned Reg = Instr.getRegister();
   1219     if (VerboseAsm) {
   1220       Streamer.AddComment("DW_CFA_restore");
   1221       Streamer.AddComment(Twine("Reg ") + Twine(Reg));
   1222     }
   1223     Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
   1224     return;
   1225   }
   1226   case MCCFIInstruction::OpEscape:
   1227     if (VerboseAsm) Streamer.AddComment("Escape bytes");
   1228     Streamer.EmitBytes(Instr.getValues());
   1229     return;
   1230   }
   1231   llvm_unreachable("Unhandled case in switch");
   1232 }
   1233 
   1234 /// EmitFrameMoves - Emit frame instructions to describe the layout of the
   1235 /// frame.
   1236 void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer,
   1237                                            ArrayRef<MCCFIInstruction> Instrs,
   1238                                            MCSymbol *BaseLabel) {
   1239   for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
   1240     const MCCFIInstruction &Instr = Instrs[i];
   1241     MCSymbol *Label = Instr.getLabel();
   1242     // Throw out move if the label is invalid.
   1243     if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
   1244 
   1245     // Advance row if new location.
   1246     if (BaseLabel && Label) {
   1247       MCSymbol *ThisSym = Label;
   1248       if (ThisSym != BaseLabel) {
   1249         if (streamer.isVerboseAsm()) streamer.AddComment("DW_CFA_advance_loc4");
   1250         streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
   1251         BaseLabel = ThisSym;
   1252       }
   1253     }
   1254 
   1255     EmitCFIInstruction(streamer, Instr);
   1256   }
   1257 }
   1258 
   1259 /// EmitCompactUnwind - Emit the unwind information in a compact way.
   1260 void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
   1261                                          const MCDwarfFrameInfo &Frame) {
   1262   MCContext &Context = Streamer.getContext();
   1263   const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
   1264   bool VerboseAsm = Streamer.isVerboseAsm();
   1265 
   1266   // range-start range-length  compact-unwind-enc personality-func   lsda
   1267   //  _foo       LfooEnd-_foo  0x00000023          0                 0
   1268   //  _bar       LbarEnd-_bar  0x00000025         __gxx_personality  except_tab1
   1269   //
   1270   //   .section __LD,__compact_unwind,regular,debug
   1271   //
   1272   //   # compact unwind for _foo
   1273   //   .quad _foo
   1274   //   .set L1,LfooEnd-_foo
   1275   //   .long L1
   1276   //   .long 0x01010001
   1277   //   .quad 0
   1278   //   .quad 0
   1279   //
   1280   //   # compact unwind for _bar
   1281   //   .quad _bar
   1282   //   .set L2,LbarEnd-_bar
   1283   //   .long L2
   1284   //   .long 0x01020011
   1285   //   .quad __gxx_personality
   1286   //   .quad except_tab1
   1287 
   1288   uint32_t Encoding = Frame.CompactUnwindEncoding;
   1289   if (!Encoding) return;
   1290   bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
   1291 
   1292   // The encoding needs to know we have an LSDA.
   1293   if (!DwarfEHFrameOnly && Frame.Lsda)
   1294     Encoding |= 0x40000000;
   1295 
   1296   // Range Start
   1297   unsigned FDEEncoding = MOFI->getFDEEncoding();
   1298   unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
   1299   if (VerboseAsm) Streamer.AddComment("Range Start");
   1300   Streamer.EmitSymbolValue(Frame.Begin, Size);
   1301 
   1302   // Range Length
   1303   const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
   1304                                               *Frame.End, 0);
   1305   if (VerboseAsm) Streamer.AddComment("Range Length");
   1306   Streamer.EmitAbsValue(Range, 4);
   1307 
   1308   // Compact Encoding
   1309   Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
   1310   if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" +
   1311                                       Twine::utohexstr(Encoding));
   1312   Streamer.EmitIntValue(Encoding, Size);
   1313 
   1314   // Personality Function
   1315   Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr);
   1316   if (VerboseAsm) Streamer.AddComment("Personality Function");
   1317   if (!DwarfEHFrameOnly && Frame.Personality)
   1318     Streamer.EmitSymbolValue(Frame.Personality, Size);
   1319   else
   1320     Streamer.EmitIntValue(0, Size); // No personality fn
   1321 
   1322   // LSDA
   1323   Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
   1324   if (VerboseAsm) Streamer.AddComment("LSDA");
   1325   if (!DwarfEHFrameOnly && Frame.Lsda)
   1326     Streamer.EmitSymbolValue(Frame.Lsda, Size);
   1327   else
   1328     Streamer.EmitIntValue(0, Size); // No LSDA
   1329 }
   1330 
   1331 const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
   1332                                           const MCSymbol *personality,
   1333                                           unsigned personalityEncoding,
   1334                                           const MCSymbol *lsda,
   1335                                           bool IsSignalFrame,
   1336                                           unsigned lsdaEncoding,
   1337                                           bool IsSimple) {
   1338   MCContext &context = streamer.getContext();
   1339   const MCRegisterInfo *MRI = context.getRegisterInfo();
   1340   const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
   1341   bool verboseAsm = streamer.isVerboseAsm();
   1342 
   1343   MCSymbol *sectionStart = context.CreateTempSymbol();
   1344   streamer.EmitLabel(sectionStart);
   1345   CIENum++;
   1346 
   1347   MCSymbol *sectionEnd = context.CreateTempSymbol();
   1348 
   1349   // Length
   1350   const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
   1351                                                *sectionEnd, 4);
   1352   if (verboseAsm) streamer.AddComment("CIE Length");
   1353   streamer.EmitAbsValue(Length, 4);
   1354 
   1355   // CIE ID
   1356   unsigned CIE_ID = IsEH ? 0 : -1;
   1357   if (verboseAsm) streamer.AddComment("CIE ID Tag");
   1358   streamer.EmitIntValue(CIE_ID, 4);
   1359 
   1360   // Version
   1361   if (verboseAsm) streamer.AddComment("DW_CIE_VERSION");
   1362   // For DWARF2, we use CIE version 1
   1363   // For DWARF3+, we use CIE version 3
   1364   uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3;
   1365   streamer.EmitIntValue(CIEVersion, 1);
   1366 
   1367   // Augmentation String
   1368   SmallString<8> Augmentation;
   1369   if (IsEH) {
   1370     if (verboseAsm) streamer.AddComment("CIE Augmentation");
   1371     Augmentation += "z";
   1372     if (personality)
   1373       Augmentation += "P";
   1374     if (lsda)
   1375       Augmentation += "L";
   1376     Augmentation += "R";
   1377     if (IsSignalFrame)
   1378       Augmentation += "S";
   1379     streamer.EmitBytes(Augmentation.str());
   1380   }
   1381   streamer.EmitIntValue(0, 1);
   1382 
   1383   // Code Alignment Factor
   1384   if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor");
   1385   streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
   1386 
   1387   // Data Alignment Factor
   1388   if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor");
   1389   streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer));
   1390 
   1391   // Return Address Register
   1392   if (verboseAsm) streamer.AddComment("CIE Return Address Column");
   1393   if (CIEVersion == 1) {
   1394     assert(MRI->getRARegister() <= 255 &&
   1395            "DWARF 2 encodes return_address_register in one byte");
   1396     streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1);
   1397   } else {
   1398     streamer.EmitULEB128IntValue(
   1399         MRI->getDwarfRegNum(MRI->getRARegister(), true));
   1400   }
   1401 
   1402   // Augmentation Data Length (optional)
   1403 
   1404   unsigned augmentationLength = 0;
   1405   if (IsEH) {
   1406     if (personality) {
   1407       // Personality Encoding
   1408       augmentationLength += 1;
   1409       // Personality
   1410       augmentationLength += getSizeForEncoding(streamer, personalityEncoding);
   1411     }
   1412     if (lsda)
   1413       augmentationLength += 1;
   1414     // Encoding of the FDE pointers
   1415     augmentationLength += 1;
   1416 
   1417     if (verboseAsm) streamer.AddComment("Augmentation Size");
   1418     streamer.EmitULEB128IntValue(augmentationLength);
   1419 
   1420     // Augmentation Data (optional)
   1421     if (personality) {
   1422       // Personality Encoding
   1423       EmitEncodingByte(streamer, personalityEncoding,
   1424                        "Personality Encoding");
   1425       // Personality
   1426       if (verboseAsm) streamer.AddComment("Personality");
   1427       EmitPersonality(streamer, *personality, personalityEncoding);
   1428     }
   1429 
   1430     if (lsda)
   1431       EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding");
   1432 
   1433     // Encoding of the FDE pointers
   1434     EmitEncodingByte(streamer, MOFI->getFDEEncoding(), "FDE Encoding");
   1435   }
   1436 
   1437   // Initial Instructions
   1438 
   1439   const MCAsmInfo *MAI = context.getAsmInfo();
   1440   if (!IsSimple) {
   1441     const std::vector<MCCFIInstruction> &Instructions =
   1442         MAI->getInitialFrameState();
   1443     EmitCFIInstructions(streamer, Instructions, nullptr);
   1444   }
   1445 
   1446   // Padding
   1447   streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());
   1448 
   1449   streamer.EmitLabel(sectionEnd);
   1450   return *sectionStart;
   1451 }
   1452 
   1453 MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
   1454                                     const MCSymbol &cieStart,
   1455                                     const MCDwarfFrameInfo &frame) {
   1456   MCContext &context = streamer.getContext();
   1457   MCSymbol *fdeStart = context.CreateTempSymbol();
   1458   MCSymbol *fdeEnd = context.CreateTempSymbol();
   1459   const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
   1460   bool verboseAsm = streamer.isVerboseAsm();
   1461 
   1462   // Length
   1463   const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
   1464   if (verboseAsm) streamer.AddComment("FDE Length");
   1465   streamer.EmitAbsValue(Length, 4);
   1466 
   1467   streamer.EmitLabel(fdeStart);
   1468 
   1469   // CIE Pointer
   1470   const MCAsmInfo *asmInfo = context.getAsmInfo();
   1471   if (IsEH) {
   1472     const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
   1473                                                  0);
   1474     if (verboseAsm) streamer.AddComment("FDE CIE Offset");
   1475     streamer.EmitAbsValue(offset, 4);
   1476   } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
   1477     const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
   1478                                                  cieStart, 0);
   1479     streamer.EmitAbsValue(offset, 4);
   1480   } else {
   1481     streamer.EmitSymbolValue(&cieStart, 4);
   1482   }
   1483 
   1484   // PC Begin
   1485   unsigned PCEncoding =
   1486       IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
   1487   unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
   1488   EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location");
   1489 
   1490   // PC Range
   1491   const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
   1492                                               *frame.End, 0);
   1493   if (verboseAsm) streamer.AddComment("FDE address range");
   1494   streamer.EmitAbsValue(Range, PCSize);
   1495 
   1496   if (IsEH) {
   1497     // Augmentation Data Length
   1498     unsigned augmentationLength = 0;
   1499 
   1500     if (frame.Lsda)
   1501       augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);
   1502 
   1503     if (verboseAsm) streamer.AddComment("Augmentation size");
   1504     streamer.EmitULEB128IntValue(augmentationLength);
   1505 
   1506     // Augmentation Data
   1507     if (frame.Lsda)
   1508       EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true,
   1509                     "Language Specific Data Area");
   1510   }
   1511 
   1512   // Call Frame Instructions
   1513   EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
   1514 
   1515   // Padding
   1516   streamer.EmitValueToAlignment(PCSize);
   1517 
   1518   return fdeEnd;
   1519 }
   1520 
   1521 namespace {
   1522   struct CIEKey {
   1523     static const CIEKey getEmptyKey() {
   1524       return CIEKey(nullptr, 0, -1, false, false);
   1525     }
   1526     static const CIEKey getTombstoneKey() {
   1527       return CIEKey(nullptr, -1, 0, false, false);
   1528     }
   1529 
   1530     CIEKey(const MCSymbol *Personality_, unsigned PersonalityEncoding_,
   1531            unsigned LsdaEncoding_, bool IsSignalFrame_, bool IsSimple_)
   1532         : Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
   1533           LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_),
   1534           IsSimple(IsSimple_) {}
   1535     const MCSymbol *Personality;
   1536     unsigned PersonalityEncoding;
   1537     unsigned LsdaEncoding;
   1538     bool IsSignalFrame;
   1539     bool IsSimple;
   1540   };
   1541 }
   1542 
   1543 namespace llvm {
   1544   template <>
   1545   struct DenseMapInfo<CIEKey> {
   1546     static CIEKey getEmptyKey() {
   1547       return CIEKey::getEmptyKey();
   1548     }
   1549     static CIEKey getTombstoneKey() {
   1550       return CIEKey::getTombstoneKey();
   1551     }
   1552     static unsigned getHashValue(const CIEKey &Key) {
   1553       return static_cast<unsigned>(hash_combine(Key.Personality,
   1554                                                 Key.PersonalityEncoding,
   1555                                                 Key.LsdaEncoding,
   1556                                                 Key.IsSignalFrame,
   1557                                                 Key.IsSimple));
   1558     }
   1559     static bool isEqual(const CIEKey &LHS,
   1560                         const CIEKey &RHS) {
   1561       return LHS.Personality == RHS.Personality &&
   1562         LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
   1563         LHS.LsdaEncoding == RHS.LsdaEncoding &&
   1564         LHS.IsSignalFrame == RHS.IsSignalFrame &&
   1565         LHS.IsSimple == RHS.IsSimple;
   1566     }
   1567   };
   1568 }
   1569 
   1570 void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
   1571                                bool IsEH) {
   1572   Streamer.generateCompactUnwindEncodings(MAB);
   1573 
   1574   MCContext &Context = Streamer.getContext();
   1575   const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
   1576   FrameEmitterImpl Emitter(IsEH);
   1577   ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
   1578 
   1579   // Emit the compact unwind info if available.
   1580   bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
   1581   if (IsEH && MOFI->getCompactUnwindSection()) {
   1582     bool SectionEmitted = false;
   1583     for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
   1584       const MCDwarfFrameInfo &Frame = FrameArray[i];
   1585       if (Frame.CompactUnwindEncoding == 0) continue;
   1586       if (!SectionEmitted) {
   1587         Streamer.SwitchSection(MOFI->getCompactUnwindSection());
   1588         Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
   1589         SectionEmitted = true;
   1590       }
   1591       NeedsEHFrameSection |=
   1592         Frame.CompactUnwindEncoding ==
   1593           MOFI->getCompactUnwindDwarfEHFrameOnly();
   1594       Emitter.EmitCompactUnwind(Streamer, Frame);
   1595     }
   1596   }
   1597 
   1598   if (!NeedsEHFrameSection) return;
   1599 
   1600   const MCSection &Section =
   1601     IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
   1602            *MOFI->getDwarfFrameSection();
   1603 
   1604   Streamer.SwitchSection(&Section);
   1605   MCSymbol *SectionStart = Context.CreateTempSymbol();
   1606   Streamer.EmitLabel(SectionStart);
   1607   Emitter.setSectionStart(SectionStart);
   1608 
   1609   MCSymbol *FDEEnd = nullptr;
   1610   DenseMap<CIEKey, const MCSymbol *> CIEStarts;
   1611 
   1612   const MCSymbol *DummyDebugKey = nullptr;
   1613   NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
   1614   for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
   1615     const MCDwarfFrameInfo &Frame = FrameArray[i];
   1616 
   1617     // Emit the label from the previous iteration
   1618     if (FDEEnd) {
   1619       Streamer.EmitLabel(FDEEnd);
   1620       FDEEnd = nullptr;
   1621     }
   1622 
   1623     if (!NeedsEHFrameSection && Frame.CompactUnwindEncoding !=
   1624           MOFI->getCompactUnwindDwarfEHFrameOnly())
   1625       // Don't generate an EH frame if we don't need one. I.e., it's taken care
   1626       // of by the compact unwind encoding.
   1627       continue;
   1628 
   1629     CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
   1630                Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
   1631     const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
   1632     if (!CIEStart)
   1633       CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
   1634                                   Frame.PersonalityEncoding, Frame.Lsda,
   1635                                   Frame.IsSignalFrame,
   1636                                   Frame.LsdaEncoding,
   1637                                   Frame.IsSimple);
   1638 
   1639     FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
   1640   }
   1641 
   1642   Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
   1643   if (FDEEnd)
   1644     Streamer.EmitLabel(FDEEnd);
   1645 }
   1646 
   1647 void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer,
   1648                                          uint64_t AddrDelta) {
   1649   MCContext &Context = Streamer.getContext();
   1650   SmallString<256> Tmp;
   1651   raw_svector_ostream OS(Tmp);
   1652   MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS);
   1653   Streamer.EmitBytes(OS.str());
   1654 }
   1655 
   1656 void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context,
   1657                                            uint64_t AddrDelta,
   1658                                            raw_ostream &OS) {
   1659   // Scale the address delta by the minimum instruction length.
   1660   AddrDelta = ScaleAddrDelta(Context, AddrDelta);
   1661 
   1662   if (AddrDelta == 0) {
   1663   } else if (isUIntN(6, AddrDelta)) {
   1664     uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
   1665     OS << Opcode;
   1666   } else if (isUInt<8>(AddrDelta)) {
   1667     OS << uint8_t(dwarf::DW_CFA_advance_loc1);
   1668     OS << uint8_t(AddrDelta);
   1669   } else if (isUInt<16>(AddrDelta)) {
   1670     // FIXME: check what is the correct behavior on a big endian machine.
   1671     OS << uint8_t(dwarf::DW_CFA_advance_loc2);
   1672     OS << uint8_t( AddrDelta       & 0xff);
   1673     OS << uint8_t((AddrDelta >> 8) & 0xff);
   1674   } else {
   1675     // FIXME: check what is the correct behavior on a big endian machine.
   1676     assert(isUInt<32>(AddrDelta));
   1677     OS << uint8_t(dwarf::DW_CFA_advance_loc4);
   1678     OS << uint8_t( AddrDelta        & 0xff);
   1679     OS << uint8_t((AddrDelta >> 8)  & 0xff);
   1680     OS << uint8_t((AddrDelta >> 16) & 0xff);
   1681     OS << uint8_t((AddrDelta >> 24) & 0xff);
   1682 
   1683   }
   1684 }
   1685