[llvm] [BOLT][DWARF] Add support for .debug_names (PR #81062)
Alexander Yermolovich via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 16:20:35 PST 2024
https://github.com/ayermolo created https://github.com/llvm/llvm-project/pull/81062
DWARF5 spec supports the .debug_names acceleration table. This is the formalized version of combination of gdb-index/pubnames/types. Added implementation of it to BOLT. It supports both monolothic and split dwarf, with and without Type Units. It does not include parent indices. This will be in followup PR. Unlike LLVM output this will put all the CUs and TUs into one Module.
>From 3d42fc75e5674ffccffc0d3e183f592c209c7648 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Wed, 15 Nov 2023 17:10:04 -0800
Subject: [PATCH] [BOLT][DWARF] Add support for .debug_names
DWARF5 spec supports the .debug_names acceleration table. This is the formalized
version of combination of gdb-index/pubnames/types. Added implementation of it
to BOLT. It supports both monolothic and split dwarf, with and without Type
Units. It does not include parent indices. This will be in followup PR. Unlike
LLVM output this will put all the CUs and TUs into one Module.
---
bolt/include/bolt/Core/BinaryContext.h | 4 +
bolt/include/bolt/Core/DIEBuilder.h | 13 +-
bolt/include/bolt/Core/DebugData.h | 20 +-
bolt/include/bolt/Core/DebugNames.h | 193 +++++
bolt/include/bolt/Rewrite/DWARFRewriter.h | 7 +-
bolt/lib/Core/CMakeLists.txt | 1 +
bolt/lib/Core/DIEBuilder.cpp | 41 +-
bolt/lib/Core/DebugData.cpp | 4 +-
bolt/lib/Core/DebugNames.cpp | 644 ++++++++++++++++
bolt/lib/Rewrite/DWARFRewriter.cpp | 34 +-
.../X86/Inputs/dwarf5-debug-names-helper.s | 487 ++++++++++++
.../test/X86/Inputs/dwarf5-debug-names-main.s | 712 ++++++++++++++++++
.../X86/Inputs/dwarf5-df-debug-names-helper.s | 326 ++++++++
.../X86/Inputs/dwarf5-df-debug-names-main.s | 493 ++++++++++++
.../dwarf5-df-types-debug-names-helper.s | 650 ++++++++++++++++
.../Inputs/dwarf5-df-types-debug-names-main.s | 626 +++++++++++++++
.../Inputs/dwarf5-types-debug-names-helper.s | 405 ++++++++++
.../Inputs/dwarf5-types-debug-names-main.s | 391 ++++++++++
...arf5-debug-names-generate-debug-names.test | 154 ++++
bolt/test/X86/dwarf5-debug-names.test | 263 +++++++
...5-df-debug-names-generate-debug-names.test | 192 +++++
bolt/test/X86/dwarf5-df-debug-names.test | 149 ++++
.../X86/dwarf5-df-one-cu-debug-names.test | 101 +++
.../test/X86/dwarf5-df-types-debug-names.test | 234 ++++++
.../dwarf5-df-types-one-cu-debug-names.test | 129 ++++
bolt/test/X86/dwarf5-one-cu-debug-names.test | 178 +++++
bolt/test/X86/dwarf5-types-debug-names.test | 129 ++++
.../X86/dwarf5-types-one-cu-debug-names.test | 98 +++
28 files changed, 6640 insertions(+), 38 deletions(-)
create mode 100644 bolt/include/bolt/Core/DebugNames.h
create mode 100644 bolt/lib/Core/DebugNames.cpp
create mode 100644 bolt/test/X86/Inputs/dwarf5-debug-names-helper.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-debug-names-main.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-debug-names-helper.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-debug-names-main.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-types-debug-names-helper.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-df-types-debug-names-main.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-types-debug-names-helper.s
create mode 100644 bolt/test/X86/Inputs/dwarf5-types-debug-names-main.s
create mode 100644 bolt/test/X86/dwarf5-debug-names-generate-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-df-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-df-one-cu-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-df-types-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-one-cu-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-types-debug-names.test
create mode 100644 bolt/test/X86/dwarf5-types-one-cu-debug-names.test
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index f1db1fbded6a47..4cf204d9b12f57 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -962,6 +962,10 @@ class BinaryContext {
return getUniqueSectionByName(".gdb_index");
}
+ ErrorOr<BinarySection &> getDebugNamesSection() const {
+ return getUniqueSectionByName(".debug_names");
+ }
+
/// @}
/// Register \p TargetFunction as a fragment of \p Function if checks pass:
diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index f89084065aae1c..cf3bf8301c1e67 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -15,6 +15,7 @@
#ifndef BOLT_CORE_DIE_BUILDER_H
#define BOLT_CORE_DIE_BUILDER_H
+#include "bolt/Core/DebugNames.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
@@ -121,9 +122,10 @@ class DIEBuilder {
FoldingSet<DIEAbbrev> AbbreviationsSet;
std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
DWARFContext *DwarfContext{nullptr};
- bool IsDWO{false};
+ DWARFUnit *SkeletonCU{nullptr};
uint64_t UnitSize{0};
llvm::DenseSet<uint64_t> AllProcessed;
+ DWARF5AcceleratorTable &DebugNamesTable;
/// Returns current state of the DIEBuilder
State &getState() { return *BuilderState.get(); }
@@ -204,7 +206,7 @@ class DIEBuilder {
void updateReferences();
/// Update the Offset and Size of DIE.
- uint32_t computeDIEOffset(const DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);
+ uint32_t computeDIEOffset(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);
void registerUnit(DWARFUnit &DU, bool NeedSort);
@@ -260,8 +262,13 @@ class DIEBuilder {
/// current Section.
DIE *constructDIEFast(DWARFDie &DDie, DWARFUnit &U, uint32_t UnitId);
+ /// Returns true if this DIEBUilder is for DWO Unit.
+ bool isDWO() const { return SkeletonCU != nullptr; }
+
public:
- DIEBuilder(DWARFContext *DwarfContext, bool IsDWO = false);
+ DIEBuilder(DWARFContext *DwarfContext,
+ DWARF5AcceleratorTable &DebugNamesTable,
+ DWARFUnit *SkeletonCU = nullptr);
/// Returns enum to what we are currently processing.
ProcessingType getCurrentProcessingState() { return getState().Type; }
diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 31a636ba2ce653..70e688a3fd1dc3 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -439,6 +439,12 @@ class DebugStrOffsetsWriter {
/// Update Str offset in .debug_str in .debug_str_offsets.
void updateAddressMap(uint32_t Index, uint32_t Address);
+ /// Get offset for given index in original .debug_str_offsets section.
+ uint64_t getOffset(uint32_t Index) const {
+ assert(StrOffsets.size() > Index && "Index is out of bounds.");
+ return StrOffsets[Index];
+ }
+
/// Writes out current sections entry into .debug_str_offsets.
void finalizeSection(DWARFUnit &Unit, DIEBuilder &DIEBldr);
@@ -450,10 +456,16 @@ class DebugStrOffsetsWriter {
return std::move(StrOffsetsBuffer);
}
-private:
/// Initializes Buffer and Stream.
void initialize(DWARFUnit &Unit);
+ /// Clear data.
+ void clear() {
+ IndexToAddressMap.clear();
+ StrOffsets.clear();
+ }
+
+private:
std::unique_ptr<DebugStrOffsetsBufferVector> StrOffsetsBuffer;
std::unique_ptr<raw_svector_ostream> StrOffsetsStream;
std::map<uint32_t, uint32_t> IndexToAddressMap;
@@ -478,11 +490,12 @@ class DebugStrWriter {
/// Returns False if no strings were added to .debug_str.
bool isInitialized() const { return !StrBuffer->empty(); }
+ /// Initializes Buffer and Stream.
+ void initialize();
+
private:
/// Mutex used for parallel processing of debug info.
std::mutex WriterMutex;
- /// Initializes Buffer and Stream.
- void initialize();
/// Creates internal data structures.
void create();
std::unique_ptr<DebugStrBufferVector> StrBuffer;
@@ -798,6 +811,7 @@ class DwarfLineTable {
// Returns DWARF Version for this line table.
uint16_t getDwarfVersion() const { return DwarfVersion; }
};
+
} // namespace bolt
} // namespace llvm
diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h
new file mode 100644
index 00000000000000..5370219401b81c
--- /dev/null
+++ b/bolt/include/bolt/Core/DebugNames.h
@@ -0,0 +1,193 @@
+//===- bolt/Core/DebugNames.cpp - Debugging information handling ---*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains declaration of classes required for generation of
+// .debug_names section.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BOLT_CORE_DEBUG_NAMES_H
+#define BOLT_CORE_DEBUG_NAMES_H
+
+#include "DebugData.h"
+#include "llvm/CodeGen/AccelTable.h"
+
+namespace llvm {
+namespace bolt {
+class BOLTDWARF5AccelTableData : DWARF5AccelTableData {
+public:
+ BOLTDWARF5AccelTableData(const uint64_t DieOffset,
+ const std::optional<uint64_t> DefiningParentOffset,
+ const unsigned DieTag, const unsigned UnitID,
+ const bool IsTU,
+ const std::optional<unsigned> SecondUnitID)
+ : DWARF5AccelTableData(DieOffset, DefiningParentOffset, DieTag, UnitID,
+ IsTU),
+ SecondUnitID(SecondUnitID) {}
+
+ uint64_t getDieOffset() const { return DWARF5AccelTableData::getDieOffset(); }
+ unsigned getDieTag() const { return DWARF5AccelTableData::getDieTag(); }
+ unsigned getUnitID() const { return DWARF5AccelTableData::getUnitID(); }
+ bool isTU() const { return DWARF5AccelTableData::isTU(); }
+ std::optional<unsigned> getSecondUnitID() const { return SecondUnitID; }
+
+private:
+ std::optional<unsigned> SecondUnitID;
+};
+
+class DWARF5AcceleratorTable {
+public:
+ DWARF5AcceleratorTable(const bool CreateDebugNames, BinaryContext &BC,
+ DebugStrWriter &MainBinaryStrWriter);
+ /// Add DWARF5 Accelerator table entry.
+ /// Input is DWARFUnit being processed, DIE that belongs to it, and potential
+ /// SkeletonCU if the Unit comes from a DWO section.
+ void addAccelTableEntry(DWARFUnit &Unit, const DIE &Die,
+ const std::optional<uint64_t> &DWOID);
+ /// Set current unit being processed.
+ void setCurrentUnit(DWARFUnit &Unit, const uint64_t UnitStartOffset);
+ /// Emit Accelerator table.
+ void emitAccelTable();
+ /// Returns true if the table was crated.
+ bool isCreated() const { return NeedToCreate; }
+ /// Returns buffer containing the accelerator table.
+ std::unique_ptr<DebugBufferVector> releaseBuffer() {
+ return std::move(FullTableBuffer);
+ }
+
+private:
+ union AbbrevDescriptor {
+ struct {
+ uint32_t CompUnit : 1;
+ uint32_t TypeUnit : 1;
+ uint32_t DieOffset : 1;
+ uint32_t Parent : 1;
+ uint32_t TypeHash : 2;
+ uint32_t Tag : 26;
+ } Bits;
+ uint32_t Value = 0;
+ };
+ class TagIndex {
+ public:
+ uint32_t DieTag;
+ uint32_t Index;
+ };
+ struct cmpByTagIndex {
+ bool operator()(const TagIndex &LHS, const TagIndex &RHS) const {
+ return LHS.Index < RHS.Index;
+ }
+ };
+ bool NeedToCreate = false;
+ BumpPtrAllocator Allocator;
+ DebugStrWriter &MainBinaryStrWriter;
+ DebugStrOffsetsWriter StrOffsetsWriter;
+ StringRef StrSection;
+ uint64_t CurrentUnitOffset = 0;
+ const DWARFUnit *CurrentUnit = nullptr;
+ std::unordered_map<uint32_t, uint32_t> AbbrevTagToIndexMap;
+
+ /// Represents a group of entries with identical name (and hence, hash value).
+ struct HashData {
+ uint64_t StrOffset;
+ uint32_t HashValue;
+ uint32_t EntryOffset;
+ std::vector<BOLTDWARF5AccelTableData *> Values;
+ };
+ using HashList = std::vector<HashData *>;
+ using BucketList = std::vector<HashList>;
+ /// Contains all the offsets of CUs.
+ SmallVector<uint32_t, 1> CUList;
+ /// Contains all the offsets of local TUs.
+ SmallVector<uint32_t, 1> LocalTUList;
+ /// Contains all the type hashes for split dwarf TUs.
+ SmallVector<uint64_t, 1> ForeignTUList;
+ using StringEntries =
+ MapVector<std::string, HashData, llvm::StringMap<unsigned>>;
+ StringEntries Entries;
+ std::map<TagIndex, SmallVector<DWARF5AccelTableData::AttributeEncoding, 2>,
+ cmpByTagIndex>
+ Abbreviations;
+ uint32_t BucketCount = 0;
+ uint32_t UniqueHashCount = 0;
+ uint32_t AbbrevTableSize = 0;
+ uint32_t CUIndexEncodingSize = 4;
+ uint32_t TUIndexEncodingSize = 4;
+ uint32_t AugmentationStringSize = 0;
+ dwarf::Form CUIndexForm = dwarf::DW_FORM_data4;
+ dwarf::Form TUIndexForm = dwarf::DW_FORM_data4;
+
+ BucketList Buckets;
+
+ std::unique_ptr<DebugBufferVector> FullTableBuffer;
+ std::unique_ptr<raw_svector_ostream> FullTableStream;
+ std::unique_ptr<DebugBufferVector> StrBuffer;
+ std::unique_ptr<raw_svector_ostream> StrStream;
+ std::unique_ptr<DebugBufferVector> EntriesBuffer;
+ std::unique_ptr<raw_svector_ostream> Entriestream;
+ std::unique_ptr<DebugBufferVector> AugStringBuffer;
+ std::unique_ptr<raw_svector_ostream> AugStringtream;
+ llvm::DenseMap<llvm::hash_code, uint64_t> StrCacheToOffsetMap;
+ // Contains DWO ID to CUList Index.
+ llvm::DenseMap<uint64_t, uint32_t> CUOffsetsToPatch;
+ /// Adds Unit to either CUList, LocalTUList or ForeignTUList.
+ /// Input Unit being processed, and DWO ID if Unit is being processed comes
+ /// from a DWO section.
+ void addUnit(DWARFUnit &Unit, const std::optional<uint64_t> &DWOID);
+ /// Returns number of buckets in .debug_name table.
+ ArrayRef<HashList> getBuckets() const { return Buckets; }
+ /// Constructs and returns a unique AbbrevTag that captures what a DIE
+ /// accesses.
+ TagIndex getAbbrevIndex(
+ const unsigned DieTag,
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet,
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+ &SecondEntryRe);
+ /// Get encoding for a given attribute.
+ std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+ getIndexForEntry(const BOLTDWARF5AccelTableData &Value) const;
+ /// Get encoding for a given attribute for second index.
+ /// Returns nullopt if there is no second index.
+ std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+ getSecondIndexForEntry(const BOLTDWARF5AccelTableData &Value) const;
+ /// Uniquify Entries.
+ void finalize();
+ /// Computes bucket count.
+ void computeBucketCount();
+ /// Populate Abbreviations Map.
+ void populateAbbrevsMap();
+ /// Write Entries.
+ void writeEntries();
+ /// Write an Entry;
+ void writeEntry(const BOLTDWARF5AccelTableData &Entry);
+ /// Write augmentation_string for BOLT.
+ void writeAugmentationString();
+ /// Emit out Header for DWARF5 Accelerator table.
+ void emitHeader() const;
+ /// Emit out CU list.
+ void emitCUList() const;
+ /// Emit out TU List. Combination of LocalTUList and ForeignTUList.
+ void emitTUList() const;
+ /// Emit buckets.
+ void emitBuckets() const;
+ /// Emit hashes for hash table.
+ void emitHashes() const;
+ /// Emit string offsets for hash table.
+ void emitStringOffsets() const;
+ /// Emit Entry Offsets for hash table.
+ void emitOffsets() const;
+ /// Emit abbreviation table.
+ void emitAbbrevs();
+ /// Emit entries.
+ void emitData();
+ /// Emit augmentation string.
+ void emitAugmentationString() const;
+};
+} // namespace bolt
+} // namespace llvm
+#endif
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index ba6775f99ce68a..20972f3d0b85ae 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -11,6 +11,7 @@
#include "bolt/Core/DIEBuilder.h"
#include "bolt/Core/DebugData.h"
+#include "bolt/Core/DebugNames.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DWP/DWP.h"
@@ -140,8 +141,10 @@ class DWARFRewriter {
const std::list<DWARFUnit *> &CUs);
/// Finalize debug sections in the main binary.
- void finalizeDebugSections(DIEBuilder &DIEBlder, DIEStreamer &Streamer,
- raw_svector_ostream &ObjOS, CUOffsetMap &CUMap);
+ void finalizeDebugSections(DIEBuilder &DIEBlder,
+ DWARF5AcceleratorTable &DebugNamesTable,
+ DIEStreamer &Streamer, raw_svector_ostream &ObjOS,
+ CUOffsetMap &CUMap);
/// Patches the binary for DWARF address ranges (e.g. in functions and lexical
/// blocks) to be updated.
diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index c913179ebcc517..441df9fe084648 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_library(LLVMBOLTCore
BinaryFunctionProfile.cpp
BinarySection.cpp
DebugData.cpp
+ DebugNames.cpp
DIEBuilder.cpp
DynoStats.cpp
Exceptions.cpp
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index 762d3419edd340..f15e764d47d849 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -19,20 +19,17 @@
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/ThreadPool.h"
-#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstdint>
#include <memory>
#include <mutex>
-#include <string>
+#include <optional>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -178,8 +175,11 @@ void DIEBuilder::constructFromUnit(DWARFUnit &DU) {
getState().CloneUnitCtxMap[*UnitId].IsConstructed = true;
}
-DIEBuilder::DIEBuilder(DWARFContext *DwarfContext, bool IsDWO)
- : DwarfContext(DwarfContext), IsDWO(IsDWO) {}
+DIEBuilder::DIEBuilder(DWARFContext *DwarfContext,
+ DWARF5AcceleratorTable &DebugNamesTable,
+ DWARFUnit *SkeletonCU)
+ : DwarfContext(DwarfContext), SkeletonCU(SkeletonCU),
+ DebugNamesTable(DebugNamesTable) {}
static unsigned int getCUNum(DWARFContext *DwarfContext, bool IsDWO) {
unsigned int CUNum = IsDWO ? DwarfContext->getNumDWOCompileUnits()
@@ -203,11 +203,11 @@ void DIEBuilder::buildTypeUnits(DebugStrOffsetsWriter *StrOffsetWriter,
true);
}
}
- const unsigned int CUNum = getCUNum(DwarfContext, IsDWO);
+ const unsigned int CUNum = getCUNum(DwarfContext, isDWO());
getState().CloneUnitCtxMap.resize(CUNum);
DWARFContext::unit_iterator_range CU4TURanges =
- IsDWO ? DwarfContext->dwo_types_section_units()
- : DwarfContext->types_section_units();
+ isDWO() ? DwarfContext->dwo_types_section_units()
+ : DwarfContext->types_section_units();
getState().Type = ProcessingType::DWARF4TUs;
for (std::unique_ptr<DWARFUnit> &DU : CU4TURanges)
@@ -217,8 +217,8 @@ void DIEBuilder::buildTypeUnits(DebugStrOffsetsWriter *StrOffsetWriter,
constructFromUnit(*DU.get());
DWARFContext::unit_iterator_range CURanges =
- IsDWO ? DwarfContext->dwo_info_section_units()
- : DwarfContext->info_section_units();
+ isDWO() ? DwarfContext->dwo_info_section_units()
+ : DwarfContext->info_section_units();
// This handles DWARF4 CUs and DWARF5 CU/TUs.
// Creating a vector so that for reference handling only DWARF5 CU/TUs are
@@ -241,11 +241,11 @@ void DIEBuilder::buildCompileUnits(const bool Init) {
if (Init)
BuilderState.reset(new State());
- unsigned int CUNum = getCUNum(DwarfContext, IsDWO);
+ unsigned int CUNum = getCUNum(DwarfContext, isDWO());
getState().CloneUnitCtxMap.resize(CUNum);
DWARFContext::unit_iterator_range CURanges =
- IsDWO ? DwarfContext->dwo_info_section_units()
- : DwarfContext->info_section_units();
+ isDWO() ? DwarfContext->dwo_info_section_units()
+ : DwarfContext->info_section_units();
// This handles DWARF4 CUs and DWARF5 CU/TUs.
// Creating a vector so that for reference handling only DWARF5 CU/TUs are
@@ -377,11 +377,13 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx,
return nullptr;
}
-uint32_t DIEBuilder::computeDIEOffset(const DWARFUnit &CU, DIE &Die,
+uint32_t DIEBuilder::computeDIEOffset(DWARFUnit &CU, DIE &Die,
uint32_t &CurOffset) {
getState().DWARFDieAddressesParsed.erase(Die.getOffset());
uint32_t CurSize = 0;
Die.setOffset(CurOffset);
+ DebugNamesTable.addAccelTableEntry(
+ CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt);
for (DIEValue &Val : Die.values())
CurSize += Val.sizeOf(CU.getFormParams());
CurSize += getULEB128Size(Die.getAbbrevNumber());
@@ -403,11 +405,11 @@ uint32_t DIEBuilder::computeDIEOffset(const DWARFUnit &CU, DIE &Die,
}
void DIEBuilder::finish() {
- auto computeOffset = [&](const DWARFUnit &CU,
- uint64_t &UnitStartOffset) -> void {
+ auto computeOffset = [&](DWARFUnit &CU, uint64_t &UnitStartOffset) -> void {
DIE *UnitDIE = getUnitDIEbyUnit(CU);
uint32_t HeaderSize = CU.getHeaderSize();
uint32_t CurOffset = HeaderSize;
+ DebugNamesTable.setCurrentUnit(CU, UnitStartOffset);
computeDIEOffset(CU, *UnitDIE, CurOffset);
DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU);
@@ -419,14 +421,14 @@ void DIEBuilder::finish() {
// It's processed first when CU is registered so will be at the begginnig of
// the vector.
uint64_t TypeUnitStartOffset = 0;
- for (const DWARFUnit *CU : getState().DUList) {
+ for (DWARFUnit *CU : getState().DUList) {
// We process DWARF$ types first.
if (!(CU->getVersion() < 5 && CU->isTypeUnit()))
break;
computeOffset(*CU, TypeUnitStartOffset);
}
- for (const DWARFUnit *CU : getState().DUList) {
+ for (DWARFUnit *CU : getState().DUList) {
// Skipping DWARF4 types.
if (CU->getVersion() < 5 && CU->isTypeUnit())
continue;
@@ -908,6 +910,5 @@ std::optional<uint32_t> DIEBuilder::getUnitId(const DWARFUnit &DU) {
return Iter->second;
return std::nullopt;
}
-
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 415b0310b6bac8..cd45049570eeb5 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -916,8 +916,7 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
}
StrOffsetSectionWasModified = false;
- IndexToAddressMap.clear();
- StrOffsets.clear();
+ clear();
}
void DebugStrWriter::create() {
@@ -1239,6 +1238,5 @@ void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
if (LineStr)
LineStr->emitSection(&Streamer);
}
-
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
new file mode 100644
index 00000000000000..a396764808c495
--- /dev/null
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -0,0 +1,644 @@
+//===- bolt/Rewrite/DebugNames.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "bolt/Core/DebugNames.h"
+#include "bolt/Core/BinaryContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/LEB128.h"
+
+namespace llvm {
+namespace bolt {
+DWARF5AcceleratorTable::DWARF5AcceleratorTable(
+ const bool CreateDebugNames, BinaryContext &BC,
+ DebugStrWriter &MainBinaryStrWriter)
+ : MainBinaryStrWriter(MainBinaryStrWriter) {
+ NeedToCreate = CreateDebugNames || BC.getDebugNamesSection();
+ if (!NeedToCreate)
+ return;
+ FullTableBuffer = std::make_unique<DebugStrBufferVector>();
+ FullTableStream = std::make_unique<raw_svector_ostream>(*FullTableBuffer);
+ StrBuffer = std::make_unique<DebugStrBufferVector>();
+ StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer);
+ EntriesBuffer = std::make_unique<DebugStrBufferVector>();
+ Entriestream = std::make_unique<raw_svector_ostream>(*EntriesBuffer);
+ AugStringBuffer = std::make_unique<DebugStrBufferVector>();
+ AugStringtream = std::make_unique<raw_svector_ostream>(*AugStringBuffer);
+
+ // Binary has split-dwarf CUs.
+ // Even thought for non-skeleton-cu all names are in .debug_str.dwo section,
+ // for the .debug_names contributions they are in .debug_str section.
+ if (BC.getNumDWOCUs()) {
+ DataExtractor StrData(BC.DwCtx->getDWARFObj().getStrSection(),
+ BC.DwCtx->isLittleEndian(), 0);
+ uint64_t Offset = 0;
+ uint64_t StrOffset = 0;
+ while (StrData.isValidOffset(Offset)) {
+ Error Err = Error::success();
+ const char *CStr = StrData.getCStr(&Offset, &Err);
+ if (Err) {
+ NeedToCreate = false;
+ errs() << "BOLT-WARNING: [internal-dwarf-error]: Could not extract "
+ "string from .debug_str section at offset: "
+ << Twine::utohexstr(StrOffset) << ".\n";
+ return;
+ }
+ auto R = StrCacheToOffsetMap.try_emplace(
+ llvm::hash_value(llvm::StringRef(CStr)), StrOffset);
+ if (!R.second)
+ errs() << "BOLT-WARNING: [internal-dwarf-error]: collision occured on "
+ << CStr << " at offset : 0x" << Twine::utohexstr(StrOffset)
+ << ". Previous string offset is: 0x"
+ << Twine::utohexstr(R.first->second) << ".\n";
+ StrOffset = Offset;
+ }
+ }
+}
+
+void DWARF5AcceleratorTable::setCurrentUnit(DWARFUnit &Unit,
+ const uint64_t UnitStartOffset) {
+ CurrentUnit = nullptr;
+ CurrentUnitOffset = UnitStartOffset;
+ std::optional<uint64_t> DWOID = Unit.getDWOId();
+ // We process Skelton CUs after DWO Units for it.
+ // Patching offset in CU list to correct one.
+ if (!Unit.isDWOUnit() && DWOID) {
+ auto Iter = CUOffsetsToPatch.find(*DWOID);
+ // Check in case no entries were added from non skeleton DWO section.
+ if (Iter != CUOffsetsToPatch.end())
+ CUList[Iter->second] = UnitStartOffset;
+ }
+}
+
+void DWARF5AcceleratorTable::addUnit(DWARFUnit &Unit,
+ const std::optional<uint64_t> &DWOID) {
+ StrOffsetsWriter.clear();
+ StrOffsetsWriter.initialize(Unit);
+ StrSection = Unit.getStringSection();
+ if (Unit.isTypeUnit()) {
+ if (DWOID) {
+ // We adding an entry for a DWO TU. The DWO CU might not have any entries,
+ // so need to add it to the list pre-emptively.
+ auto Iter = CUOffsetsToPatch.insert({*DWOID, CUList.size()});
+ if (Iter.second)
+ CUList.push_back(0xBADBAD);
+ ForeignTUList.push_back(
+ cast_or_null<DWARFTypeUnit>(&Unit)->getTypeHash());
+ } else {
+ LocalTUList.push_back(CurrentUnitOffset);
+ }
+ } else {
+ if (DWOID) {
+ // This is a path for split dwarf without type units.
+ // We process DWO Units before Skeleton CU. So at this point we don't know
+ // the offset of Skeleton CU. Adding CULit index to a map to patch later
+ // with the correct offset.
+ auto Iter = CUOffsetsToPatch.insert({*DWOID, CUList.size()});
+ if (Iter.second)
+ CUList.push_back(0xBADBAD);
+ } else {
+ CUList.push_back(CurrentUnitOffset);
+ }
+ }
+}
+
+// Returns true if DW_TAG_variable should be included in .debug-names based on
+// section 6.1.1.1 for DWARF5 spec.
+static bool shouldIncludeVariable(const DWARFUnit &Unit, const DIE &Die) {
+ if (Die.findAttribute(dwarf::Attribute::DW_AT_declaration))
+ return false;
+ const DIEValue LocAttrInfo =
+ Die.findAttribute(dwarf::Attribute::DW_AT_location);
+ if (!LocAttrInfo)
+ return false;
+ if (!(doesFormBelongToClass(LocAttrInfo.getForm(), DWARFFormValue::FC_Exprloc,
+ Unit.getVersion()) ||
+ doesFormBelongToClass(LocAttrInfo.getForm(), DWARFFormValue::FC_Block,
+ Unit.getVersion())))
+ return false;
+ std::vector<uint8_t> Sblock;
+ auto constructVect =
+ [&](const DIEValueList::const_value_range &Iter) -> void {
+ for (const DIEValue &Val : Iter)
+ Sblock.push_back(Val.getDIEInteger().getValue());
+ };
+ if (doesFormBelongToClass(LocAttrInfo.getForm(), DWARFFormValue::FC_Exprloc,
+ Unit.getVersion()))
+ constructVect(LocAttrInfo.getDIELoc().values());
+ else
+ constructVect(LocAttrInfo.getDIEBlock().values());
+ ArrayRef<uint8_t> Expr = ArrayRef<uint8_t>(Sblock);
+ DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
+ Unit.getContext().isLittleEndian(), 0);
+ DWARFExpression LocExpr(Data, Unit.getAddressByteSize(),
+ Unit.getFormParams().Format);
+ for (const DWARFExpression::Operation &Expr : LocExpr)
+ if (Expr.getCode() == dwarf::DW_OP_addrx ||
+ Expr.getCode() == dwarf::DW_OP_form_tls_address)
+ return true;
+ return false;
+}
+void DWARF5AcceleratorTable::addAccelTableEntry(
+ DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID) {
+ if (Unit.getVersion() < 5 || !NeedToCreate)
+ return;
+ std::string NameToUse = "";
+ auto canProcess = [&](const DIE &Die) -> bool {
+ switch (Die.getTag()) {
+ case dwarf::DW_TAG_base_type:
+ case dwarf::DW_TAG_class_type:
+ case dwarf::DW_TAG_enumeration_type:
+ case dwarf::DW_TAG_imported_declaration:
+ case dwarf::DW_TAG_pointer_type:
+ case dwarf::DW_TAG_structure_type:
+ case dwarf::DW_TAG_typedef:
+ case dwarf::DW_TAG_unspecified_type:
+ if (Die.findAttribute(dwarf::Attribute::DW_AT_name))
+ return true;
+ return false;
+ case dwarf::DW_TAG_namespace:
+ // According to DWARF5 spec namespaces without DW_AT_name needs to have
+ // "(anonymous namespace)"
+ if (!Die.findAttribute(dwarf::Attribute::DW_AT_name))
+ NameToUse = "(anonymous namespace)";
+ return true;
+ case dwarf::DW_TAG_inlined_subroutine:
+ case dwarf::DW_TAG_label:
+ case dwarf::DW_TAG_subprogram:
+ if (Die.findAttribute(dwarf::Attribute::DW_AT_low_pc) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_high_pc) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_ranges) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_entry_pc))
+ return true;
+ return false;
+ case dwarf::DW_TAG_variable:
+ return shouldIncludeVariable(Unit, Die);
+ default:
+ break;
+ }
+ return false;
+ };
+
+ auto getUnitID = [&](const DWARFUnit &Unit, bool &IsTU,
+ uint32_t &DieTag) -> uint32_t {
+ IsTU = Unit.isTypeUnit();
+ DieTag = Die.getTag();
+ if (IsTU) {
+ if (DWOID)
+ return ForeignTUList.size() - 1;
+ return LocalTUList.size() - 1;
+ }
+ return CUList.size() - 1;
+ };
+
+ if (!canProcess(Die))
+ return;
+
+ // Addes a Unit to either CU, LocalTU or ForeignTU list the first time we
+ // encounter it.
+ // Invoking it here so that we don't add Units that don't have any entries.
+ if (&Unit != CurrentUnit) {
+ CurrentUnit = &Unit;
+ addUnit(Unit, DWOID);
+ }
+
+ auto addEntry = [&](DIEValue ValName) -> void {
+ if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) &&
+ NameToUse.empty())
+ return;
+ std::string Name = "";
+ uint64_t NameIndexOffset = 0;
+ if (NameToUse.empty()) {
+ NameIndexOffset = ValName.getDIEInteger().getValue();
+ if (ValName.getForm() != dwarf::DW_FORM_strp)
+ NameIndexOffset = StrOffsetsWriter.getOffset(NameIndexOffset);
+ // Counts on strings end with '\0'.
+ Name = std::string(&StrSection.data()[NameIndexOffset]);
+ } else {
+ Name = NameToUse;
+ }
+ auto &It = Entries[Name];
+ if (It.Values.empty()) {
+ if (DWOID && NameToUse.empty()) {
+ // For DWO Unit the offset is in the .debug_str.dwo section.
+ // Need to find offset for the name in the .debug_str section.
+ llvm::hash_code Hash = llvm::hash_value(llvm::StringRef(Name));
+ auto ItCache = StrCacheToOffsetMap.find(Hash);
+ if (ItCache == StrCacheToOffsetMap.end())
+ NameIndexOffset = MainBinaryStrWriter.addString(Name);
+ else
+ NameIndexOffset = ItCache->second;
+ }
+ if (!NameToUse.empty())
+ NameIndexOffset = MainBinaryStrWriter.addString(Name);
+ It.StrOffset = NameIndexOffset;
+ // This the same hash function used in DWARF5AccelTableData.
+ It.HashValue = caseFoldingDjbHash(Name);
+ }
+
+ bool IsTU = false;
+ uint32_t DieTag = 0;
+ uint32_t UnitID = getUnitID(Unit, IsTU, DieTag);
+ std::optional<unsigned> SecondIndex = std::nullopt;
+ if (IsTU && DWOID) {
+ auto Iter = CUOffsetsToPatch.find(*DWOID);
+ if (Iter == CUOffsetsToPatch.end())
+ errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find "
+ "DWO ID in CU offsets for second Unit Index "
+ << Name << ". For DIE at offset: "
+ << Twine::utohexstr(CurrentUnitOffset + Die.getOffset()) << ".";
+ SecondIndex = Iter->second;
+ }
+ It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData(
+ Die.getOffset(), std::nullopt, DieTag, UnitID, IsTU, SecondIndex));
+ };
+
+ addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
+ addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
+ return;
+}
+
+/// Algorithm from llvm implementation.
+void DWARF5AcceleratorTable::computeBucketCount() {
+ // First get the number of unique hashes.
+ std::vector<uint32_t> Uniques;
+ Uniques.reserve(Entries.size());
+ for (const auto &E : Entries)
+ Uniques.push_back(E.second.HashValue);
+ array_pod_sort(Uniques.begin(), Uniques.end());
+ std::vector<uint32_t>::iterator P =
+ std::unique(Uniques.begin(), Uniques.end());
+
+ UniqueHashCount = std::distance(Uniques.begin(), P);
+
+ if (UniqueHashCount > 1024)
+ BucketCount = UniqueHashCount / 4;
+ else if (UniqueHashCount > 16)
+ BucketCount = UniqueHashCount / 2;
+ else
+ BucketCount = std::max<uint32_t>(UniqueHashCount, 1);
+}
+
+/// Bucket code as in: AccelTableBase::finalize()
+void DWARF5AcceleratorTable::finalize() {
+ if (!NeedToCreate)
+ return;
+ // Create the individual hash data outputs.
+ for (auto &E : Entries) {
+ // Unique the entries.
+ llvm::stable_sort(E.second.Values, [](const BOLTDWARF5AccelTableData *A,
+ const BOLTDWARF5AccelTableData *B) {
+ return A->getDieOffset() < B->getDieOffset();
+ });
+ }
+ // Figure out how many buckets we need, then compute the bucket contents and
+ // the final ordering. The hashes and offsets can be emitted by walking these
+ // data structures.
+ computeBucketCount();
+
+ // Compute bucket contents and final ordering.
+ Buckets.resize(BucketCount);
+ for (auto &E : Entries) {
+ uint32_t Bucket = E.second.HashValue % BucketCount;
+ Buckets[Bucket].push_back(&E.second);
+ }
+
+ // Sort the contents of the buckets by hash value so that hash collisions end
+ // up together. Stable sort makes testing easier and doesn't cost much more.
+ for (auto &Bucket : Buckets)
+ llvm::stable_sort(Bucket, [](HashData *LHS, HashData *RHS) {
+ return LHS->HashValue < RHS->HashValue;
+ });
+
+ CUIndexForm = DIEInteger::BestForm(/*IsSigned*/ false, CUList.size() - 1);
+ TUIndexForm = DIEInteger::BestForm(
+ /*IsSigned*/ false, LocalTUList.size() + ForeignTUList.size() - 1);
+ const dwarf::FormParams FormParams{5, 4, dwarf::DwarfFormat::DWARF32, false};
+ CUIndexEncodingSize = *dwarf::getFixedFormByteSize(CUIndexForm, FormParams);
+ TUIndexEncodingSize = *dwarf::getFixedFormByteSize(TUIndexForm, FormParams);
+}
+
+DWARF5AcceleratorTable::TagIndex DWARF5AcceleratorTable::getAbbrevIndex(
+ const unsigned DieTag,
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet,
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+ &SecondEntryRet) {
+ AbbrevDescriptor AbbrvDesc;
+ auto setFields =
+ [&](const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &Entry)
+ -> void {
+ if (!Entry)
+ return;
+ switch (Entry->Encoding.Index) {
+ case dwarf::DW_IDX_compile_unit:
+ AbbrvDesc.Bits.CompUnit = true;
+ break;
+ case dwarf::DW_IDX_type_unit:
+ AbbrvDesc.Bits.TypeUnit = true;
+ break;
+ case dwarf::DW_IDX_parent:
+ AbbrvDesc.Bits.Parent = true;
+ break;
+ case dwarf::DW_IDX_type_hash:
+ AbbrvDesc.Bits.TypeHash = true;
+ break;
+ default:
+ return;
+ }
+ };
+ setFields(EntryRet);
+ setFields(SecondEntryRet);
+ AbbrvDesc.Bits.DieOffset = true;
+ AbbrvDesc.Bits.Tag = DieTag;
+ auto Iter = AbbrevTagToIndexMap.insert(
+ {AbbrvDesc.Value, static_cast<uint32_t>(AbbrevTagToIndexMap.size() + 1)});
+ return {DieTag, Iter.first->second};
+}
+
+std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+DWARF5AcceleratorTable::getIndexForEntry(
+ const BOLTDWARF5AccelTableData &Value) const {
+ if (Value.isTU())
+ return {{Value.getUnitID(), {dwarf::DW_IDX_type_unit, TUIndexForm}}};
+ if (CUList.size() > 1)
+ return {{Value.getUnitID(), {dwarf::DW_IDX_compile_unit, CUIndexForm}}};
+ return std::nullopt;
+}
+
+std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+DWARF5AcceleratorTable::getSecondIndexForEntry(
+ const BOLTDWARF5AccelTableData &Value) const {
+ if (Value.isTU() && CUList.size() > 1 && Value.getSecondUnitID())
+ return {
+ {*Value.getSecondUnitID(), {dwarf::DW_IDX_compile_unit, CUIndexForm}}};
+ return std::nullopt;
+}
+
+void DWARF5AcceleratorTable::populateAbbrevsMap() {
+ for (auto &Bucket : getBuckets()) {
+ for (DWARF5AcceleratorTable::HashData *Hash : Bucket) {
+ for (BOLTDWARF5AccelTableData *Value : Hash->Values) {
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
+ getIndexForEntry(*Value);
+ // For entries that need to refer to the foreign type units and to
+ // the CU.
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
+ SecondEntryRet = getSecondIndexForEntry(*Value);
+ const unsigned Tag = Value->getDieTag();
+ const TagIndex AbbrvTag = getAbbrevIndex(Tag, EntryRet, SecondEntryRet);
+ if (Abbreviations.count(AbbrvTag) == 0) {
+ SmallVector<DWARF5AccelTableData::AttributeEncoding, 2> UA;
+ if (EntryRet)
+ UA.push_back(EntryRet->Encoding);
+ if (SecondEntryRet)
+ UA.push_back(SecondEntryRet->Encoding);
+ UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
+ Abbreviations.try_emplace(AbbrvTag, UA);
+ }
+ }
+ }
+ }
+}
+
+void DWARF5AcceleratorTable::writeEntry(const BOLTDWARF5AccelTableData &Entry) {
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
+ getIndexForEntry(Entry);
+ // For forgeign type (FTU) units that need to refer to the FTU and to the CU.
+ const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> SecondEntryRet =
+ getSecondIndexForEntry(Entry);
+ const TagIndex TagIndexVal =
+ getAbbrevIndex(Entry.getDieTag(), EntryRet, SecondEntryRet);
+ auto AbbrevIt = Abbreviations.find(TagIndexVal);
+ assert(AbbrevIt != Abbreviations.end() &&
+ "Why wasn't this abbrev generated?");
+ encodeULEB128(TagIndexVal.Index, *Entriestream);
+ auto writeIndex = [&](uint32_t Index, uint32_t IndexSize) -> void {
+ switch (IndexSize) {
+ default:
+ llvm_unreachable("Unsupported Index Size!");
+ break;
+ case sizeof(uint8_t):
+ support::endian::write(*Entriestream, static_cast<uint8_t>(Index),
+ llvm::endianness::little);
+ break;
+ case sizeof(uint16_t):
+ support::endian::write(*Entriestream, static_cast<uint16_t>(Index),
+ llvm::endianness::little);
+ break;
+ case sizeof(uint32_t):
+ support::endian::write(*Entriestream, static_cast<uint32_t>(Index),
+ llvm::endianness::little);
+ break;
+ };
+ };
+
+ for (const DWARF5AccelTableData::AttributeEncoding &AttrEnc :
+ AbbrevIt->second) {
+ switch (AttrEnc.Index) {
+ default: {
+ llvm_unreachable("Unexpected index attribute!");
+ break;
+ }
+ case dwarf::DW_IDX_compile_unit: {
+ const unsigned CUIndex =
+ SecondEntryRet ? SecondEntryRet->Index : EntryRet->Index;
+ writeIndex(CUIndex, CUIndexEncodingSize);
+ break;
+ }
+ case dwarf::DW_IDX_type_unit: {
+ writeIndex(EntryRet->Index, TUIndexEncodingSize);
+ break;
+ }
+ case dwarf::DW_IDX_die_offset: {
+ assert(AttrEnc.Form == dwarf::DW_FORM_ref4);
+ support::endian::write(*Entriestream,
+ static_cast<uint32_t>(Entry.getDieOffset()),
+ llvm::endianness::little);
+ break;
+ }
+ }
+ }
+}
+
+void DWARF5AcceleratorTable::writeEntries() {
+ for (auto &Bucket : getBuckets()) {
+ for (DWARF5AcceleratorTable::HashData *Hash : Bucket) {
+ Hash->EntryOffset = EntriesBuffer->size();
+ for (const BOLTDWARF5AccelTableData *Value : Hash->Values) {
+ writeEntry(*Value);
+ }
+ support::endian::write(*Entriestream, static_cast<uint8_t>(0),
+ llvm::endianness::little);
+ }
+ }
+}
+
+void DWARF5AcceleratorTable::writeAugmentationString() {
+ // String needs to be multiple of 4 bytes.
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('B'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('O'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('L'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('T'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('0'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('0'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('0'),
+ llvm::endianness::little);
+ support::endian::write(*AugStringtream, static_cast<uint8_t>('0'),
+ llvm::endianness::little);
+ AugmentationStringSize = AugStringBuffer->size();
+}
+
+/// Calculates size of .debug_names header without Length field.
+static constexpr uint32_t getDebugNamesHeaderSize() {
+ constexpr uint16_t VersionLength = sizeof(uint16_t);
+ constexpr uint16_t PaddingLength = sizeof(uint16_t);
+ constexpr uint32_t CompUnitCountLength = sizeof(uint32_t);
+ constexpr uint32_t LocalTypeUnitCountLength = sizeof(uint32_t);
+ constexpr uint32_t ForeignTypeUnitCountLength = sizeof(uint32_t);
+ constexpr uint32_t BucketCountLength = sizeof(uint32_t);
+ constexpr uint32_t NameCountLength = sizeof(uint32_t);
+ constexpr uint32_t AbbrevTableSizeLength = sizeof(uint32_t);
+ constexpr uint32_t AugmentationStringSizeLenght = sizeof(uint32_t);
+ return VersionLength + PaddingLength + CompUnitCountLength +
+ LocalTypeUnitCountLength + ForeignTypeUnitCountLength +
+ BucketCountLength + NameCountLength + AbbrevTableSizeLength +
+ AugmentationStringSizeLenght;
+}
+
+void DWARF5AcceleratorTable::emitHeader() const {
+ constexpr uint32_t HeaderSize = getDebugNamesHeaderSize();
+ // Header Length
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(HeaderSize + StrBuffer->size() +
+ AugmentationStringSize),
+ llvm::endianness::little);
+ // Version
+ support::endian::write(*FullTableStream, static_cast<uint16_t>(5),
+ llvm::endianness::little);
+ // Padding
+ support::endian::write(*FullTableStream, static_cast<uint16_t>(0),
+ llvm::endianness::little);
+ // Compilation Unit Count
+ support::endian::write(*FullTableStream, static_cast<uint32_t>(CUList.size()),
+ llvm::endianness::little);
+ // Local Type Unit Count
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(LocalTUList.size()),
+ llvm::endianness::little);
+ // Foreign Type Unit Count
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(ForeignTUList.size()),
+ llvm::endianness::little);
+ // Bucket Count
+ support::endian::write(*FullTableStream, static_cast<uint32_t>(BucketCount),
+ llvm::endianness::little);
+ // Name Count
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(Entries.size()),
+ llvm::endianness::little);
+ // Abbrev Table Size
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(AbbrevTableSize),
+ llvm::endianness::little);
+ // Augmentation String Size
+ support::endian::write(*FullTableStream,
+ static_cast<uint32_t>(AugmentationStringSize),
+ llvm::endianness::little);
+
+ emitAugmentationString();
+ FullTableStream->write(StrBuffer->data(), StrBuffer->size());
+}
+
+void DWARF5AcceleratorTable::emitCUList() const {
+ for (const uint32_t CUID : CUList)
+ support::endian::write(*StrStream, CUID, llvm::endianness::little);
+}
+void DWARF5AcceleratorTable::emitTUList() const {
+ for (const uint32_t TUID : LocalTUList)
+ support::endian::write(*StrStream, TUID, llvm::endianness::little);
+
+ for (const uint64_t TUID : ForeignTUList)
+ support::endian::write(*StrStream, TUID, llvm::endianness::little);
+}
+void DWARF5AcceleratorTable::emitBuckets() const {
+ uint32_t Index = 1;
+ for (const auto &Bucket : enumerate(getBuckets())) {
+ const uint32_t TempIndex = Bucket.value().empty() ? 0 : Index;
+ support::endian::write(*StrStream, TempIndex, llvm::endianness::little);
+ Index += Bucket.value().size();
+ }
+}
+void DWARF5AcceleratorTable::emitHashes() const {
+ for (const auto &Bucket : getBuckets()) {
+ for (const DWARF5AcceleratorTable::HashData *Hash : Bucket)
+ support::endian::write(*StrStream, Hash->HashValue,
+ llvm::endianness::little);
+ }
+}
+void DWARF5AcceleratorTable::emitStringOffsets() const {
+ for (const auto &Bucket : getBuckets()) {
+ for (const DWARF5AcceleratorTable::HashData *Hash : Bucket)
+ support::endian::write(*StrStream, static_cast<uint32_t>(Hash->StrOffset),
+ llvm::endianness::little);
+ }
+}
+void DWARF5AcceleratorTable::emitOffsets() const {
+ for (const auto &Bucket : getBuckets()) {
+ for (const DWARF5AcceleratorTable::HashData *Hash : Bucket)
+ support::endian::write(*StrStream,
+ static_cast<uint32_t>(Hash->EntryOffset),
+ llvm::endianness::little);
+ }
+}
+void DWARF5AcceleratorTable::emitAbbrevs() {
+ const uint32_t AbbrevTableStart = StrBuffer->size();
+ for (const auto &Abbrev : Abbreviations) {
+ encodeULEB128(Abbrev.first.Index, *StrStream);
+ encodeULEB128(Abbrev.first.DieTag, *StrStream);
+ for (const auto &AttrEnc : Abbrev.second) {
+ encodeULEB128(AttrEnc.Index, *StrStream);
+ encodeULEB128(AttrEnc.Form, *StrStream);
+ }
+ encodeULEB128(0, *StrStream);
+ encodeULEB128(0, *StrStream);
+ }
+ encodeULEB128(0, *StrStream);
+ AbbrevTableSize = StrBuffer->size() - AbbrevTableStart;
+}
+void DWARF5AcceleratorTable::emitData() {
+ StrStream->write(EntriesBuffer->data(), EntriesBuffer->size());
+}
+void DWARF5AcceleratorTable::emitAugmentationString() const {
+ FullTableStream->write(AugStringBuffer->data(), AugStringBuffer->size());
+}
+void DWARF5AcceleratorTable::emitAccelTable() {
+ if (!NeedToCreate)
+ return;
+ finalize();
+ populateAbbrevsMap();
+ writeEntries();
+ writeAugmentationString();
+ emitCUList();
+ emitTUList();
+ emitBuckets();
+ emitHashes();
+ emitStringOffsets();
+ emitOffsets();
+ emitAbbrevs();
+ emitData();
+ emitHeader();
+}
+} // namespace bolt
+} // namespace llvm
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index cefccbdfa2f012..4f1b725f1c6cd3 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -347,6 +347,12 @@ static cl::opt<bool>
"multiple non-relocatable dwarf object files (dwo)."),
cl::init(false), cl::cat(BoltCategory));
+static cl::opt<bool> CreateDebugNames(
+ "create-debug-names-section",
+ cl::desc("Creates .debug_names section, if the input binary doesn't have "
+ "it already, for DWARF5 CU/TUs."),
+ cl::init(false), cl::cat(BoltCategory));
+
static cl::opt<bool>
DebugSkeletonCu("debug-skeleton-cu",
cl::desc("prints out offsetrs for abbrev and debu_info of "
@@ -692,6 +698,8 @@ void DWARFRewriter::updateDebugInfo() {
return ObjectName;
};
+ DWARF5AcceleratorTable DebugNamesTable(opts::CreateDebugNames, BC,
+ *StrWriter);
DWPState State;
if (opts::WriteDWP)
initDWPState(State);
@@ -709,7 +717,8 @@ void DWARFRewriter::updateDebugInfo() {
: LegacyRangesSectionWriter.get();
// Skipping CUs that failed to load.
if (SplitCU) {
- DIEBuilder DWODIEBuilder(&(*SplitCU)->getContext(), true);
+ DIEBuilder DWODIEBuilder(&(*SplitCU)->getContext(), DebugNamesTable,
+ Unit);
DWODIEBuilder.buildDWOUnit(**SplitCU);
std::string DWOName = updateDWONameCompDir(
*Unit, *DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
@@ -754,7 +763,7 @@ void DWARFRewriter::updateDebugInfo() {
AddrWriter->update(*DIEBlder, *Unit);
};
- DIEBuilder DIEBlder(BC.DwCtx.get());
+ DIEBuilder DIEBlder(BC.DwCtx.get(), DebugNamesTable);
DIEBlder.buildTypeUnits(StrOffstsWriter.get());
SmallVector<char, 20> OutBuffer;
std::unique_ptr<raw_svector_ostream> ObjOS =
@@ -786,10 +795,13 @@ void DWARFRewriter::updateDebugInfo() {
ThreadPool.wait();
}
+ DebugNamesTable.emitAccelTable();
+
if (opts::WriteDWP)
finalizeDWP(State);
- finalizeDebugSections(DIEBlder, *Streamer, *ObjOS, OffsetMap);
+ finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS,
+ OffsetMap);
updateGdbIndexSection(OffsetMap, CUIndex);
}
@@ -1523,10 +1535,9 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder,
return CUMap;
}
-void DWARFRewriter::finalizeDebugSections(DIEBuilder &DIEBlder,
- DIEStreamer &Streamer,
- raw_svector_ostream &ObjOS,
- CUOffsetMap &CUMap) {
+void DWARFRewriter::finalizeDebugSections(
+ DIEBuilder &DIEBlder, DWARF5AcceleratorTable &DebugNamesTable,
+ DIEStreamer &Streamer, raw_svector_ostream &ObjOS, CUOffsetMap &CUMap) {
if (StrWriter->isInitialized()) {
RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
@@ -1624,6 +1635,15 @@ void DWARFRewriter::finalizeDebugSections(DIEBuilder &DIEBlder,
copyByteArray(ARangesContents),
ARangesContents.size());
}
+
+ if (DebugNamesTable.isCreated()) {
+ RewriteInstance::addToDebugSectionsToOverwrite(".debug_names");
+ std::unique_ptr<DebugBufferVector> DebugNamesSectionContents =
+ DebugNamesTable.releaseBuffer();
+ BC.registerOrUpdateNoteSection(".debug_names",
+ copyByteArray(*DebugNamesSectionContents),
+ DebugNamesSectionContents->size());
+ }
}
void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
diff --git a/bolt/test/X86/Inputs/dwarf5-debug-names-helper.s b/bolt/test/X86/Inputs/dwarf5-debug-names-helper.s
new file mode 100644
index 00000000000000..f10417bd0cebe9
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-debug-names-helper.s
@@ -0,0 +1,487 @@
+# clang++ -g2 -gdwarf-5 -gpubnames -fdebug-types-section -S
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# helper.cpp
+# #include "header.h"
+# int fooint;
+# struct Foo2Int {
+# int *c1;
+# int *c2;
+# };
+#
+# int foo() {
+# Foo2Int fint;
+# Foo2a f;
+# return 0;
+# }
+
+ .text
+ .file "helper.cpp"
+ .file 0 "/typeDedup" "helper.cpp" md5 0xc33186b2db66a78883b1546aace9855d
+ .globl _Z3foov # -- Begin function _Z3foov
+ .p2align 4, 0x90
+ .type _Z3foov, at function
+_Z3foov: # @_Z3foov
+.Lfunc_begin0:
+ .loc 0 8 0 # helper.cpp:8:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp0:
+ .loc 0 11 3 prologue_end # helper.cpp:11:3
+ xorl %eax, %eax
+ .loc 0 11 3 epilogue_begin is_stmt 0 # helper.cpp:11:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z3foov, .Lfunc_end0-_Z3foov
+ .cfi_endproc
+ # -- End function
+ .type fooint, at object # @fooint
+ .bss
+ .globl fooint
+ .p2align 2, 0x0
+fooint:
+ .long 0 # 0x0
+ .size fooint, 4
+
+ .file 1 "." "header.h" md5 0xfea7bb1f22c47f129e15695f7137a1e7
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x97 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 2 # Abbrev [2] 0x23:0xb DW_TAG_variable
+ .byte 3 # DW_AT_name
+ .long 46 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 3 # Abbrev [3] 0x2e:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 4 # Abbrev [4] 0x32:0x27 DW_TAG_subprogram
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 5 # DW_AT_linkage_name
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .long 46 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x42:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 7 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 89 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x4d:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 88
+ .byte 11 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 119 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x59:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 10 # DW_AT_name
+ .byte 16 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 7 # Abbrev [7] 0x5f:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 7 # Abbrev [7] 0x68:0x9 DW_TAG_member
+ .byte 9 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 8 # Abbrev [8] 0x72:0x5 DW_TAG_pointer_type
+ .long 46 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x77:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 14 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 7 # Abbrev [7] 0x7d:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 153 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 7 # Abbrev [7] 0x86:0x9 DW_TAG_member
+ .byte 9 # DW_AT_name
+ .long 153 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 7 # Abbrev [7] 0x8f:0x9 DW_TAG_member
+ .byte 13 # DW_AT_name
+ .long 153 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 8 # Abbrev [8] 0x99:0x5 DW_TAG_pointer_type
+ .long 158 # DW_AT_type
+ .byte 3 # Abbrev [3] 0x9e:0x4 DW_TAG_base_type
+ .byte 12 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 64 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0git" # string offset=0
+.Linfo_string1:
+ .asciz "helper.cpp" # string offset=24
+.Linfo_string2:
+ .asciz "/home/ayermolo/local/tasks/T138552329/typeDedup" # string offset=35
+.Linfo_string3:
+ .asciz "fooint" # string offset=83
+.Linfo_string4:
+ .asciz "int" # string offset=90
+.Linfo_string5:
+ .asciz "foo" # string offset=94
+.Linfo_string6:
+ .asciz "_Z3foov" # string offset=98
+.Linfo_string7:
+ .asciz "fint" # string offset=106
+.Linfo_string8:
+ .asciz "Foo2Int" # string offset=111
+.Linfo_string9:
+ .asciz "c1" # string offset=119
+.Linfo_string10:
+ .asciz "c2" # string offset=122
+.Linfo_string11:
+ .asciz "f" # string offset=125
+.Linfo_string12:
+ .asciz "Foo2a" # string offset=127
+.Linfo_string13:
+ .asciz "char" # string offset=133
+.Linfo_string14:
+ .asciz "c3" # string offset=138
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .long .Linfo_string6
+ .long .Linfo_string5
+ .long .Linfo_string7
+ .long .Linfo_string9
+ .long .Linfo_string10
+ .long .Linfo_string8
+ .long .Linfo_string11
+ .long .Linfo_string13
+ .long .Linfo_string14
+ .long .Linfo_string12
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad fooint
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 7 # Header: bucket count
+ .long 7 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long 1 # Bucket 0
+ .long 0 # Bucket 1
+ .long 2 # Bucket 2
+ .long 3 # Bucket 3
+ .long 0 # Bucket 4
+ .long 5 # Bucket 5
+ .long 7 # Bucket 6
+ .long -1257882357 # Hash in Bucket 0
+ .long -1168750522 # Hash in Bucket 2
+ .long 193495088 # Hash in Bucket 3
+ .long 259227804 # Hash in Bucket 3
+ .long 193491849 # Hash in Bucket 5
+ .long 2090147939 # Hash in Bucket 5
+ .long -35356620 # Hash in Bucket 6
+ .long .Linfo_string6 # String in Bucket 0: _Z3foov
+ .long .Linfo_string8 # String in Bucket 2: Foo2Int
+ .long .Linfo_string4 # String in Bucket 3: int
+ .long .Linfo_string12 # String in Bucket 3: Foo2a
+ .long .Linfo_string5 # String in Bucket 5: foo
+ .long .Linfo_string13 # String in Bucket 5: char
+ .long .Linfo_string3 # String in Bucket 6: fooint
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 2
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 6
+.Lnames_abbrev_start0:
+ .ascii "\230." # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230\023" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230$" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\2304" # Abbrev code
+ .byte 52 # DW_TAG_variable
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames3:
+.L0:
+ .ascii "\230." # Abbreviation code
+ .long 50 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: _Z3foov
+.Lnames4:
+.L5:
+ .ascii "\230\023" # Abbreviation code
+ .long 89 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2Int
+.Lnames0:
+.L2:
+ .ascii "\230$" # Abbreviation code
+ .long 46 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: int
+.Lnames5:
+.L3:
+ .ascii "\230\023" # Abbreviation code
+ .long 119 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2a
+.Lnames2:
+ .ascii "\230." # Abbreviation code
+ .long 50 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: foo
+.Lnames6:
+.L1:
+ .ascii "\230$" # Abbreviation code
+ .long 158 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: char
+.Lnames1:
+.L4:
+ .ascii "\2304" # Abbreviation code
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: fooint
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-debug-names-main.s b/bolt/test/X86/Inputs/dwarf5-debug-names-main.s
new file mode 100644
index 00000000000000..2d3f4d2d208f5e
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-debug-names-main.s
@@ -0,0 +1,712 @@
+# clang++ -g2 -gdwarf-5 -gpubnames -fdebug-types-section
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# main.cpp
+# #include "header.h"
+# extern int fooint;
+# namespace {
+# struct t1 {
+# int i;
+# };
+# }
+# template <int *> struct t2 {
+# t1 v1;
+# };
+# struct t3 {
+# t2<&fooint> v1;
+# };
+# t3 v1;
+#
+# struct Foo {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# struct Foo2 {
+# char *c1;
+# char *c2;
+# };
+# int main(int argc, char *argv[]) {
+# Foo f;
+# Foo2 f2;
+# Foo2a f3;
+# return 0;
+# }
+ .text
+ .file "main.cpp"
+ .file 0 "/typeDedup" "main.cpp" md5 0x04e636082b2b8a95a6ca39dde52372ae
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .loc 0 25 0 # main.cpp:25:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+.Ltmp0:
+ .loc 0 29 2 prologue_end # main.cpp:29:2
+ xorl %eax, %eax
+ .loc 0 29 2 epilogue_begin is_stmt 0 # main.cpp:29:2
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .type v1, at object # @v1
+ .bss
+ .globl v1
+ .p2align 2, 0x0
+v1:
+ .zero 4
+ .size v1, 4
+
+ .file 1 "." "header.h" md5 0xfea7bb1f22c47f129e15695f7137a1e7
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 48 # DW_TAG_template_value_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 57 # DW_TAG_namespace
+ .byte 1 # DW_CHILDREN_yes
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x11a DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 2 # Abbrev [2] 0x23:0xb DW_TAG_variable
+ .byte 3 # DW_AT_name
+ .long 46 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 14 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 1
+ .byte 3 # Abbrev [3] 0x2e:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 8 # DW_AT_name
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 11 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x34:0x9 DW_TAG_member
+ .byte 3 # DW_AT_name
+ .long 62 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 12 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 3 # Abbrev [3] 0x3e:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 7 # DW_AT_name
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .byte 5 # Abbrev [5] 0x44:0x9 DW_TAG_template_value_parameter
+ .long 87 # DW_AT_type
+ .byte 3 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 159
+ .byte 4 # Abbrev [4] 0x4d:0x9 DW_TAG_member
+ .byte 3 # DW_AT_name
+ .long 97 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x57:0x5 DW_TAG_pointer_type
+ .long 92 # DW_AT_type
+ .byte 7 # Abbrev [7] 0x5c:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 8 # Abbrev [8] 0x60:0x12 DW_TAG_namespace
+ .byte 3 # Abbrev [3] 0x61:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 6 # DW_AT_name
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x67:0x9 DW_TAG_member
+ .byte 5 # DW_AT_name
+ .long 92 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x72:0x48 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 9 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 25 # DW_AT_decl_line
+ .long 92 # DW_AT_type
+ # DW_AT_external
+ .byte 10 # Abbrev [10] 0x81:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .byte 10 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 25 # DW_AT_decl_line
+ .long 92 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x8c:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 11 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 25 # DW_AT_decl_line
+ .long 186 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x97:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 88
+ .byte 13 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 26 # DW_AT_decl_line
+ .long 200 # DW_AT_type
+ .byte 11 # Abbrev [11] 0xa2:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 72
+ .byte 18 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 27 # DW_AT_decl_line
+ .long 234 # DW_AT_type
+ .byte 11 # Abbrev [11] 0xad:0xc DW_TAG_variable
+ .byte 3 # DW_AT_location
+ .byte 145
+ .ascii "\260\177"
+ .byte 20 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 28 # DW_AT_decl_line
+ .long 259 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0xba:0x5 DW_TAG_pointer_type
+ .long 191 # DW_AT_type
+ .byte 6 # Abbrev [6] 0xbf:0x5 DW_TAG_pointer_type
+ .long 196 # DW_AT_type
+ .byte 7 # Abbrev [7] 0xc4:0x4 DW_TAG_base_type
+ .byte 12 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 3 # Abbrev [3] 0xc8:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 17 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 16 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0xce:0x9 DW_TAG_member
+ .byte 14 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 17 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0xd7:0x9 DW_TAG_member
+ .byte 15 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 18 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0xe0:0x9 DW_TAG_member
+ .byte 16 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 19 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 3 # Abbrev [3] 0xea:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 19 # DW_AT_name
+ .byte 16 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 21 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0xf0:0x9 DW_TAG_member
+ .byte 14 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 22 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0xf9:0x9 DW_TAG_member
+ .byte 15 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 23 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 3 # Abbrev [3] 0x103:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 21 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x109:0x9 DW_TAG_member
+ .byte 14 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x112:0x9 DW_TAG_member
+ .byte 15 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x11b:0x9 DW_TAG_member
+ .byte 16 # DW_AT_name
+ .long 191 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 92 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0git" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=24
+.Linfo_string2:
+ .asciz "/home/ayermolo/local/tasks/T138552329/typeDedup" # string offset=33
+.Linfo_string3:
+ .asciz "v1" # string offset=81
+.Linfo_string4:
+ .asciz "t3" # string offset=84
+.Linfo_string5:
+ .asciz "t2<&fooint>" # string offset=87
+.Linfo_string6:
+ .asciz "int" # string offset=99
+.Linfo_string7:
+ .asciz "(anonymous namespace)" # string offset=103
+.Linfo_string8:
+ .asciz "t1" # string offset=125
+.Linfo_string9:
+ .asciz "i" # string offset=128
+.Linfo_string10:
+ .asciz "main" # string offset=130
+.Linfo_string11:
+ .asciz "argc" # string offset=135
+.Linfo_string12:
+ .asciz "argv" # string offset=140
+.Linfo_string13:
+ .asciz "char" # string offset=145
+.Linfo_string14:
+ .asciz "f" # string offset=150
+.Linfo_string15:
+ .asciz "Foo" # string offset=152
+.Linfo_string16:
+ .asciz "c1" # string offset=156
+.Linfo_string17:
+ .asciz "c2" # string offset=159
+.Linfo_string18:
+ .asciz "c3" # string offset=162
+.Linfo_string19:
+ .asciz "f2" # string offset=165
+.Linfo_string20:
+ .asciz "Foo2" # string offset=168
+.Linfo_string21:
+ .asciz "f3" # string offset=173
+.Linfo_string22:
+ .asciz "Foo2a" # string offset=176
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string6
+ .long .Linfo_string9
+ .long .Linfo_string8
+ .long .Linfo_string5
+ .long .Linfo_string4
+ .long .Linfo_string10
+ .long .Linfo_string11
+ .long .Linfo_string12
+ .long .Linfo_string13
+ .long .Linfo_string14
+ .long .Linfo_string16
+ .long .Linfo_string17
+ .long .Linfo_string18
+ .long .Linfo_string15
+ .long .Linfo_string19
+ .long .Linfo_string20
+ .long .Linfo_string21
+ .long .Linfo_string22
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad fooint
+ .quad v1
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 11 # Header: bucket count
+ .long 11 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long 1 # Bucket 0
+ .long 3 # Bucket 1
+ .long 5 # Bucket 2
+ .long 0 # Bucket 3
+ .long 0 # Bucket 4
+ .long 6 # Bucket 5
+ .long 8 # Bucket 6
+ .long 9 # Bucket 7
+ .long 11 # Bucket 8
+ .long 0 # Bucket 9
+ .long 0 # Bucket 10
+ .long 259227804 # Hash in Bucket 0
+ .long 2090147939 # Hash in Bucket 0
+ .long 193491849 # Hash in Bucket 1
+ .long 958480634 # Hash in Bucket 1
+ .long 2090263771 # Hash in Bucket 2
+ .long 5863786 # Hash in Bucket 5
+ .long 5863852 # Hash in Bucket 5
+ .long 193495088 # Hash in Bucket 6
+ .long 5863788 # Hash in Bucket 7
+ .long 2090499946 # Hash in Bucket 7
+ .long -1929613044 # Hash in Bucket 8
+ .long .Linfo_string22 # String in Bucket 0: Foo2a
+ .long .Linfo_string13 # String in Bucket 0: char
+ .long .Linfo_string15 # String in Bucket 1: Foo
+ .long .Linfo_string5 # String in Bucket 1: t2<&fooint>
+ .long .Linfo_string20 # String in Bucket 2: Foo2
+ .long .Linfo_string8 # String in Bucket 5: t1
+ .long .Linfo_string3 # String in Bucket 5: v1
+ .long .Linfo_string6 # String in Bucket 6: int
+ .long .Linfo_string4 # String in Bucket 7: t3
+ .long .Linfo_string10 # String in Bucket 7: main
+ .long .Linfo_string7 # String in Bucket 8: (anonymous namespace)
+ .long .Lnames10-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames7-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames8-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames9-.Lnames_entries0 # Offset in Bucket 2
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames5-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 6
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 7
+ .long .Lnames6-.Lnames_entries0 # Offset in Bucket 7
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 8
+.Lnames_abbrev_start0:
+ .ascii "\2309" # Abbrev code
+ .byte 57 # DW_TAG_namespace
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\270\023" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230\023" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230$" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\2304" # Abbrev code
+ .byte 52 # DW_TAG_variable
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230." # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames10:
+.L1:
+ .ascii "\230\023" # Abbreviation code
+ .long 259 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2a
+.Lnames7:
+.L8:
+ .ascii "\230$" # Abbreviation code
+ .long 196 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: char
+.Lnames8:
+.L0:
+ .ascii "\230\023" # Abbreviation code
+ .long 200 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo
+.Lnames1:
+.L2:
+ .ascii "\230\023" # Abbreviation code
+ .long 62 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: t2<&fooint>
+.Lnames9:
+.L9:
+ .ascii "\230\023" # Abbreviation code
+ .long 234 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2
+.Lnames4:
+.L5:
+ .ascii "\270\023" # Abbreviation code
+ .long 97 # DW_IDX_die_offset
+ .long .L3-.Lnames_entries0 # DW_IDX_parent
+ .byte 0 # End of list: t1
+.Lnames5:
+.L7:
+ .ascii "\2304" # Abbreviation code
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: v1
+.Lnames2:
+.L10:
+ .ascii "\230$" # Abbreviation code
+ .long 92 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: int
+.Lnames0:
+.L6:
+ .ascii "\230\023" # Abbreviation code
+ .long 46 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: t3
+.Lnames6:
+.L4:
+ .ascii "\230." # Abbreviation code
+ .long 114 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: main
+.Lnames3:
+.L3:
+ .ascii "\2309" # Abbreviation code
+ .long 96 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: (anonymous namespace)
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-debug-names-helper.s b/bolt/test/X86/Inputs/dwarf5-df-debug-names-helper.s
new file mode 100644
index 00000000000000..8a53bda5f71240
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-debug-names-helper.s
@@ -0,0 +1,326 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-compilation-dir='.'
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# helper.cpp
+# #include "header.h"
+# struct Foo2Int {
+# int *c1;
+# int *c2;
+# };
+# Foo2Int fint;
+# const Foo2a f{nullptr, nullptr};
+
+ .text
+ .file "helper.cpp"
+ .file 0 "." "helper.cpp" md5 0x2804efac708fd4180d403e6d5dbcc54a
+ .type fint, at object # @fint
+ .bss
+ .globl fint
+ .p2align 3, 0x0
+fint:
+ .zero 16
+ .size fint, 16
+
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 3223434782003797151
+ .byte 1 # Abbrev [1] 0x14:0xf DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "Foo2Int" # string offset=2
+.Lskel_string2:
+ .asciz "int" # string offset=10
+.Lskel_string3:
+ .asciz "fint" # string offset=14
+.Lskel_string4:
+ .asciz "helper.dwo" # string offset=19
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string4
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 36 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "fint" # string offset=0
+.Linfo_string1:
+ .asciz "c1" # string offset=5
+.Linfo_string2:
+ .asciz "int" # string offset=8
+.Linfo_string3:
+ .asciz "c2" # string offset=12
+.Linfo_string4:
+ .asciz "Foo2Int" # string offset=15
+.Linfo_string5:
+ .asciz "clang version 19.0.0git (git at github.com:ayermolo/llvm-project.git da9e9277be64deca73370a90d22af33e5b37cc52)" # string offset=23
+.Linfo_string6:
+ .asciz "helper.cpp" # string offset=131
+.Linfo_string7:
+ .asciz "helper.dwo" # string offset=142
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 5
+ .long 8
+ .long 12
+ .long 15
+ .long 23
+ .long 131
+ .long 142
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 3223434782003797151
+ .byte 1 # Abbrev [1] 0x14:0x34 DW_TAG_compile_unit
+ .byte 5 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 6 # DW_AT_name
+ .byte 7 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 3 # Abbrev [3] 0x25:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 4 # DW_AT_name
+ .byte 16 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x2b:0x9 DW_TAG_member
+ .byte 1 # DW_AT_name
+ .long 62 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x34:0x9 DW_TAG_member
+ .byte 3 # DW_AT_name
+ .long 62 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x3e:0x5 DW_TAG_pointer_type
+ .long 67 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x43:0x4 DW_TAG_base_type
+ .byte 2 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad fint
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 3 # Header: bucket count
+ .long 3 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long 1 # Bucket 0
+ .long 2 # Bucket 1
+ .long 3 # Bucket 2
+ .long -1168750522 # Hash in Bucket 0
+ .long 2090257270 # Hash in Bucket 1
+ .long 193495088 # Hash in Bucket 2
+ .long .Lskel_string1 # String in Bucket 0: Foo2Int
+ .long .Lskel_string3 # String in Bucket 1: fint
+ .long .Lskel_string2 # String in Bucket 2: int
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2
+.Lnames_abbrev_start0:
+ .ascii "\230\023" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\2304" # Abbrev code
+ .byte 52 # DW_TAG_variable
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230$" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames0:
+.L1:
+ .ascii "\230\023" # Abbreviation code
+ .long 37 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2Int
+.Lnames2:
+.L0:
+ .ascii "\2304" # Abbreviation code
+ .long 26 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: fint
+.Lnames1:
+.L2:
+ .ascii "\230$" # Abbreviation code
+ .long 67 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: int
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 19.0.0git (git at github.com:ayermolo/llvm-project.git da9e9277be64deca73370a90d22af33e5b37cc52)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-debug-names-main.s b/bolt/test/X86/Inputs/dwarf5-df-debug-names-main.s
new file mode 100644
index 00000000000000..7ca72132391751
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-debug-names-main.s
@@ -0,0 +1,493 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-compilation-dir='.'
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# main.cpp
+# #include "header.h"
+# struct Foo2 {
+# char *c1;
+# };
+# int main(int argc, char *argv[]) {
+# Foo2 f2;
+# Foo2a f3;
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 0 "." "main.cpp" md5 0x9c5cea5bb78d3fc265cd175110bfe903
+ .loc 0 5 0 # main.cpp:5:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+.Ltmp0:
+ .loc 0 8 2 prologue_end # main.cpp:8:2
+ xorl %eax, %eax
+ .loc 0 8 2 epilogue_begin is_stmt 0 # main.cpp:8:2
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .file 1 "." "header.h" md5 0xfea7bb1f22c47f129e15695f7137a1e7
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad -5618023701701543936
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main" # string offset=2
+.Lskel_string2:
+ .asciz "int" # string offset=7
+.Lskel_string3:
+ .asciz "char" # string offset=11
+.Lskel_string4:
+ .asciz "Foo2" # string offset=16
+.Lskel_string5:
+ .asciz "Foo2a" # string offset=21
+.Lskel_string6:
+ .asciz "main.dwo" # string offset=27
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string6
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 64 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "main" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=5
+.Linfo_string2:
+ .asciz "argc" # string offset=9
+.Linfo_string3:
+ .asciz "argv" # string offset=14
+.Linfo_string4:
+ .asciz "char" # string offset=19
+.Linfo_string5:
+ .asciz "f2" # string offset=24
+.Linfo_string6:
+ .asciz "c1" # string offset=27
+.Linfo_string7:
+ .asciz "Foo2" # string offset=30
+.Linfo_string8:
+ .asciz "f3" # string offset=35
+.Linfo_string9:
+ .asciz "c2" # string offset=38
+.Linfo_string10:
+ .asciz "c3" # string offset=41
+.Linfo_string11:
+ .asciz "Foo2a" # string offset=44
+.Linfo_string12:
+ .asciz "clang version 19.0.0git (git at github.com:ayermolo/llvm-project.git da9e9277be64deca73370a90d22af33e5b37cc52)" # string offset=50
+.Linfo_string13:
+ .asciz "main.cpp" # string offset=158
+.Linfo_string14:
+ .asciz "main.dwo" # string offset=167
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 5
+ .long 9
+ .long 14
+ .long 19
+ .long 24
+ .long 27
+ .long 30
+ .long 35
+ .long 38
+ .long 41
+ .long 44
+ .long 50
+ .long 158
+ .long 167
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad -5618023701701543936
+ .byte 1 # Abbrev [1] 0x14:0x87 DW_TAG_compile_unit
+ .byte 12 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 13 # DW_AT_name
+ .byte 14 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0x3c DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 0 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ # DW_AT_external
+ .byte 3 # Abbrev [3] 0x29:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .byte 2 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ .byte 3 # Abbrev [3] 0x34:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 90 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x3f:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 104
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 104 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x4a:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 80
+ .byte 8 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .long 120 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x56:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x5a:0x5 DW_TAG_pointer_type
+ .long 95 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x5f:0x5 DW_TAG_pointer_type
+ .long 100 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x64:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 7 # Abbrev [7] 0x68:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 7 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 8 # Abbrev [8] 0x6e:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 95 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 7 # Abbrev [7] 0x78:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 11 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 8 # Abbrev [8] 0x7e:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 95 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 8 # Abbrev [8] 0x87:0x9 DW_TAG_member
+ .byte 9 # DW_AT_name
+ .long 95 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 8 # Abbrev [8] 0x90:0x9 DW_TAG_member
+ .byte 10 # DW_AT_name
+ .long 95 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 5 # Header: bucket count
+ .long 5 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long 0 # Bucket 0
+ .long 1 # Bucket 1
+ .long 0 # Bucket 2
+ .long 3 # Bucket 3
+ .long 4 # Bucket 4
+ .long 2090263771 # Hash in Bucket 1
+ .long 2090499946 # Hash in Bucket 1
+ .long 193495088 # Hash in Bucket 3
+ .long 259227804 # Hash in Bucket 4
+ .long 2090147939 # Hash in Bucket 4
+ .long .Lskel_string4 # String in Bucket 1: Foo2
+ .long .Lskel_string1 # String in Bucket 1: main
+ .long .Lskel_string2 # String in Bucket 3: int
+ .long .Lskel_string5 # String in Bucket 4: Foo2a
+ .long .Lskel_string3 # String in Bucket 4: char
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4
+.Lnames_abbrev_start0:
+ .ascii "\230\023" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230." # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\230$" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames3:
+.L4:
+ .ascii "\230\023" # Abbreviation code
+ .long 104 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2
+.Lnames0:
+.L1:
+ .ascii "\230." # Abbreviation code
+ .long 26 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: main
+.Lnames1:
+.L3:
+ .ascii "\230$" # Abbreviation code
+ .long 86 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: int
+.Lnames4:
+.L2:
+ .ascii "\230\023" # Abbreviation code
+ .long 120 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: Foo2a
+.Lnames2:
+.L0:
+ .ascii "\230$" # Abbreviation code
+ .long 100 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: char
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 19.0.0git (git at github.com:ayermolo/llvm-project.git da9e9277be64deca73370a90d22af33e5b37cc52)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-helper.s b/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-helper.s
new file mode 100644
index 00000000000000..10842852eccdb1
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-helper.s
@@ -0,0 +1,650 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-types-section -fdebug-compilation-dir='.' -S
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# #include "header.h"
+# struct Foo2Int {
+# int *c1;
+# int *c2;
+# };
+# Foo2Int fint;
+# const Foo2a f{nullptr, nullptr};
+
+ .text
+ .file "helper.cpp"
+ .file 0 "." "helper.cpp" md5 0xc33186b2db66a78883b1546aace9855d
+ .globl _Z3foov # -- Begin function _Z3foov
+ .p2align 4, 0x90
+ .type _Z3foov, at function
+_Z3foov: # @_Z3foov
+.Lfunc_begin0:
+ .loc 0 8 0 # helper.cpp:8:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp0:
+ .loc 0 11 3 prologue_end # helper.cpp:11:3
+ xorl %eax, %eax
+ .loc 0 11 3 epilogue_begin is_stmt 0 # helper.cpp:11:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z3foov, .Lfunc_end0-_Z3foov
+ .cfi_endproc
+ # -- End function
+ .type fooint, at object # @fooint
+ .bss
+ .globl fooint
+ .p2align 2, 0x0
+fooint:
+ .long 0 # 0x0
+ .size fooint, 4
+
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 6 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad -3882554063269480080 # Type Signature
+ .long 33 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x2c DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .byte 5 # DW_AT_comp_dir
+ .byte 6 # DW_AT_dwo_name
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x21:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 9 # DW_AT_name
+ .byte 16 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x27:0x9 DW_TAG_member
+ .byte 7 # DW_AT_name
+ .long 58 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x30:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 58 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x3a:0x5 DW_TAG_pointer_type
+ .long 63 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x3f:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
+.Ldebug_info_dwo_start1:
+ .short 5 # DWARF version number
+ .byte 6 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 33 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x35 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .byte 5 # DW_AT_comp_dir
+ .byte 6 # DW_AT_dwo_name
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x21:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 13 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x27:0x9 DW_TAG_member
+ .byte 7 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x30:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x39:0x9 DW_TAG_member
+ .byte 12 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x43:0x5 DW_TAG_pointer_type
+ .long 72 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x48:0x4 DW_TAG_base_type
+ .byte 11 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end1:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 2142419470755914572
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "int" # string offset=2
+.Lskel_string2:
+ .asciz "fooint" # string offset=6
+.Lskel_string3:
+ .asciz "foo" # string offset=13
+.Lskel_string4:
+ .asciz "_Z3foov" # string offset=17
+.Lskel_string5:
+ .asciz "Foo2Int" # string offset=25
+.Lskel_string6:
+ .asciz "Foo2a" # string offset=33
+.Lskel_string7:
+ .asciz "char" # string offset=39
+.Lskel_string8:
+ .asciz "helper.dwo" # string offset=44
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string8
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 68 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "fooint" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=7
+.Linfo_string2:
+ .asciz "_Z3foov" # string offset=11
+.Linfo_string3:
+ .asciz "foo" # string offset=19
+.Linfo_string4:
+ .asciz "fint" # string offset=23
+.Linfo_string5:
+ .asciz "." # string offset=28
+.Linfo_string6:
+ .asciz "helper.dwo" # string offset=30
+.Linfo_string7:
+ .asciz "c1" # string offset=41
+.Linfo_string8:
+ .asciz "c2" # string offset=44
+.Linfo_string9:
+ .asciz "Foo2Int" # string offset=47
+.Linfo_string10:
+ .asciz "f" # string offset=55
+.Linfo_string11:
+ .asciz "char" # string offset=57
+.Linfo_string12:
+ .asciz "c3" # string offset=62
+.Linfo_string13:
+ .asciz "Foo2a" # string offset=65
+.Linfo_string14:
+ .asciz "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" # string offset=71
+.Linfo_string15:
+ .asciz "helper.cpp" # string offset=179
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 7
+ .long 11
+ .long 19
+ .long 23
+ .long 28
+ .long 30
+ .long 41
+ .long 44
+ .long 47
+ .long 55
+ .long 57
+ .long 62
+ .long 65
+ .long 71
+ .long 179
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
+.Ldebug_info_dwo_start2:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 2142419470755914572
+ .byte 6 # Abbrev [6] 0x14:0x4f DW_TAG_compile_unit
+ .byte 14 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 15 # DW_AT_name
+ .byte 6 # DW_AT_dwo_name
+ .byte 7 # Abbrev [7] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 5 # Abbrev [5] 0x25:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 8 # Abbrev [8] 0x29:0x27 DW_TAG_subprogram
+ .byte 1 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 2 # DW_AT_linkage_name
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 9 # Abbrev [9] 0x39:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 80 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x44:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 88
+ .byte 10 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 89 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 10 # Abbrev [10] 0x50:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad -3882554063269480080 # DW_AT_signature
+ .byte 10 # Abbrev [10] 0x59:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end2:
+ .section .debug_abbrev.dwo,"e", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 65 # DW_TAG_type_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 105 # DW_AT_signature
+ .byte 32 # DW_FORM_ref_sig8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_line.dwo,"e", at progbits
+.Ltmp2:
+ .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length
+.Ldebug_line_start0:
+ .short 5
+ .byte 8
+ .byte 0
+ .long .Lprologue_end0-.Lprologue_start0
+.Lprologue_start0:
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte -5
+ .byte 14
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 46
+ .byte 0
+ .byte 46
+ .byte 0
+ .byte 3
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 15
+ .byte 5
+ .byte 30
+ .byte 2
+ .ascii "helper.cpp"
+ .byte 0
+ .byte 0
+ .byte 0xc3, 0x31, 0x86, 0xb2
+ .byte 0xdb, 0x66, 0xa7, 0x88
+ .byte 0x83, 0xb1, 0x54, 0x6a
+ .byte 0xac, 0xe9, 0x85, 0x5d
+ .ascii "header.h"
+ .byte 0
+ .byte 1
+ .byte 0xfe, 0xa7, 0xbb, 0x1f
+ .byte 0x22, 0xc4, 0x7f, 0x12
+ .byte 0x9e, 0x15, 0x69, 0x5f
+ .byte 0x71, 0x37, 0xa1, 0xe7
+.Lprologue_end0:
+.Ldebug_line_end0:
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad fooint
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 2 # Header: foreign type unit count
+ .long 7 # Header: bucket count
+ .long 7 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .quad -3882554063269480080 # Type unit 0
+ .quad 1175092228111723119 # Type unit 1
+ .long 1 # Bucket 0
+ .long 0 # Bucket 1
+ .long 2 # Bucket 2
+ .long 3 # Bucket 3
+ .long 0 # Bucket 4
+ .long 5 # Bucket 5
+ .long 7 # Bucket 6
+ .long -1257882357 # Hash in Bucket 0
+ .long -1168750522 # Hash in Bucket 2
+ .long 193495088 # Hash in Bucket 3
+ .long 259227804 # Hash in Bucket 3
+ .long 193491849 # Hash in Bucket 5
+ .long 2090147939 # Hash in Bucket 5
+ .long -35356620 # Hash in Bucket 6
+ .long .Lskel_string4 # String in Bucket 0: _Z3foov
+ .long .Lskel_string5 # String in Bucket 2: Foo2Int
+ .long .Lskel_string1 # String in Bucket 3: int
+ .long .Lskel_string6 # String in Bucket 3: Foo2a
+ .long .Lskel_string3 # String in Bucket 5: foo
+ .long .Lskel_string7 # String in Bucket 5: char
+ .long .Lskel_string2 # String in Bucket 6: fooint
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 2
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames5-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 6
+.Lnames_abbrev_start0:
+ .ascii "\350\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\354\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\310\013" # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\210\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\210\r" # Abbrev code
+ .byte 52 # DW_TAG_variable
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\214\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames3:
+ .ascii "\310\013" # Abbreviation code
+ .long 41 # DW_IDX_die_offset
+ .byte 0 # End of list: _Z3foov
+.Lnames4:
+ .ascii "\354\004" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 33 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 80 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2Int
+.Lnames0:
+ .ascii "\210\t" # Abbreviation code
+ .long 37 # DW_IDX_die_offset
+ .ascii "\214\t" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 63 # DW_IDX_die_offset
+ .byte 0 # End of list: int
+.Lnames5:
+ .ascii "\354\004" # Abbreviation code
+ .byte 1 # DW_IDX_type_unit
+ .long 33 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 89 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2a
+.Lnames2:
+ .ascii "\310\013" # Abbreviation code
+ .long 41 # DW_IDX_die_offset
+ .byte 0 # End of list: foo
+.Lnames6:
+ .ascii "\214\t" # Abbreviation code
+ .byte 1 # DW_IDX_type_unit
+ .long 72 # DW_IDX_die_offset
+ .byte 0 # End of list: char
+.Lnames1:
+ .ascii "\210\r" # Abbreviation code
+ .long 26 # DW_IDX_die_offset
+ .byte 0 # End of list: fooint
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-main.s b/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-main.s
new file mode 100644
index 00000000000000..f89f28ec13f4eb
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-types-debug-names-main.s
@@ -0,0 +1,626 @@
+# clang++ -gsplit-dwarf -g2 -gdwarf-5 -gpubnames -fdebug-types-section -fdebug-compilation-dir='.' -S
+# header.h
+# struct Foo2a {
+# char *c1;
+# char *c2;
+# char *c3;
+# };
+# include "header.h"
+# struct Foo2 {
+# char *c1;
+# };
+# int main(int argc, char *argv[]) {
+# Foo2 f2;
+# Foo2a f3;
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 0 "." "main.cpp" md5 0x9c5cea5bb78d3fc265cd175110bfe903
+ .loc 0 5 0 # main.cpp:5:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+.Ltmp0:
+ .loc 0 8 2 prologue_end # main.cpp:8:2
+ xorl %eax, %eax
+ .loc 0 8 2 epilogue_begin is_stmt 0 # main.cpp:8:2
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 6 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 5322170643381124694 # Type Signature
+ .long 33 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x23 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .byte 6 # DW_AT_comp_dir
+ .byte 7 # DW_AT_dwo_name
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x21:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 9 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x27:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 49 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x31:0x5 DW_TAG_pointer_type
+ .long 54 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x36:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
+.Ldebug_info_dwo_start1:
+ .short 5 # DWARF version number
+ .byte 6 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 33 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x35 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .byte 6 # DW_AT_comp_dir
+ .byte 7 # DW_AT_dwo_name
+ .long 0 # DW_AT_stmt_list
+ .byte 2 # Abbrev [2] 0x21:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 13 # DW_AT_name
+ .byte 24 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x27:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x30:0x9 DW_TAG_member
+ .byte 11 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 8 # DW_AT_data_member_location
+ .byte 3 # Abbrev [3] 0x39:0x9 DW_TAG_member
+ .byte 12 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .byte 16 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x43:0x5 DW_TAG_pointer_type
+ .long 72 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x48:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end1:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 5962099678818150071
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ .byte 1 # DW_AT_dwo_name
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main" # string offset=53
+.Lskel_string2:
+ .asciz "int" # string offset=58
+.Lskel_string3:
+ .asciz "char" # string offset=62
+.Lskel_string4:
+ .asciz "Foo2" # string offset=67
+.Lskel_string5:
+ .asciz "Foo2a" # string offset=72
+.Lskel_string6:
+ .asciz "main.dwo" # string offset=78
+ .section .debug_str_offsets,"", at progbits
+ .long .Lskel_string0
+ .long .Lskel_string6
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 68 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS", at progbits,1
+.Linfo_string0:
+ .asciz "main" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=5
+.Linfo_string2:
+ .asciz "argc" # string offset=9
+.Linfo_string3:
+ .asciz "argv" # string offset=14
+.Linfo_string4:
+ .asciz "char" # string offset=19
+.Linfo_string5:
+ .asciz "f2" # string offset=24
+.Linfo_string6:
+ .asciz "/home/ayermolo/local/tasks/T138552329/typeDedupSplit" # string offset=27
+.Linfo_string7:
+ .asciz "main.dwo" # string offset=80
+.Linfo_string8:
+ .asciz "c1" # string offset=89
+.Linfo_string9:
+ .asciz "Foo2" # string offset=92
+.Linfo_string10:
+ .asciz "f3" # string offset=97
+.Linfo_string11:
+ .asciz "c2" # string offset=100
+.Linfo_string12:
+ .asciz "c3" # string offset=103
+.Linfo_string13:
+ .asciz "Foo2a" # string offset=106
+.Linfo_string14:
+ .asciz "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" # string offset=112
+.Linfo_string15:
+ .asciz "main.cpp" # string offset=220
+ .section .debug_str_offsets.dwo,"e", at progbits
+ .long 0
+ .long 5
+ .long 9
+ .long 14
+ .long 19
+ .long 24
+ .long 27
+ .long 80
+ .long 89
+ .long 92
+ .long 97
+ .long 100
+ .long 103
+ .long 106
+ .long 112
+ .long 220
+ .section .debug_info.dwo,"e", at progbits
+ .long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
+.Ldebug_info_dwo_start2:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 5962099678818150071
+ .byte 6 # Abbrev [6] 0x14:0x67 DW_TAG_compile_unit
+ .byte 14 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 15 # DW_AT_name
+ .byte 7 # DW_AT_dwo_name
+ .byte 7 # Abbrev [7] 0x1a:0x3c DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 0 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0x29:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .byte 2 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 86 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x34:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ .long 90 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x3f:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 104
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 104 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x4a:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 80
+ .byte 10 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .long 113 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x56:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 4 # Abbrev [4] 0x5a:0x5 DW_TAG_pointer_type
+ .long 95 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x5f:0x5 DW_TAG_pointer_type
+ .long 100 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x64:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 10 # Abbrev [10] 0x68:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 5322170643381124694 # DW_AT_signature
+ .byte 10 # Abbrev [10] 0x71:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end2:
+ .section .debug_abbrev.dwo,"e", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 65 # DW_TAG_type_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 105 # DW_AT_signature
+ .byte 32 # DW_FORM_ref_sig8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_line.dwo,"e", at progbits
+.Ltmp2:
+ .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length
+.Ldebug_line_start0:
+ .short 5
+ .byte 8
+ .byte 0
+ .long .Lprologue_end0-.Lprologue_start0
+.Lprologue_start0:
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte -5
+ .byte 14
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 8
+ .byte 2
+ .ascii "/home/ayermolo/local/tasks/T138552329/typeDedupSplit"
+ .byte 0
+ .byte 46
+ .byte 0
+ .byte 3
+ .byte 1
+ .byte 8
+ .byte 2
+ .byte 15
+ .byte 5
+ .byte 30
+ .byte 2
+ .ascii "main.cpp"
+ .byte 0
+ .byte 0
+ .byte 0x9c, 0x5c, 0xea, 0x5b
+ .byte 0xb7, 0x8d, 0x3f, 0xc2
+ .byte 0x65, 0xcd, 0x17, 0x51
+ .byte 0x10, 0xbf, 0xe9, 0x03
+ .ascii "header.h"
+ .byte 0
+ .byte 1
+ .byte 0xfe, 0xa7, 0xbb, 0x1f
+ .byte 0x22, 0xc4, 0x7f, 0x12
+ .byte 0x9e, 0x15, 0x69, 0x5f
+ .byte 0x71, 0x37, 0xa1, 0xe7
+.Lprologue_end0:
+.Ldebug_line_end0:
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 2 # Header: foreign type unit count
+ .long 5 # Header: bucket count
+ .long 5 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .quad 5322170643381124694 # Type unit 0
+ .quad 1175092228111723119 # Type unit 1
+ .long 0 # Bucket 0
+ .long 1 # Bucket 1
+ .long 0 # Bucket 2
+ .long 3 # Bucket 3
+ .long 4 # Bucket 4
+ .long 2090263771 # Hash in Bucket 1
+ .long 2090499946 # Hash in Bucket 1
+ .long 193495088 # Hash in Bucket 3
+ .long 259227804 # Hash in Bucket 4
+ .long 2090147939 # Hash in Bucket 4
+ .long .Lskel_string4 # String in Bucket 1: Foo2
+ .long .Lskel_string1 # String in Bucket 1: main
+ .long .Lskel_string2 # String in Bucket 3: int
+ .long .Lskel_string5 # String in Bucket 4: Foo2a
+ .long .Lskel_string3 # String in Bucket 4: char
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4
+.Lnames_abbrev_start0:
+ .ascii "\350\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\354\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\310\013" # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\210\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\214\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames3:
+ .ascii "\354\004" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 33 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 104 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2
+.Lnames0:
+ .ascii "\310\013" # Abbreviation code
+ .long 26 # DW_IDX_die_offset
+ .byte 0 # End of list: main
+.Lnames1:
+ .ascii "\210\t" # Abbreviation code
+ .long 86 # DW_IDX_die_offset
+ .byte 0 # End of list: int
+.Lnames4:
+ .ascii "\354\004" # Abbreviation code
+ .byte 1 # DW_IDX_type_unit
+ .long 33 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 113 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2a
+.Lnames2:
+ .ascii "\214\t" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 54 # DW_IDX_die_offset
+ .ascii "\214\t" # Abbreviation code
+ .byte 1 # DW_IDX_type_unit
+ .long 72 # DW_IDX_die_offset
+ .ascii "\210\t" # Abbreviation code
+ .long 100 # DW_IDX_die_offset
+ .byte 0 # End of list: char
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-types-debug-names-helper.s b/bolt/test/X86/Inputs/dwarf5-types-debug-names-helper.s
new file mode 100644
index 00000000000000..3e89382ed2d8aa
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-types-debug-names-helper.s
@@ -0,0 +1,405 @@
+# clang++ helper.cpp -g2 -gdwarf-5 -gpubnames -fdebug-types-section
+# header.h
+# struct Foo2a {
+# char *c1;
+# };
+# helper.cpp
+# #include "header.h"
+# int foo() {
+# Foo2a f;
+# return 0;
+# }
+
+
+ .text
+ .file "helper.cpp"
+ .globl _Z3foov # -- Begin function _Z3foov
+ .p2align 4, 0x90
+ .type _Z3foov, at function
+_Z3foov: # @_Z3foov
+.Lfunc_begin0:
+ .file 0 "/typeDedupSmall" "helper.cpp" md5 0x305ec66c221c583021f8375b300e2591
+ .loc 0 2 0 # helper.cpp:2:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+.Ltmp0:
+ .loc 0 4 3 prologue_end # helper.cpp:4:3
+ xorl %eax, %eax
+ .loc 0 4 3 epilogue_begin is_stmt 0 # helper.cpp:4:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z3foov, .Lfunc_end0-_Z3foov
+ .cfi_endproc
+ # -- End function
+ .file 1 "." "header.h" md5 0x53699580704254cb1dd2a83230f8a7ea
+ .section .debug_info,"G", at progbits,1175092228111723119,comdat
+.Ltu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 2 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 35 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x25 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 2 # Abbrev [2] 0x23:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 9 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member
+ .byte 7 # DW_AT_name
+ .long 51 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x33:0x5 DW_TAG_pointer_type
+ .long 56 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x38:0x4 DW_TAG_base_type
+ .byte 8 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 65 # DW_TAG_type_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 105 # DW_AT_signature
+ .byte 32 # DW_FORM_ref_sig8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 6 # Abbrev [6] 0xc:0x41 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 7 # Abbrev [7] 0x23:0x1c DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0x33:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 67 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x3f:0x4 DW_TAG_base_type
+ .byte 5 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 9 # Abbrev [9] 0x43:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end1:
+ .section .debug_str_offsets,"", at progbits
+ .long 44 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" # string offset=0
+.Linfo_string1:
+ .asciz "helper.cpp" # string offset=108
+.Linfo_string2:
+ .asciz "/home/typeDedupSmall" # string offset=119
+.Linfo_string3:
+ .asciz "foo" # string offset=172
+.Linfo_string4:
+ .asciz "_Z3foov" # string offset=176
+.Linfo_string5:
+ .asciz "int" # string offset=184
+.Linfo_string6:
+ .asciz "f" # string offset=188
+.Linfo_string7:
+ .asciz "Foo2a" # string offset=190
+.Linfo_string8:
+ .asciz "c1" # string offset=196
+.Linfo_string9:
+ .asciz "char" # string offset=199
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string4
+ .long .Linfo_string3
+ .long .Linfo_string5
+ .long .Linfo_string6
+ .long .Linfo_string8
+ .long .Linfo_string9
+ .long .Linfo_string7
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 1 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 5 # Header: bucket count
+ .long 5 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long .Ltu_begin0 # Type unit 0
+ .long 0 # Bucket 0
+ .long 0 # Bucket 1
+ .long 0 # Bucket 2
+ .long 1 # Bucket 3
+ .long 2 # Bucket 4
+ .long 193495088 # Hash in Bucket 3
+ .long 193491849 # Hash in Bucket 4
+ .long 259227804 # Hash in Bucket 4
+ .long 2090147939 # Hash in Bucket 4
+ .long -1257882357 # Hash in Bucket 4
+ .long .Linfo_string5 # String in Bucket 3: int
+ .long .Linfo_string3 # String in Bucket 4: foo
+ .long .Linfo_string7 # String in Bucket 4: Foo2a
+ .long .Linfo_string9 # String in Bucket 4: char
+ .long .Linfo_string4 # String in Bucket 4: _Z3foov
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 4
+.Lnames_abbrev_start0:
+ .ascii "\350\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\354\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\210\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\310\013" # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\214\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames2:
+ .ascii "\210\t" # Abbreviation code
+ .long 63 # DW_IDX_die_offset
+ .byte 0 # End of list: int
+.Lnames0:
+ .ascii "\310\013" # Abbreviation code
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # End of list: foo
+.Lnames3:
+ .ascii "\354\004" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 35 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 67 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2a
+.Lnames4:
+ .ascii "\214\t" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 56 # DW_IDX_die_offset
+ .byte 0 # End of list: char
+.Lnames1:
+ .ascii "\310\013" # Abbreviation code
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # End of list: _Z3foov
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-types-debug-names-main.s b/bolt/test/X86/Inputs/dwarf5-types-debug-names-main.s
new file mode 100644
index 00000000000000..cb9d287081d7f9
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-types-debug-names-main.s
@@ -0,0 +1,391 @@
+# clang++ -g2 -gdwarf-5 -gpubnames -fdebug-types-section
+# header.h
+# struct Foo2a {
+# char *c1;
+# };
+# main.cpp
+# #include "header.h"
+# int main() {
+# Foo2a f3;
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 0 "/typeDedupSmall" "main.cpp" md5 0x6e787b94dac2f817bb35cfde8006dc82
+ .loc 0 2 0 # main.cpp:2:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+.Ltmp0:
+ .loc 0 4 2 prologue_end # main.cpp:4:2
+ xorl %eax, %eax
+ .loc 0 4 2 epilogue_begin is_stmt 0 # main.cpp:4:2
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .file 1 "." "header.h" md5 0x53699580704254cb1dd2a83230f8a7ea
+ .section .debug_info,"G", at progbits,1175092228111723119,comdat
+.Ltu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 2 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 1175092228111723119 # Type Signature
+ .long 35 # Type DIE Offset
+ .byte 1 # Abbrev [1] 0x18:0x25 DW_TAG_type_unit
+ .short 33 # DW_AT_language
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 2 # Abbrev [2] 0x23:0x10 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 8 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member
+ .byte 6 # DW_AT_name
+ .long 51 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x33:0x5 DW_TAG_pointer_type
+ .long 56 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x38:0x4 DW_TAG_base_type
+ .byte 7 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 65 # DW_TAG_type_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 105 # DW_AT_signature
+ .byte 32 # DW_FORM_ref_sig8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 6 # Abbrev [6] 0xc:0x40 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 7 # Abbrev [7] 0x23:0x1b DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .long 62 # DW_AT_type
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0x32:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 112
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 66 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x3e:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 9 # Abbrev [9] 0x42:0x9 DW_TAG_structure_type
+ # DW_AT_declaration
+ .quad 1175092228111723119 # DW_AT_signature
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end1:
+ .section .debug_str_offsets,"", at progbits
+ .long 40 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=108
+.Linfo_string2:
+ .asciz "/home/typeDedupSmall" # string offset=117
+.Linfo_string3:
+ .asciz "main" # string offset=170
+.Linfo_string4:
+ .asciz "int" # string offset=175
+.Linfo_string5:
+ .asciz "f3" # string offset=179
+.Linfo_string6:
+ .asciz "Foo2a" # string offset=182
+.Linfo_string7:
+ .asciz "c1" # string offset=188
+.Linfo_string8:
+ .asciz "char" # string offset=191
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .long .Linfo_string5
+ .long .Linfo_string7
+ .long .Linfo_string8
+ .long .Linfo_string6
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 1 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 4 # Header: bucket count
+ .long 4 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long .Ltu_begin0 # Type unit 0
+ .long 1 # Bucket 0
+ .long 0 # Bucket 1
+ .long 3 # Bucket 2
+ .long 4 # Bucket 3
+ .long 193495088 # Hash in Bucket 0
+ .long 259227804 # Hash in Bucket 0
+ .long 2090499946 # Hash in Bucket 2
+ .long 2090147939 # Hash in Bucket 3
+ .long .Linfo_string4 # String in Bucket 0: int
+ .long .Linfo_string6 # String in Bucket 0: Foo2a
+ .long .Linfo_string3 # String in Bucket 2: main
+ .long .Linfo_string8 # String in Bucket 3: char
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 0
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3
+.Lnames_abbrev_start0:
+ .ascii "\350\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\354\004" # Abbrev code
+ .byte 19 # DW_TAG_structure_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\210\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\310\013" # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .ascii "\214\t" # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 2 # DW_IDX_type_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames1:
+ .ascii "\210\t" # Abbreviation code
+ .long 62 # DW_IDX_die_offset
+ .byte 0 # End of list: int
+.Lnames2:
+ .ascii "\354\004" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 35 # DW_IDX_die_offset
+ .ascii "\350\004" # Abbreviation code
+ .long 66 # DW_IDX_die_offset
+ .byte 0 # End of list: Foo2a
+.Lnames0:
+ .ascii "\310\013" # Abbreviation code
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # End of list: main
+.Lnames3:
+ .ascii "\214\t" # Abbreviation code
+ .byte 0 # DW_IDX_type_unit
+ .long 56 # DW_IDX_die_offset
+ .byte 0 # End of list: char
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 18.0.0git (git at github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test
new file mode 100644
index 00000000000000..8c3abafbc74654
--- /dev/null
+++ b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test
@@ -0,0 +1,154 @@
+; REQUIRES: system-linux
+
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_main.s -o %tmain.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_helper.s -o %thelper.o
+; RUN: %clang %cflags -dwarf-5 %tmain.o %thelper.o -o %t.exe -Wl,-q
+; RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections --create-debug-names-section=true
+; RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %t.bolt > %t.txt
+; RUN: cat %t.txt | FileCheck --check-prefix=BOLT %s
+
+;; Tests BOLT generates .debug_names with --create-debug-names-section.
+;; Also applicable when binary has CUs that do not contribute to .debug_names pre-bolt.
+
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0x107
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 2
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 8
+; BOLT-NEXT: Name count: 8
+; BOLT-NEXT: Abbreviations table size: 0x19
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET1]]
+; BOLT-NEXT: CU[1]: [[OFFSET2]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000033
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000007f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0xB887389
+; BOLT-NEXT: String: {{.+}} "foo"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0x8C06E589
+; BOLT-NEXT: String: {{.+}} "_Z3usePiS_"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000028
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0xB88B3D2
+; BOLT-NEXT: String: {{.+}} "use"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000028
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000049
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 6 {
+; BOLT-NEXT: Hash: 0xFDE4B5D2
+; BOLT-NEXT: String: {{.+}} "fooVar"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000028
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 7 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000092
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 5 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 6 [
+; BOLT-NEXT: Name 8 {
+; BOLT-NEXT: Hash: 0xB5063CFE
+; BOLT-NEXT: String: {{.+}} "_Z3fooi"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 7 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-debug-names.test b/bolt/test/X86/dwarf5-debug-names.test
new file mode 100644
index 00000000000000..1f8c3c7d9b55ae
--- /dev/null
+++ b/bolt/test/X86/dwarf5-debug-names.test
@@ -0,0 +1,263 @@
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-main.s -o %tmain.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-helper.s -o %thelper.o
+; RUN: %clang %cflags -gdwarf-5 %tmain.o %thelper.o -o %tmain.exe
+; RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %tmain.exe.bolt > %tlog.txt
+; RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with two CUs
+
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0x1C6
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 2
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 14
+; BOLT-NEXT: Name count: 15
+; BOLT-NEXT: Abbreviations table size: 0x29
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET1]]
+; BOLT-NEXT: CU[1]: [[OFFSET2]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV5:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0x59796C
+; BOLT-NEXT: String: {{.+}} "t3"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0x7C96E4DB
+; BOLT-NEXT: String: {{.+}} "Foo2"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000eb
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0x8CFC710C
+; BOLT-NEXT: String: {{.+}} "(anonymous namespace)"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000061
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000061
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0xBA564846
+; BOLT-NEXT: String: {{.+}} "Foo2Int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000005a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 5 [
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0xB887389
+; BOLT-NEXT: String: {{.+}} "Foo"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000c9
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 6 {
+; BOLT-NEXT: Hash: 0xB887389
+; BOLT-NEXT: String: {{.+}} "foo"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000033
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 7 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000009f
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000c5
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 6 [
+; BOLT-NEXT: Name 8 {
+; BOLT-NEXT: Hash: 0x392140FA
+; BOLT-NEXT: String: {{.+}} "t2<&fooint>"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 9 {
+; BOLT-NEXT: Hash: 0xFDE48034
+; BOLT-NEXT: String: {{.+}} "fooint"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV5]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000024
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 7 [
+; BOLT-NEXT: Name 10 {
+; BOLT-NEXT: Hash: 0xB5063D0B
+; BOLT-NEXT: String: {{.+}} "_Z3foov"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000033
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 8 [
+; BOLT-NEXT: Name 11 {
+; BOLT-NEXT: Hash: 0x5979AC
+; BOLT-NEXT: String: {{.+}} "v1"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV5]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000024
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 9 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 10 [
+; BOLT-NEXT: Name 12 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000005d
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 13 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000078
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ 0x1b5 {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000104
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 14 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000073
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 11 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 12 [
+; BOLT-NEXT: Name 15 {
+; BOLT-NEXT: Hash: 0x59796A
+; BOLT-NEXT: String: {{.+}} "t1"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000062
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 13 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test b/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test
new file mode 100644
index 00000000000000..2ba58dca43e3b0
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test
@@ -0,0 +1,192 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-dualcu-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-dualcu-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe -fno-pic -no-pie
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --create-debug-names-section=true
+; RUN: llvm-dwarfdump --debug-info --debug-names main.exe.bolt > %t/foo.txt
+; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests BOLT generates .debug_names with --create-debug-names-section.
+;; Also applicable when binary has split dwarf CUs that do not contribute to .debug_names pre-bolt.
+
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0x14C
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 2
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 11
+; BOLT-NEXT: Name count: 11
+; BOLT-NEXT: Abbreviations table size: 0x19
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET1]]
+; BOLT-NEXT: CU[1]: [[OFFSET2]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0x2B61E
+; BOLT-NEXT: String: {{.+}} "y"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000029
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000008c
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0x2B609
+; BOLT-NEXT: String: {{.+}} "d"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000029
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0x2B61F
+; BOLT-NEXT: String: {{.+}} "z"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0xB88B3D2
+; BOLT-NEXT: String: {{.+}} "use"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000034
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 6 {
+; BOLT-NEXT: Hash: 0x45A3B006
+; BOLT-NEXT: String: {{.+}} "_Z6helperii"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000034
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 5 [
+; BOLT-NEXT: Name 7 {
+; BOLT-NEXT: Hash: 0x8C06E589
+; BOLT-NEXT: String: {{.+}} "_Z3usePiS_"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000034
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 6 [
+; BOLT-NEXT: Name 8 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000025
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ 0x134 {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000025
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 7 [
+; BOLT-NEXT: Name 9 {
+; BOLT-NEXT: Hash: 0x1D853E5
+; BOLT-NEXT: String: {{.+}} "helper"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000034
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 10 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000057
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 8 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 9 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 10 [
+; BOLT-NEXT: Name 11 {
+; BOLT-NEXT: Hash: 0x2B61D
+; BOLT-NEXT: String: {{.+}} "x"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
diff --git a/bolt/test/X86/dwarf5-df-debug-names.test b/bolt/test/X86/dwarf5-df-debug-names.test
new file mode 100644
index 00000000000000..7ad4b95f1237d1
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-debug-names.test
@@ -0,0 +1,149 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-debug-names-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-debug-names-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info --debug-names main.exe.bolt > log.txt
+; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with two CUs for split dwarf.
+
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+: BOLT: Name Index @ 0x0 {
+: BOLT-NEXT: Header {
+: BOLT-NEXT: Length: 0xF8
+: BOLT-NEXT: Format: DWARF32
+: BOLT-NEXT: Version: 5
+: BOLT-NEXT: CU count: 2
+: BOLT-NEXT: Local TU count: 0
+: BOLT-NEXT: Foreign TU count: 0
+: BOLT-NEXT: Bucket count: 7
+: BOLT-NEXT: Name count: 7
+: BOLT-NEXT: Abbreviations table size: 0x21
+: BOLT-NEXT: Augmentation: 'BOLT0000'
+: BOLT-NEXT: }
+: BOLT-NEXT: Compilation Unit offsets [
+: BOLT-NEXT: CU[0]: [[OFFSET]]
+: BOLT-NEXT: CU[1]: [[OFFSET1]]
+: BOLT-NEXT: ]
+: BOLT-NEXT: Abbreviations [
+: BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+: BOLT-NEXT: Tag: DW_TAG_structure_type
+: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+: BOLT-NEXT: }
+: BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+: BOLT-NEXT: Tag: DW_TAG_base_type
+: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+: BOLT-NEXT: }
+: BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+: BOLT-NEXT: Tag: DW_TAG_variable
+: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+: BOLT-NEXT: }
+: BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+: BOLT-NEXT: Tag: DW_TAG_subprogram
+: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+: BOLT-NEXT: }
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 0 [
+: BOLT-NEXT: EMPTY
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 1 [
+: BOLT-NEXT: Name 1 {
+: BOLT-NEXT: Hash: 0x7C96E4DB
+: BOLT-NEXT: String: {{.+}} "Foo2"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV1]]
+: BOLT-NEXT: Tag: DW_TAG_structure_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x00
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000068
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 2 [
+: BOLT-NEXT: Name 2 {
+: BOLT-NEXT: Hash: 0xBA564846
+: BOLT-NEXT: String: {{.+}} "Foo2Int"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV1]]
+: BOLT-NEXT: Tag: DW_TAG_structure_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x01
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000025
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 3 [
+: BOLT-NEXT: Name 3 {
+: BOLT-NEXT: Hash: 0xB888030
+: BOLT-NEXT: String: {{.+}} "int"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV2]]
+: BOLT-NEXT: Tag: DW_TAG_base_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x01
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000043
+: BOLT-NEXT: }
+: BOLT-NEXT: Entry @ 0xd9 {
+: BOLT-NEXT: Abbrev: [[ABBREV2]]
+: BOLT-NEXT: Tag: DW_TAG_base_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x00
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000056
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: Name 4 {
+: BOLT-NEXT: Hash: 0xF73809C
+: BOLT-NEXT: String: {{.+}} "Foo2a"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV1]]
+: BOLT-NEXT: Tag: DW_TAG_structure_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x00
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000078
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: Name 5 {
+: BOLT-NEXT: Hash: 0x7C96CB76
+: BOLT-NEXT: String: {{.+}} "fint"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV3]]
+: BOLT-NEXT: Tag: DW_TAG_variable
+: BOLT-NEXT: DW_IDX_compile_unit: 0x01
+: BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: Name 6 {
+: BOLT-NEXT: Hash: 0x7C9A7F6A
+: BOLT-NEXT: String: {{.+}} "main"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV4]]
+: BOLT-NEXT: Tag: DW_TAG_subprogram
+: BOLT-NEXT: DW_IDX_compile_unit: 0x00
+: BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 4 [
+: BOLT-NEXT: EMPTY
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 5 [
+: BOLT-NEXT: Name 7 {
+: BOLT-NEXT: Hash: 0x7C952063
+: BOLT-NEXT: String: {{.+}} "char"
+: BOLT-NEXT: Entry @ {{.+}} {
+: BOLT-NEXT: Abbrev: [[ABBREV2]]
+: BOLT-NEXT: Tag: DW_TAG_base_type
+: BOLT-NEXT: DW_IDX_compile_unit: 0x00
+: BOLT-NEXT: DW_IDX_die_offset: 0x00000064
+: BOLT-NEXT: }
+: BOLT-NEXT: }
+: BOLT-NEXT: ]
+: BOLT-NEXT: Bucket 6 [
+: BOLT-NEXT: EMPTY
+: BOLT-NEXT: ]
+: BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-df-one-cu-debug-names.test b/bolt/test/X86/dwarf5-df-one-cu-debug-names.test
new file mode 100644
index 00000000000000..03311afaec56c4
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-one-cu-debug-names.test
@@ -0,0 +1,101 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-debug-names-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info --debug-names main.exe.bolt > log.txt
+; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with one CU for split dwarf.
+
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0xAD
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 1
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 5
+; BOLT-NEXT: Name count: 5
+; BOLT-NEXT: Abbreviations table size: 0x13
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: 0x00000000
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0x7C96E4DB
+; BOLT-NEXT: String: {{.+}} "Foo2"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000068
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000056
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000078
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000064
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-df-types-debug-names.test b/bolt/test/X86/dwarf5-df-types-debug-names.test
new file mode 100644
index 00000000000000..4abb4ed332ba62
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-types-debug-names.test
@@ -0,0 +1,234 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo > log.txt
+; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo.dwo >> log.txt
+; RUN: llvm-dwarfdump --debug-info --debug-names main.exe.bolt >> log.txt
+; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with two CUs and foreign TUs.
+
+; BOLT: type_signature = [[TYPE:0x[0-9a-f]*]]
+; BOLT: type_signature = [[TYPE1:0x[0-9a-f]*]]
+; BOLT: Compile Unit
+; BOLT: type_signature = [[TYPE2:0x[0-9a-f]*]]
+; BOLT: type_signature = [[TYPE3:0x[0-9a-f]*]]
+; BOLT: Compile Unit
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0x178
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 2
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 4
+; BOLT-NEXT: Bucket count: 9
+; BOLT-NEXT: Name count: 9
+; BOLT-NEXT: Abbreviations table size: 0x2D
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET]]
+; BOLT-NEXT: CU[1]: [[OFFSET1]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Foreign Type Unit signatures [
+; BOLT-NEXT: ForeignTU[0]: [[TYPE]]
+; BOLT-NEXT: ForeignTU[1]: [[TYPE1]]
+; BOLT-NEXT: ForeignTU[2]: [[TYPE2]]
+; BOLT-NEXT: ForeignTU[3]: [[TYPE3]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0x7C96E4DB
+; BOLT-NEXT: String: {{.+}} "Foo2"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0xB5063D0B
+; BOLT-NEXT: String: {{.+}} "_Z3foov"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000029
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0xFDE48034
+; BOLT-NEXT: String: {{.+}} "fooint"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000025
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: 0x5
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x02
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000056
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0xB887389
+; BOLT-NEXT: String: {{.+}} "foo"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000029
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 6 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x01
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x03
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 7 {
+; BOLT-NEXT: Hash: 0xBA564846
+; BOLT-NEXT: String: {{.+}} "Foo2Int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x02
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 5 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 6 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 7 [
+; BOLT-NEXT: Name 8 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 8 [
+; BOLT-NEXT: Name 9 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: 0x5
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000036
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: 0x5
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x01
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000048
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: 0x5
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x03
+; BOLT-NEXT: DW_IDX_compile_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000048
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_compile_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000064
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test b/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test
new file mode 100644
index 00000000000000..b4679b0fd402a5
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test
@@ -0,0 +1,129 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo > log.txt
+; RUN: llvm-dwarfdump --debug-info --debug-names main.exe.bolt >> log.txt
+; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with one CU and foreign TUs.
+
+; BOLT: type_signature = [[TYPE:0x[0-9a-f]*]]
+; BOLT: type_signature = [[TYPE1:0x[0-9a-f]*]]
+; BOLT: Compile Unit
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0xD5
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 1
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 2
+; BOLT-NEXT: Bucket count: 5
+; BOLT-NEXT: Name count: 5
+; BOLT-NEXT: Abbreviations table size: 0x1D
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Foreign Type Unit signatures [
+; BOLT-NEXT: ForeignTU[0]: [[TYPE]]
+; BOLT-NEXT: ForeignTU[1]: [[TYPE1]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0x7C96E4DB
+; BOLT-NEXT: String: {{.+}} "Foo2"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000056
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ 0xc7 {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000036
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x01
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000048
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000064
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-one-cu-debug-names.test b/bolt/test/X86/dwarf5-one-cu-debug-names.test
new file mode 100644
index 00000000000000..6e71b60c204826
--- /dev/null
+++ b/bolt/test/X86/dwarf5-one-cu-debug-names.test
@@ -0,0 +1,178 @@
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-main.s -o %tmain.o
+; RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe
+; RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %tmain.exe.bolt > %tlog.txt
+; RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with one CUs
+
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+; BOLT: Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0x142
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 1
+; BOLT-NEXT: Local TU count: 0
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 11
+; BOLT-NEXT: Name count: 11
+; BOLT-NEXT: Abbreviations table size: 0x1F
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET1]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV5:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000104
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000c5
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0xB887389
+; BOLT-NEXT: String: {{.+}} "Foo"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000c9
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0x392140FA
+; BOLT-NEXT: String: {{.+}} "t2<&fooint>"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 5 {
+; BOLT-NEXT: Hash: 0x7C96E4DB
+; BOLT-NEXT: String: {{.+}} "Foo2"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x000000eb
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 4 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 5 [
+; BOLT-NEXT: Name 6 {
+; BOLT-NEXT: Hash: 0x59796A
+; BOLT-NEXT: String: {{.+}} "t1"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000062
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 7 {
+; BOLT-NEXT: Hash: 0x5979AC
+; BOLT-NEXT: String: {{.+}} "v1"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_variable
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000024
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 6 [
+; BOLT-NEXT: Name 8 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000005d
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 7 [
+; BOLT-NEXT: Name 9 {
+; BOLT-NEXT: Hash: 0x59796C
+; BOLT-NEXT: String: {{.+}} "t3"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 10 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV4]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000073
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 8 [
+; BOLT-NEXT: Name 11 {
+; BOLT-NEXT: Hash: 0x8CFC710C
+; BOLT-NEXT: String: {{.+}} "(anonymous namespace)"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV5]]
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000061
+; BOLT-NEXT: }
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV5]]
+; BOLT-NEXT: Tag: DW_TAG_namespace
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000061
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 9 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 10 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: }
diff --git a/bolt/test/X86/dwarf5-types-debug-names.test b/bolt/test/X86/dwarf5-types-debug-names.test
new file mode 100644
index 00000000000000..2afa21b58762ab
--- /dev/null
+++ b/bolt/test/X86/dwarf5-types-debug-names.test
@@ -0,0 +1,129 @@
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-types-debug-names-main.s -o %tmain.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-types-debug-names-helper.s -o %thelper.o
+; RUN: %clang %cflags -gdwarf-5 %tmain.o %thelper.o -o %tmain.exe
+; RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info --debug-names %tmain.exe.bolt > %tlog.txt
+; RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with two CUs and a local TU.
+
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Type Unit
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit
+
+
+; BOLT: Name Index @ 0x0 {
+; BOLT: Header {
+; BOLT: Length: 0xE5
+; BOLT: Format: DWARF32
+; BOLT: Version: 5
+; BOLT: CU count: 2
+; BOLT: Local TU count: 1
+; BOLT: Foreign TU count: 0
+; BOLT: Bucket count: 6
+; BOLT: Name count: 6
+; BOLT: Abbreviations table size: 0x21
+; BOLT: Augmentation: 'BOLT0000'
+; BOLT: }
+; BOLT: Compilation Unit offsets [
+; BOLT: CU[0]: [[OFFSET1]]
+; BOLT: CU[1]: [[OFFSET2]]
+; BOLT: ]
+; BOLT: Local Type Unit offsets [
+; BOLT: LocalTU[0]: [[OFFSET]]
+; BOLT: ]
+; BOLT: Abbreviations [
+; BOLT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
+; BOLT: Tag: DW_TAG_structure_type
+; BOLT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT: }
+; BOLT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT: Tag: DW_TAG_subprogram
+; BOLT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT: }
+; BOLT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT: Tag: DW_TAG_base_type
+; BOLT: DW_IDX_compile_unit: DW_FORM_data1
+; BOLT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT: }
+; BOLT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT: Tag: DW_TAG_base_type
+; BOLT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 0 [
+; BOLT: Name 1 {
+; BOLT: Hash: 0xF73809C
+; BOLT: String: {{.+}} "Foo2a"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV]]
+; BOLT: Tag: DW_TAG_structure_type
+; BOLT: DW_IDX_type_unit: 0x00
+; BOLT: DW_IDX_die_offset: 0x00000023
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 1 [
+; BOLT: Name 2 {
+; BOLT: Hash: 0xB5063D0B
+; BOLT: String: {{.+}} "_Z3foov"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV1]]
+; BOLT: Tag: DW_TAG_subprogram
+; BOLT: DW_IDX_compile_unit: 0x01
+; BOLT: DW_IDX_die_offset: 0x00000024
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 2 [
+; BOLT: Name 3 {
+; BOLT: Hash: 0xB888030
+; BOLT: String: {{.+}} "int"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV2]]
+; BOLT: Tag: DW_TAG_base_type
+; BOLT: DW_IDX_compile_unit: 0x01
+; BOLT: DW_IDX_die_offset: 0x00000040
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 3 [
+; BOLT: Name 4 {
+; BOLT: Hash: 0xB887389
+; BOLT: String: {{.+}} "foo"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV1]]
+; BOLT: Tag: DW_TAG_subprogram
+; BOLT: DW_IDX_compile_unit: 0x01
+; BOLT: DW_IDX_die_offset: 0x00000024
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 4 [
+; BOLT: Name 5 {
+; BOLT: Hash: 0x7C9A7F6A
+; BOLT: String: {{.+}} "main"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV1]]
+; BOLT: Tag: DW_TAG_subprogram
+; BOLT: DW_IDX_compile_unit: 0x00
+; BOLT: DW_IDX_die_offset: 0x00000024
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: Bucket 5 [
+; BOLT: Name 6 {
+; BOLT: Hash: 0x7C952063
+; BOLT: String: {{.+}} "char"
+; BOLT: Entry @ {{.+}} {
+; BOLT: Abbrev: [[ABBREV3]]
+; BOLT: Tag: DW_TAG_base_type
+; BOLT: DW_IDX_type_unit: 0x00
+; BOLT: DW_IDX_die_offset: 0x00000038
+; BOLT: }
+; BOLT: }
+; BOLT: ]
+; BOLT: }
diff --git a/bolt/test/X86/dwarf5-types-one-cu-debug-names.test b/bolt/test/X86/dwarf5-types-one-cu-debug-names.test
new file mode 100644
index 00000000000000..734918be7cb52a
--- /dev/null
+++ b/bolt/test/X86/dwarf5-types-one-cu-debug-names.test
@@ -0,0 +1,98 @@
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-types-debug-names-main.s -o %tmain.o
+; RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe
+; RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info --debug-names %tmain.exe.bolt > %tlog.txt
+; RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s
+
+;; Tests that BOLT correctly generates .debug_names section with one CU and a local TU.
+
+; BOLT: [[OFFSET:0x[0-9a-f]*]]: Type Unit
+; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+
+; BOLT:Name Index @ 0x0 {
+; BOLT-NEXT: Header {
+; BOLT-NEXT: Length: 0xA7
+; BOLT-NEXT: Format: DWARF32
+; BOLT-NEXT: Version: 5
+; BOLT-NEXT: CU count: 1
+; BOLT-NEXT: Local TU count: 1
+; BOLT-NEXT: Foreign TU count: 0
+; BOLT-NEXT: Bucket count: 4
+; BOLT-NEXT: Name count: 4
+; BOLT-NEXT: Abbreviations table size: 0x1D
+; BOLT-NEXT: Augmentation: 'BOLT0000'
+; BOLT-NEXT: }
+; BOLT-NEXT: Compilation Unit offsets [
+; BOLT-NEXT: CU[0]: [[OFFSET1]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Local Type Unit offsets [
+; BOLT-NEXT: LocalTU[0]: [[OFFSET]]
+; BOLT-NEXT: ]
+; BOLT-NEXT: Abbreviations [
+; BOLT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 0 [
+; BOLT-NEXT: Name 1 {
+; BOLT-NEXT: Hash: 0xB888030
+; BOLT-NEXT: String: {{.+}} "int"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: Name 2 {
+; BOLT-NEXT: Hash: 0xF73809C
+; BOLT-NEXT: String: {{.+}} "Foo2a"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV1]]
+; BOLT-NEXT: Tag: DW_TAG_structure_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000023
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 1 [
+; BOLT-NEXT: EMPTY
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 2 [
+; BOLT-NEXT: Name 3 {
+; BOLT-NEXT: Hash: 0x7C9A7F6A
+; BOLT-NEXT: String: {{.+}} "main"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV2]]
+; BOLT-NEXT: Tag: DW_TAG_subprogram
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000024
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT: Bucket 3 [
+; BOLT-NEXT: Name 4 {
+; BOLT-NEXT: Hash: 0x7C952063
+; BOLT-NEXT: String: {{.+}} "char"
+; BOLT-NEXT: Entry @ {{.+}} {
+; BOLT-NEXT: Abbrev: [[ABBREV3]]
+; BOLT-NEXT: Tag: DW_TAG_base_type
+; BOLT-NEXT: DW_IDX_type_unit: 0x00
+; BOLT-NEXT: DW_IDX_die_offset: 0x00000038
+; BOLT-NEXT: }
+; BOLT-NEXT: }
+; BOLT-NEXT: ]
+; BOLT-NEXT:}
More information about the llvm-commits
mailing list