[lld] [lld][ELF] Implement merged .debug_names section (PR #88092)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 10 12:05:35 PDT 2024


================
@@ -789,6 +793,121 @@ class RelroPaddingSection final : public SyntheticSection {
   void writeTo(uint8_t *buf) override {}
 };
 
+// Used by the merged DWARF32 .debug_names (a per-module index). If we
+// move to DWARF64, most of this data will need to be re-sized.
+class DebugNamesBaseSection : public SyntheticSection {
+public:
+  struct Abbrev : llvm::FoldingSetNode {
+    uint32_t code;
+    uint32_t tag;
+    SmallVector<llvm::DWARFDebugNames::AttributeEncoding, 2> attributes;
+
+    void Profile(llvm::FoldingSetNodeID &id) const;
+  };
+
+  struct AttrValue {
+    uint32_t attrValue;
+    uint8_t attrSize;
+  };
+
+  struct IndexEntry {
+    uint32_t abbrevCode;
+    uint32_t poolOffset;
+    union {
+      uint64_t parentOffset = 0;
+      IndexEntry *parentEntry;
+    };
+    SmallVector<AttrValue, 3> attrValues;
+  };
+
+  struct NameTableEntry {
+    const char *name;
+    uint32_t hashValue;
+    uint32_t stringOffset;
+    uint32_t entryOffset;
+    // Used to relocate `stringOffset` in the merged section.
+    uint32_t chunkIdx;
+    SmallVector<IndexEntry *, 0> indexEntries;
+
+    llvm::iterator_range<
+        llvm::pointee_iterator<typename SmallVector<IndexEntry *, 0>::iterator>>
+    entries() {
+      return llvm::make_pointee_range(indexEntries);
+    }
+  };
+
+  // One name index described by an input .debug_names section. An InputChunk
+  // typically contains one single name index.
+  struct NameIndex {
+    llvm::DWARFDebugNames::Header hdr;
+    llvm::DenseMap<uint32_t, uint32_t> abbrevCodeMap;
+    SmallVector<NameTableEntry, 0> nameEntries;
+  };
+
+  // InputChunk and OutputChunk hold per-file contribution to the merged index.
+  // InputChunk instances will be discarded after `create` completes.
+  struct InputChunk {
+    uint32_t baseCuIdx;
+    LLDDWARFSection section;
+    SmallVector<NameIndex, 0> nameIndices;
+    std::optional<llvm::DWARFDebugNames> llvmDebugNames;
+  };
+
+  struct OutputChunk {
+    // Pointer to the .debug_info section that contains compile units, used to
+    // compute the relocated CU offsets.
+    InputSection *infoSec;
+    SmallVector<uint32_t, 0> compUnits;
+  };
+
+  DebugNamesBaseSection();
+  size_t getSize() const override { return size; }
+  bool isNeeded() const override { return numChunks > 0; }
+
+protected:
+  void init(llvm::function_ref<void(InputFile *, InputChunk &, OutputChunk &)>);
+  static void parse(InputChunk &inputChunk, OutputChunk &chunk,
+                    llvm::DWARFDataExtractor &namesExtractor,
+                    llvm::DataExtractor &strExtractor,
+                    llvm::function_ref<SmallVector<uint32_t, 0>(
+                        const llvm::DWARFDebugNames::Header &hdr,
+                        const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)>
+                        readOffsets);
+  void computeHdrAndAbbrevTable(MutableArrayRef<InputChunk>);
+  std::pair<uint32_t, uint32_t> computeEntryPool(MutableArrayRef<InputChunk>);
----------------
MaskRay wrote:

ditto above.  cheap type (2 words)

https://github.com/llvm/llvm-project/pull/88092


More information about the llvm-commits mailing list