Home | History | Annotate | Line # | Download | only in DWARFLinker
      1 //===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_DWARFLINKER_DWARFSTREAMER_H
     10 #define LLVM_DWARFLINKER_DWARFSTREAMER_H
     11 
     12 #include "llvm/CodeGen/AccelTable.h"
     13 #include "llvm/CodeGen/AsmPrinter.h"
     14 #include "llvm/DWARFLinker/DWARFLinker.h"
     15 #include "llvm/MC/MCAsmInfo.h"
     16 #include "llvm/MC/MCContext.h"
     17 #include "llvm/MC/MCInstrInfo.h"
     18 #include "llvm/MC/MCObjectFileInfo.h"
     19 #include "llvm/MC/MCRegisterInfo.h"
     20 #include "llvm/Target/TargetMachine.h"
     21 
     22 namespace llvm {
     23 
     24 enum class OutputFileType {
     25   Object,
     26   Assembly,
     27 };
     28 
     29 ///   User of DwarfStreamer should call initialization code
     30 ///   for AsmPrinter:
     31 ///
     32 ///   InitializeAllTargetInfos();
     33 ///   InitializeAllTargetMCs();
     34 ///   InitializeAllTargets();
     35 ///   InitializeAllAsmPrinters();
     36 
     37 class MCCodeEmitter;
     38 
     39 /// The Dwarf streaming logic.
     40 ///
     41 /// All interactions with the MC layer that is used to build the debug
     42 /// information binary representation are handled in this class.
     43 class DwarfStreamer : public DwarfEmitter {
     44 public:
     45   DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
     46                 std::function<StringRef(StringRef Input)> Translator,
     47                 messageHandler Error, messageHandler Warning)
     48       : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
     49         ErrorHandler(Error), WarningHandler(Warning) {}
     50 
     51   bool init(Triple TheTriple);
     52 
     53   /// Dump the file to the disk.
     54   void finish();
     55 
     56   AsmPrinter &getAsmPrinter() const { return *Asm; }
     57 
     58   /// Set the current output section to debug_info and change
     59   /// the MC Dwarf version to \p DwarfVersion.
     60   void switchToDebugInfoSection(unsigned DwarfVersion);
     61 
     62   /// Emit the compilation unit header for \p Unit in the
     63   /// debug_info section.
     64   ///
     65   /// As a side effect, this also switches the current Dwarf version
     66   /// of the MC layer to the one of U.getOrigUnit().
     67   void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
     68 
     69   /// Recursively emit the DIE tree rooted at \p Die.
     70   void emitDIE(DIE &Die) override;
     71 
     72   /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
     73   void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
     74                    unsigned DwarfVersion) override;
     75 
     76   /// Emit DIE containing warnings.
     77   void emitPaperTrailWarningsDie(DIE &Die) override;
     78 
     79   /// Emit contents of section SecName From Obj.
     80   void emitSectionContents(StringRef SecData, StringRef SecName) override;
     81 
     82   /// Emit the string table described by \p Pool.
     83   void emitStrings(const NonRelocatableStringpool &Pool) override;
     84 
     85   /// Emit the swift_ast section stored in \p Buffer.
     86   void emitSwiftAST(StringRef Buffer);
     87 
     88   /// Emit debug_ranges for \p FuncRange by translating the
     89   /// original \p Entries.
     90   void emitRangesEntries(
     91       int64_t UnitPcOffset, uint64_t OrigLowPc,
     92       const FunctionIntervals::const_iterator &FuncRange,
     93       const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
     94       unsigned AddressSize) override;
     95 
     96   /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
     97   /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
     98   /// DW_AT_ranges attribute.
     99   void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override;
    100 
    101   uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
    102 
    103   /// Emit the debug_loc contribution for \p Unit by copying the entries from
    104   /// \p Dwarf and offsetting them. Update the location attributes to point to
    105   /// the new entries.
    106   void emitLocationsForUnit(
    107       const CompileUnit &Unit, DWARFContext &Dwarf,
    108       std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr)
    109       override;
    110 
    111   /// Emit the line table described in \p Rows into the debug_line section.
    112   void emitLineTableForUnit(MCDwarfLineTableParams Params,
    113                             StringRef PrologueBytes, unsigned MinInstLength,
    114                             std::vector<DWARFDebugLine::Row> &Rows,
    115                             unsigned AdddressSize) override;
    116 
    117   /// Copy the debug_line over to the updated binary while unobfuscating the
    118   /// file names and directories.
    119   void translateLineTable(DataExtractor LineData, uint64_t Offset) override;
    120 
    121   uint64_t getLineSectionSize() const override { return LineSectionSize; }
    122 
    123   /// Emit the .debug_pubnames contribution for \p Unit.
    124   void emitPubNamesForUnit(const CompileUnit &Unit) override;
    125 
    126   /// Emit the .debug_pubtypes contribution for \p Unit.
    127   void emitPubTypesForUnit(const CompileUnit &Unit) override;
    128 
    129   /// Emit a CIE.
    130   void emitCIE(StringRef CIEBytes) override;
    131 
    132   /// Emit an FDE with data \p Bytes.
    133   void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
    134                StringRef Bytes) override;
    135 
    136   /// Emit DWARF debug names.
    137   void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override;
    138 
    139   /// Emit Apple namespaces accelerator table.
    140   void emitAppleNamespaces(
    141       AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
    142 
    143   /// Emit Apple names accelerator table.
    144   void
    145   emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
    146 
    147   /// Emit Apple Objective-C accelerator table.
    148   void
    149   emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
    150 
    151   /// Emit Apple type accelerator table.
    152   void
    153   emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
    154 
    155   uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
    156 
    157   uint64_t getDebugInfoSectionSize() const override {
    158     return DebugInfoSectionSize;
    159   }
    160 
    161 private:
    162   inline void error(const Twine &Error, StringRef Context = "") {
    163     if (ErrorHandler)
    164       ErrorHandler(Error, Context, nullptr);
    165   }
    166 
    167   inline void warn(const Twine &Warning, StringRef Context = "") {
    168     if (WarningHandler)
    169       WarningHandler(Warning, Context, nullptr);
    170   }
    171 
    172   /// \defgroup MCObjects MC layer objects constructed by the streamer
    173   /// @{
    174   std::unique_ptr<MCRegisterInfo> MRI;
    175   std::unique_ptr<MCAsmInfo> MAI;
    176   std::unique_ptr<MCObjectFileInfo> MOFI;
    177   std::unique_ptr<MCContext> MC;
    178   MCAsmBackend *MAB; // Owned by MCStreamer
    179   std::unique_ptr<MCInstrInfo> MII;
    180   std::unique_ptr<MCSubtargetInfo> MSTI;
    181   MCInstPrinter *MIP; // Owned by AsmPrinter
    182   MCCodeEmitter *MCE; // Owned by MCStreamer
    183   MCStreamer *MS;     // Owned by AsmPrinter
    184   std::unique_ptr<TargetMachine> TM;
    185   std::unique_ptr<AsmPrinter> Asm;
    186   /// @}
    187 
    188   /// The output file we stream the linked Dwarf to.
    189   raw_pwrite_stream &OutFile;
    190   OutputFileType OutFileType = OutputFileType::Object;
    191   std::function<StringRef(StringRef Input)> Translator;
    192 
    193   uint64_t RangesSectionSize = 0;
    194   uint64_t LocSectionSize = 0;
    195   uint64_t LineSectionSize = 0;
    196   uint64_t FrameSectionSize = 0;
    197   uint64_t DebugInfoSectionSize = 0;
    198 
    199   /// Keep track of emitted CUs and their Unique ID.
    200   struct EmittedUnit {
    201     unsigned ID;
    202     MCSymbol *LabelBegin;
    203   };
    204   std::vector<EmittedUnit> EmittedUnits;
    205 
    206   /// Emit the pubnames or pubtypes section contribution for \p
    207   /// Unit into \p Sec. The data is provided in \p Names.
    208   void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
    209                              const CompileUnit &Unit,
    210                              const std::vector<CompileUnit::AccelInfo> &Names);
    211 
    212   messageHandler ErrorHandler = nullptr;
    213   messageHandler WarningHandler = nullptr;
    214 };
    215 
    216 } // end namespace llvm
    217 
    218 #endif // LLVM_DWARFLINKER_DWARFSTREAMER_H
    219