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

Generated by: LCOV version 1.13