LCOV - code coverage report
Current view: top level - lib/MC - MCDwarf.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 754 775 97.3 %
Date: 2018-07-13 00:08:38 Functions: 40 41 97.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13