Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- DWARFLinker.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_PARALLEL_DWARFLINKER_H
0010 #define LLVM_DWARFLINKER_PARALLEL_DWARFLINKER_H
0011 
0012 #include "llvm/CodeGen/AsmPrinter.h"
0013 #include "llvm/DWARFLinker/DWARFFile.h"
0014 #include "llvm/DWARFLinker/DWARFLinkerBase.h"
0015 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
0016 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
0017 #include "llvm/MC/MCDwarf.h"
0018 #include "llvm/TargetParser/Triple.h"
0019 
0020 /// ------------------------------------------------------------------
0021 /// The core of the Dwarf linking logic.
0022 ///
0023 /// The generation of the dwarf information from the object files will be
0024 /// driven by the selection of 'root DIEs', which are DIEs that
0025 /// describe variables or functions that resolves to the corresponding
0026 /// code section(and thus have entries in the Addresses map). All the debug
0027 /// information that will be generated(the DIEs, but also the line
0028 /// tables, ranges, ...) is derived from that set of root DIEs.
0029 ///
0030 /// The root DIEs are identified because they contain relocations that
0031 /// points to code section(the low_pc for a function, the location for
0032 /// a variable). These relocations are gathered as a very first step
0033 /// when we start processing a object file by AddressesMap.
0034 ///
0035 /// The overall linking process looks like this:
0036 ///
0037 /// parrallel_for_each(ObjectFile) {
0038 ///   for_each (Compile Unit) {
0039 ///     1. Load Clang modules.
0040 ///   }
0041 ///
0042 ///   parrallel_for_each(Compile Unit) {
0043 ///     1. Load input DWARF for Compile Unit.
0044 ///     2. Report warnings for Clang modules.
0045 ///     3. Analyze live DIEs and type names(if ODR deduplication is requested).
0046 ///     4. Clone DIEs(Generate output DIEs and resulting DWARF tables).
0047 ///        The result is in an OutDebugInfoBytes, which is an ELF file
0048 ///        containing DWARF tables corresponding to the current compile unit.
0049 ///     5. Cleanup Input and Output DIEs.
0050 ///   }
0051 ///
0052 ///   Deallocate loaded Object file.
0053 /// }
0054 ///
0055 /// if (ODR deduplication is requested)
0056 ///   Generate an artificial compilation unit ("Type Table": used to partially
0057 ///   generate DIEs at the clone stage).
0058 ///
0059 /// for_each (ObjectFile) {
0060 ///   for_each (Compile Unit) {
0061 ///     1. Set offsets to Compile Units DWARF tables.
0062 ///     2. Sort offsets/attributes/patches to have a predictable result.
0063 ///     3. Patch size/offsets fields.
0064 ///     4. Generate index tables.
0065 ///     5. Move DWARF tables of compile units into the resulting file.
0066 ///   }
0067 /// }
0068 ///
0069 /// Every compile unit is processed separately, visited only once
0070 /// (except case inter-CU references exist), and used data is freed
0071 /// after the compile unit is processed. The resulting file is glued together
0072 /// from the generated debug tables which correspond to separate compile units.
0073 ///
0074 /// Handling inter-CU references: inter-CU references are hard to process
0075 /// using only one pass. f.e. if CU1 references CU100 and CU100 references
0076 /// CU1, we could not finish handling of CU1 until we finished CU100.
0077 /// Thus we either need to load all CUs into the memory, either load CUs several
0078 /// times. This implementation loads inter-connected CU into memory at the first
0079 /// pass and processes them at the second pass.
0080 ///
0081 /// ODR deduplication: Artificial compilation unit will be constructed to keep
0082 /// type dies. All types are moved into that compilation unit. Type's references
0083 /// are patched so that they point to the corresponding types from artificial
0084 /// compilation unit. All partial type definitions would be merged into single
0085 /// type definition.
0086 ///
0087 
0088 namespace llvm {
0089 namespace dwarf_linker {
0090 namespace parallel {
0091 
0092 /// This structure keeps data of the concrete section.
0093 struct SectionDescriptorBase {
0094   SectionDescriptorBase(DebugSectionKind SectionKind, dwarf::FormParams Format,
0095                         llvm::endianness Endianess)
0096       : SectionKind(SectionKind), Format(Format), Endianess(Endianess) {}
0097   virtual ~SectionDescriptorBase() = default;
0098   /// Returns section content.
0099   virtual StringRef getContents() = 0;
0100   /// Returns section kind.
0101   DebugSectionKind getKind() { return SectionKind; }
0102   /// Returns section name.
0103   const StringLiteral &getName() const { return getSectionName(SectionKind); }
0104   /// Returns endianess used by section.
0105   llvm::endianness getEndianess() const { return Endianess; }
0106   /// Returns FormParams used by section.
0107   dwarf::FormParams getFormParams() const { return Format; }
0108 
0109 protected:
0110   /// The section kind.
0111   DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries;
0112   /// Output format.
0113   dwarf::FormParams Format = {4, 4, dwarf::DWARF32};
0114   llvm::endianness Endianess = llvm::endianness::little;
0115 };
0116 
0117 using SectionHandlerTy =
0118     std::function<void(std::shared_ptr<SectionDescriptorBase> Section)>;
0119 
0120 class DWARFLinker : public DWARFLinkerBase {
0121 public:
0122   virtual ~DWARFLinker() = default;
0123 
0124   /// Creates dwarf linker instance.
0125   static std::unique_ptr<DWARFLinker>
0126   createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler);
0127 
0128   /// Set output DWARF handler. Result of linking DWARF is set of sections
0129   /// containing final debug info. DWARFLinkerBase::link() pass generated
0130   /// sections using specified \p SectionHandler.
0131   virtual void setOutputDWARFHandler(const Triple &TargetTriple,
0132                                      SectionHandlerTy SectionHandler) = 0;
0133 };
0134 
0135 } // end of namespace parallel
0136 } // end of namespace dwarf_linker
0137 } // end of namespace llvm
0138 
0139 #endif // LLVM_DWARFLINKER_PARALLEL_DWARFLINKER_H