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

Generated by: LCOV version 1.13