Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:49

0001 //===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
0010 #define LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
0011 
0012 #include "DWARFLinker.h"
0013 #include "llvm/BinaryFormat/Swift.h"
0014 #include "llvm/CodeGen/AsmPrinter.h"
0015 #include "llvm/MC/MCAsmInfo.h"
0016 #include "llvm/MC/MCContext.h"
0017 #include "llvm/MC/MCInstrInfo.h"
0018 #include "llvm/MC/MCObjectFileInfo.h"
0019 #include "llvm/MC/MCRegisterInfo.h"
0020 #include "llvm/MC/MCSubtargetInfo.h"
0021 #include "llvm/Target/TargetMachine.h"
0022 
0023 namespace llvm {
0024 template <typename DataT> class AccelTable;
0025 
0026 class MCCodeEmitter;
0027 class DWARFDebugMacro;
0028 
0029 namespace dwarf_linker {
0030 namespace classic {
0031 
0032 ///   User of DwarfStreamer should call initialization code
0033 ///   for AsmPrinter:
0034 ///
0035 ///   InitializeAllTargetInfos();
0036 ///   InitializeAllTargetMCs();
0037 ///   InitializeAllTargets();
0038 ///   InitializeAllAsmPrinters();
0039 
0040 /// The Dwarf streaming logic.
0041 ///
0042 /// All interactions with the MC layer that is used to build the debug
0043 /// information binary representation are handled in this class.
0044 class DwarfStreamer : public DwarfEmitter {
0045 public:
0046   DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType,
0047                 raw_pwrite_stream &OutFile,
0048                 DWARFLinkerBase::MessageHandlerTy Warning)
0049       : OutFile(OutFile), OutFileType(OutFileType), WarningHandler(Warning) {}
0050   virtual ~DwarfStreamer() = default;
0051 
0052   static Expected<std::unique_ptr<DwarfStreamer>> createStreamer(
0053       const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
0054       raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning);
0055 
0056   Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
0057 
0058   /// Dump the file to the disk.
0059   void finish() override;
0060 
0061   AsmPrinter &getAsmPrinter() const { return *Asm; }
0062 
0063   /// Set the current output section to debug_info and change
0064   /// the MC Dwarf version to \p DwarfVersion.
0065   void switchToDebugInfoSection(unsigned DwarfVersion);
0066 
0067   /// Emit the compilation unit header for \p Unit in the
0068   /// debug_info section.
0069   ///
0070   /// As a side effect, this also switches the current Dwarf version
0071   /// of the MC layer to the one of U.getOrigUnit().
0072   void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
0073 
0074   /// Recursively emit the DIE tree rooted at \p Die.
0075   void emitDIE(DIE &Die) override;
0076 
0077   /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
0078   void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
0079                    unsigned DwarfVersion) override;
0080 
0081   /// Emit contents of section SecName From Obj.
0082   void emitSectionContents(StringRef SecData,
0083                            DebugSectionKind SecKind) override;
0084 
0085   /// Emit the string table described by \p Pool into .debug_str table.
0086   void emitStrings(const NonRelocatableStringpool &Pool) override;
0087 
0088   /// Emit the debug string offset table described by \p StringOffsets into the
0089   /// .debug_str_offsets table.
0090   void emitStringOffsets(const SmallVector<uint64_t> &StringOffset,
0091                          uint16_t TargetDWARFVersion) override;
0092 
0093   /// Emit the string table described by \p Pool into .debug_line_str table.
0094   void emitLineStrings(const NonRelocatableStringpool &Pool) override;
0095 
0096   /// Emit the swift_ast section stored in \p Buffer.
0097   void emitSwiftAST(StringRef Buffer);
0098 
0099   /// Emit the swift reflection section stored in \p Buffer.
0100   void emitSwiftReflectionSection(
0101       llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
0102       StringRef Buffer, uint32_t Alignment, uint32_t Size);
0103 
0104   /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
0105   MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
0106 
0107   /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
0108   void emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
0109                                        const AddressRanges &LinkedRanges,
0110                                        PatchLocation Patch,
0111                                        DebugDieValuePool &AddrPool) override;
0112 
0113   /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
0114   void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
0115                                      MCSymbol *EndLabel) override;
0116 
0117   /// Emit debug locations(.debug_loc, .debug_loclists) header.
0118   MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override;
0119 
0120   /// Emit .debug_addr header.
0121   MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override;
0122 
0123   /// Emit the addresses described by \p Addrs into .debug_addr table.
0124   void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
0125                            uint8_t AddrSize) override;
0126 
0127   /// Emit .debug_addr footer.
0128   void emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
0129                                  MCSymbol *EndLabel) override;
0130 
0131   /// Emit debug ranges(.debug_loc, .debug_loclists) fragment.
0132   void emitDwarfDebugLocListFragment(
0133       const CompileUnit &Unit,
0134       const DWARFLocationExpressionsVector &LinkedLocationExpression,
0135       PatchLocation Patch, DebugDieValuePool &AddrPool) override;
0136 
0137   /// Emit debug ranges(.debug_loc, .debug_loclists) footer.
0138   void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
0139                                    MCSymbol *EndLabel) override;
0140 
0141   /// Emit .debug_aranges entries for \p Unit
0142   void emitDwarfDebugArangesTable(const CompileUnit &Unit,
0143                                   const AddressRanges &LinkedRanges) override;
0144 
0145   uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
0146 
0147   uint64_t getRngListsSectionSize() const override {
0148     return RngListsSectionSize;
0149   }
0150 
0151   /// Emit .debug_line table entry for specified \p LineTable
0152   void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
0153                             const CompileUnit &Unit,
0154                             OffsetsStringPool &DebugStrPool,
0155                             OffsetsStringPool &DebugLineStrPool) override;
0156 
0157   uint64_t getLineSectionSize() const override { return LineSectionSize; }
0158 
0159   /// Emit the .debug_pubnames contribution for \p Unit.
0160   void emitPubNamesForUnit(const CompileUnit &Unit) override;
0161 
0162   /// Emit the .debug_pubtypes contribution for \p Unit.
0163   void emitPubTypesForUnit(const CompileUnit &Unit) override;
0164 
0165   /// Emit a CIE.
0166   void emitCIE(StringRef CIEBytes) override;
0167 
0168   /// Emit an FDE with data \p Bytes.
0169   void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
0170                StringRef Bytes) override;
0171 
0172   /// Emit DWARF debug names.
0173   void emitDebugNames(DWARF5AccelTable &Table) override;
0174 
0175   /// Emit Apple namespaces accelerator table.
0176   void emitAppleNamespaces(
0177       AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
0178 
0179   /// Emit Apple names accelerator table.
0180   void
0181   emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
0182 
0183   /// Emit Apple Objective-C accelerator table.
0184   void
0185   emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
0186 
0187   /// Emit Apple type accelerator table.
0188   void
0189   emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
0190 
0191   uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
0192 
0193   uint64_t getDebugInfoSectionSize() const override {
0194     return DebugInfoSectionSize;
0195   }
0196 
0197   uint64_t getDebugMacInfoSectionSize() const override {
0198     return MacInfoSectionSize;
0199   }
0200 
0201   uint64_t getDebugMacroSectionSize() const override {
0202     return MacroSectionSize;
0203   }
0204 
0205   uint64_t getLocListsSectionSize() const override {
0206     return LocListsSectionSize;
0207   }
0208 
0209   uint64_t getDebugAddrSectionSize() const override { return AddrSectionSize; }
0210 
0211   void emitMacroTables(DWARFContext *Context,
0212                        const Offset2UnitMap &UnitMacroMap,
0213                        OffsetsStringPool &StringPool) override;
0214 
0215 private:
0216   inline void warn(const Twine &Warning, StringRef Context = "") {
0217     if (WarningHandler)
0218       WarningHandler(Warning, Context, nullptr);
0219   }
0220 
0221   MCSection *getMCSection(DebugSectionKind SecKind);
0222 
0223   void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
0224                           const Offset2UnitMap &UnitMacroMap,
0225                           OffsetsStringPool &StringPool, uint64_t &OutOffset);
0226 
0227   /// Emit piece of .debug_ranges for \p LinkedRanges.
0228   void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
0229                                          const AddressRanges &LinkedRanges,
0230                                          PatchLocation Patch);
0231 
0232   /// Emit piece of .debug_rnglists for \p LinkedRanges.
0233   void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit,
0234                                            const AddressRanges &LinkedRanges,
0235                                            PatchLocation Patch,
0236                                            DebugDieValuePool &AddrPool);
0237 
0238   /// Emit piece of .debug_loc for \p LinkedRanges.
0239   void emitDwarfDebugLocTableFragment(
0240       const CompileUnit &Unit,
0241       const DWARFLocationExpressionsVector &LinkedLocationExpression,
0242       PatchLocation Patch);
0243 
0244   /// Emit piece of .debug_loclists for \p LinkedRanges.
0245   void emitDwarfDebugLocListsTableFragment(
0246       const CompileUnit &Unit,
0247       const DWARFLocationExpressionsVector &LinkedLocationExpression,
0248       PatchLocation Patch, DebugDieValuePool &AddrPool);
0249 
0250   /// \defgroup Line table emission
0251   /// @{
0252   void emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
0253                              OffsetsStringPool &DebugStrPool,
0254                              OffsetsStringPool &DebugLineStrPool);
0255   void emitLineTableString(const DWARFDebugLine::Prologue &P,
0256                            const DWARFFormValue &String,
0257                            OffsetsStringPool &DebugStrPool,
0258                            OffsetsStringPool &DebugLineStrPool);
0259   void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,
0260                                     OffsetsStringPool &DebugStrPool,
0261                                     OffsetsStringPool &DebugLineStrPool);
0262   void emitLineTablePrologueV2IncludeAndFileTable(
0263       const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
0264       OffsetsStringPool &DebugLineStrPool);
0265   void emitLineTablePrologueV5IncludeAndFileTable(
0266       const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
0267       OffsetsStringPool &DebugLineStrPool);
0268   void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
0269                          MCSymbol *LineEndSym, unsigned AddressByteSize);
0270   void emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
0271                      uint64_t &SectionSize);
0272   void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
0273                            dwarf::DwarfFormat Format, uint64_t &SectionSize);
0274   /// @}
0275 
0276   /// \defgroup MCObjects MC layer objects constructed by the streamer
0277   /// @{
0278   std::unique_ptr<MCRegisterInfo> MRI;
0279   std::unique_ptr<MCAsmInfo> MAI;
0280   std::unique_ptr<MCObjectFileInfo> MOFI;
0281   std::unique_ptr<MCContext> MC;
0282   MCAsmBackend *MAB; // Owned by MCStreamer
0283   std::unique_ptr<MCInstrInfo> MII;
0284   std::unique_ptr<MCSubtargetInfo> MSTI;
0285   MCInstPrinter *MIP; // Owned by AsmPrinter
0286   MCCodeEmitter *MCE; // Owned by MCStreamer
0287   MCStreamer *MS;     // Owned by AsmPrinter
0288   std::unique_ptr<TargetMachine> TM;
0289   std::unique_ptr<AsmPrinter> Asm;
0290   /// @}
0291 
0292   /// The output file we stream the linked Dwarf to.
0293   raw_pwrite_stream &OutFile;
0294   DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
0295 
0296   uint64_t RangesSectionSize = 0;
0297   uint64_t RngListsSectionSize = 0;
0298   uint64_t LocSectionSize = 0;
0299   uint64_t LocListsSectionSize = 0;
0300   uint64_t LineSectionSize = 0;
0301   uint64_t FrameSectionSize = 0;
0302   uint64_t DebugInfoSectionSize = 0;
0303   uint64_t MacInfoSectionSize = 0;
0304   uint64_t MacroSectionSize = 0;
0305   uint64_t AddrSectionSize = 0;
0306   uint64_t StrOffsetSectionSize = 0;
0307 
0308   /// Keep track of emitted CUs and their Unique ID.
0309   struct EmittedUnit {
0310     unsigned ID;
0311     MCSymbol *LabelBegin;
0312   };
0313   std::vector<EmittedUnit> EmittedUnits;
0314 
0315   /// Emit the pubnames or pubtypes section contribution for \p
0316   /// Unit into \p Sec. The data is provided in \p Names.
0317   void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
0318                              const CompileUnit &Unit,
0319                              const std::vector<CompileUnit::AccelInfo> &Names);
0320 
0321   DWARFLinkerBase::MessageHandlerTy WarningHandler = nullptr;
0322 };
0323 
0324 } // end of namespace classic
0325 } // end of namespace dwarf_linker
0326 } // end of namespace llvm
0327 
0328 #endif // LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H