[llvm] [dyndbg][llvm][ELF] Add ELF section type for dynamic debugging (PR #208803)
Andrew Ng via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 07:21:37 PDT 2026
https://github.com/nga888 updated https://github.com/llvm/llvm-project/pull/208803
>From 9dd03a19b6fcb712a0945cae32f68ff6387a2580 Mon Sep 17 00:00:00 2001
From: Andrew Ng <andrew.ng at sony.com>
Date: Fri, 10 Jul 2026 19:11:01 +0100
Subject: [PATCH] [dyndbg][llvm][ELF] Add ELF section type for dynamic
debugging
Add ELF section type `SHT_LLVM_DYNDBG_ELF` for embedding the "inner"
unoptimized dynamic debugging ELF object within the "outer" optimized
ELF object.
RFC: https://discourse.llvm.org/t/90113
---
llvm/docs/Extensions.md | 12 ++++++++++++
llvm/include/llvm/BinaryFormat/ELF.h | 1 +
llvm/lib/MC/MCAsmInfoELF.cpp | 2 ++
llvm/lib/MC/MCParser/ELFAsmParser.cpp | 2 ++
llvm/lib/Object/ELF.cpp | 1 +
llvm/lib/ObjectYAML/ELFYAML.cpp | 1 +
llvm/test/tools/llvm-readobj/ELF/section-types.test | 5 +++++
7 files changed, 24 insertions(+)
diff --git a/llvm/docs/Extensions.md b/llvm/docs/Extensions.md
index aaaa4b1d8a013..ba824570b4500 100644
--- a/llvm/docs/Extensions.md
+++ b/llvm/docs/Extensions.md
@@ -679,6 +679,18 @@ This indicates that `ball` calls `foo`, `bar` and `baz` directly;
`ball` indirectly calls functions whose types are `4524972987496481828`,
`3498816979441845844` and `8646233951371320954`.
+#### `SHT_LLVM_DYNDBG_ELF` Section (Dynamic Debugging ELF)
+
+This section is used to embed a dynamic debugging ELF object. The section is
+created by the compiler when dynamic debugging is enabled. The content of this
+section is an ELF object with code that is compiled unoptimized and compatible
+with the optimized ELF object in which it is embedded. The linker combines
+embedded dynamic debugging ELF objects into a single embedded dynamic debugging
+ELF object in the linker output. The unoptimized code within the embedded
+dynamic debugging object can be used by a debugger to replace the optimized
+equivalent during debugging. See "Dynamic Debugging" documentation for further
+details.
+
### CodeView-Dependent
#### `.cv_file` Directive
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 3f1889f236ea1..2ef32651c98d5 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1196,6 +1196,7 @@ enum : unsigned {
SHT_LLVM_JT_SIZES = 0x6fff4c0d, // LLVM jump tables sizes.
SHT_LLVM_CFI_JUMP_TABLE = 0x6fff4c0e, // LLVM CFI jump table.
SHT_LLVM_CALL_GRAPH = 0x6fff4c0f, // LLVM Call Graph Section.
+ SHT_LLVM_DYNDBG_ELF = 0x6fff4c10, // LLVM Dynamic Debugging ELF.
// Android's experimental support for SHT_RELR sections.
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
diff --git a/llvm/lib/MC/MCAsmInfoELF.cpp b/llvm/lib/MC/MCAsmInfoELF.cpp
index 34cea68896234..e964ea92f2d74 100644
--- a/llvm/lib/MC/MCAsmInfoELF.cpp
+++ b/llvm/lib/MC/MCAsmInfoELF.cpp
@@ -200,6 +200,8 @@ void MCAsmInfoELF::printSwitchToSection(const MCSection &Section,
OS << "llvm_cfi_jump_table";
else if (Sec.Type == ELF::SHT_LLVM_CALL_GRAPH)
OS << "llvm_call_graph";
+ else if (Sec.Type == ELF::SHT_LLVM_DYNDBG_ELF)
+ OS << "llvm_dyndbg_elf";
else
OS << "0x" << Twine::utohexstr(Sec.Type);
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index d7adf17793af6..626c4fc192cb5 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -638,6 +638,8 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) {
Type = ELF::SHT_LLVM_CFI_JUMP_TABLE;
else if (TypeName == "llvm_call_graph")
Type = ELF::SHT_LLVM_CALL_GRAPH;
+ else if (TypeName == "llvm_dyndbg_elf")
+ Type = ELF::SHT_LLVM_DYNDBG_ELF;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index 48dd225932ba8..15e090cd29b74 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -336,6 +336,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_JT_SIZES)
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CFI_JUMP_TABLE)
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH);
+ STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DYNDBG_ELF);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_SFRAME);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 0d742e34b4b22..4e96b74bd9c15 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -680,6 +680,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_LLVM_OFFLOADING);
ECase(SHT_LLVM_LTO);
ECase(SHT_LLVM_CALL_GRAPH);
+ ECase(SHT_LLVM_DYNDBG_ELF);
ECase(SHT_GNU_SFRAME);
ECase(SHT_GNU_ATTRIBUTES);
ECase(SHT_GNU_HASH);
diff --git a/llvm/test/tools/llvm-readobj/ELF/section-types.test b/llvm/test/tools/llvm-readobj/ELF/section-types.test
index 12a9d0543bebd..32193fbc8322a 100644
--- a/llvm/test/tools/llvm-readobj/ELF/section-types.test
+++ b/llvm/test/tools/llvm-readobj/ELF/section-types.test
@@ -65,6 +65,8 @@
# LLVM: Type: SHT_LLVM_LTO
# LLVM: Name: .llvm.callgraph
# LLVM: Type: SHT_LLVM_CALL_GRAPH
+# LLVM: Name: .llvm.dyndbg_elf
+# LLVM: Type: SHT_LLVM_DYNDBG_ELF
# LLVM: Name: gnu_sframe
# LLVM: Type: SHT_GNU_SFRAME
# LLVM: Name: gnu_attributes
@@ -130,6 +132,7 @@
# GNU-NEXT: .phdrs LLVM_PART_PHDR
# GNU-NEXT: .llvm.lto LLVM_LTO
# GNU-NEXT: .llvm.callgraph LLVM_CALL_GRAPH
+# GNU-NEXT: .llvm.dyndbg_elf LLVM_DYNDBG_ELF
# GNU-NEXT: gnu_sframe SFRAME
# GNU-NEXT: gnu_attributes ATTRIBUTES
# GNU-NEXT: gnu_hash GNU_HASH
@@ -223,6 +226,8 @@ Sections:
Type: SHT_LLVM_LTO
- Name: .llvm.callgraph
Type: SHT_LLVM_CALL_GRAPH
+ - Name: .llvm.dyndbg_elf
+ Type: SHT_LLVM_DYNDBG_ELF
- Name: gnu_sframe
Type: SHT_GNU_SFRAME
- Name: gnu_attributes
More information about the llvm-commits
mailing list