[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
https://github.com/OCHyams updated
https://github.com/llvm/llvm-project/pull/194860
>From c2eecc25d5663a2a0fe77816055cd8d38e0ce9ae Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams
Date: Thu, 2 Apr 2026 15:49:06 +0100
Subject: [PATCH 1/4] [dyndbg][Clang] Implement nested-ELF dynamic debugging
support
A clone of the module is compiled without optimisations and embedded into the
to-be-optimised module using embedBufferInModule, similarly to how
-ffat-lto-objects and -fembed-offload-object work.
That unoptimised-code object is embedded in the optimised-code object in a
section called .debug_llvm_dyndbg.
The optimised ELF/module may be referred to as the "outer" ELF/module, and the
unoptimized one the "inner" ELF/module.
The outer module holds global data referred to by both modules and all calls in
the inner module are to outer module functions. To facilitate this the outer
module is modified, adding external-linkage aliases for local symbols.
See https://discourse.llvm.org/t/90113 for more detail (including a diagram).
---
clang/include/clang/Basic/CodeGenOptions.h| 3 +
clang/include/clang/Basic/DebugOptions.def| 7 ++
.../clang/Basic/DiagnosticDriverKinds.td | 4 +
.../clang/Basic/DiagnosticFrontendKinds.td| 4 +
clang/include/clang/Options/Options.td| 18
clang/lib/CodeGen/BackendUtil.cpp | 85 +++
clang/lib/Driver/ToolChains/Clang.cpp | 27 ++
clang/lib/Frontend/CompilerInvocation.cpp | 6 ++
.../DynamicDebugging/EndToEnd/X86/globalopt.c | 24 ++
.../EndToEnd/X86/lit.local.cfg| 4 +
.../X86/obj-emission-target/lit.local.cfg | 3 +
.../X86/obj-emission-target/no-target.c | 14 +++
.../DynamicDebugging/EndToEnd/X86/section.c | 13 +++
.../attr-outer-no-specialization.c| 7 ++
.../attr-outer-tail-pad-unsupported.c | 9 ++
.../DynamicDebugging/attr-outer-tail-pad.c| 10 +++
.../DynamicDebugging/compiler-used.cpp| 37
clang/test/DebugInfo/DynamicDebugging/embed.c | 12 +++
.../DebugInfo/DynamicDebugging/inner-attrs.c | 25 ++
.../DynamicDebugging/symbols-functions.cpp| 33 +++
.../DynamicDebugging/symbols-globals.cpp | 72
.../symbols-internal-comdat.cpp | 27 ++
clang/test/Driver/dynamic-debugging-flags.c | 28 ++
clang/test/Misc/warning-flags.c | 4 +-
24 files changed, 475 insertions(+), 1 deletion(-)
create mode 100644
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/globalopt.c
create mode 100644
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/lit.local.cfg
create mode 100644
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/lit.local.cfg
create mode 100644
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/no-target.c
create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/section.c
create mode 100644
clang/test/DebugInfo/DynamicDebugging/attr-outer-no-specialization.c
create mode 100644
clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad-unsupported.c
create mode 100644 clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad.c
create mode 100644 clang/test/DebugInfo/DynamicDebugging/compiler-used.cpp
create mode 100644 clang/test/DebugInfo/DynamicDebugging/embed.c
create mode 100644 clang/test/DebugInfo/DynamicDebugging/inner-attrs.c
create mode 100644 clang/test/DebugInfo/DynamicDebugging/symbols-functions.cpp
create mode 100644 clang/test/DebugInfo/DynamicDebugging/symbols-globals.cpp
create mode 100644
clang/test/DebugInfo/DynamicDebugging/symbols-internal-comdat.cpp
create mode 100644 clang/test/Driver/dynamic-debugging-flags.c
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 9454f7672b7e1..5afc27beaa923 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -359,6 +359,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Prefix to use for -save-temps output.
std::string SaveTempsFilePrefix;
+ /// Prefix to use for -save-dynamic-debugging-temps output.
+ std::string SaveDynDbgTempsFilePrefix;
+
/// Name of file passed with -fcuda-include-gpubinary option to forward to
/// CUDA runtime back-end for incorporating them into host-side object file.
std::string CudaGpuBinaryFileName;
diff --git a/clang/include/clang/Basic/DebugOptions.def
b/clang/include/clang/Basic/DebugOptions.def
index 604e87e615a69..b2fa50a289da9 100644
--- a/clang/include/clang/Basic/DebugOptions.def
+++ b/clang/include/clang/Basic/DebugOptions.def
@@ -62,6 +62,13 @@ ENUM_DEBUGOPT(AssignmentTrackingMode,
AssignmentTrackingOpts, 2,
/// Whether or not to use Key Instructions to determine breakpoint locations.
DEBUGOPT(DebugKeyInstructions, 1, 0, Benign)
+/// Whether or not to use the Dynamic Debugging feature.
+DEBUGOPT(DynamicDebugging, 1, 0, Benign)
+
+/// Flag f
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
github-actions[bot] wrote: # :window: Windows x64 Test Results The build failed before running any tests. Click on a failure below to see the details. [code=1] tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.obj ``` FAILED: [code=1] tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.obj sccache C:\clang\clang-msvc\bin\clang-cl.exe /nologo -TP -DCLANG_BUILD_STATIC -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GLIBCXX_ASSERTIONS -D_HAS_EXCEPTIONS=0 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -IC:\_work\llvm-project\llvm-project\build\tools\clang\lib\CodeGen -IC:\_work\llvm-project\llvm-project\clang\lib\CodeGen -IC:\_work\llvm-project\llvm-project\clang\include -IC:\_work\llvm-project\llvm-project\build\tools\clang\include -IC:\_work\llvm-project\llvm-project\build\include -IC:\_work\llvm-project\llvm-project\llvm\include /DWIN32 /D_WINDOWS /Zc:inline /Zc:__cplusplus /Oi /Brepro /bigobj /permissive- -Werror=unguarded-availability-new /W4 -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported /Gw /O2 /Ob2 -std:c++17 -MD -UNDEBUG /EHs-c- /GR- /showIncludes /Fotools\clang\lib\CodeGen\CMakeFiles\obj.clangCodeGen.dir\BackendUtil.cpp.obj /Fdtools\clang\lib\CodeGen\CMakeFiles\obj.clangCodeGen.dir\ -c -- C:\_work\llvm-project\llvm-project\clang\lib\CodeGen\BackendUtil.cpp C:\_work\llvm-project\llvm-project\clang\lib\CodeGen\BackendUtil.cpp(93,10): fatal error: 'llvm/Transforms/Utils/DynamicDebugging.h' file not found 93 | #include "llvm/Transforms/Utils/DynamicDebugging.h" | ^~ 1 error generated. ``` If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label. https://github.com/llvm/llvm-project/pull/194860 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results The build failed before running any tests. Click on a failure below to see the details. tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.o ``` FAILED: tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.o sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/CodeGen -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17 -UNDEBUG -fno-exceptions -funwind-tables -fno-rtti -MD -MT tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.o -MF tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.o.d -o tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/BackendUtil.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/BackendUtil.cpp /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:93:10: fatal error: 'llvm/Transforms/Utils/DynamicDebugging.h' file not found 93 | #include "llvm/Transforms/Utils/DynamicDebugging.h" | ^~ 1 error generated. ``` tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o ``` FAILED: tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/Frontend -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/Frontend -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17 -UNDEBUG -fno-exceptions -funwind-tables -fno-rtti -MD -MT tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o -MF tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o.d -o tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp:2010:12: error: variable 'A' set but not used [-Werror,-Wunused-but-set-variable] 2010 | if (Arg *A = Args.getLastArg(OPT_save_dynamic_debugging_temps)) |^ 1 error generated. ``` If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label. https://github.com/llvm/llvm-project/pull/194860 ___ cfe-commits mailing list [email protected] https://
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff origin/main HEAD --extensions h,cpp,c -- clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/globalopt.c clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/no-target.c clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/section.c clang/test/DebugInfo/DynamicDebugging/attr-outer-no-specialization.c clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad-unsupported.c clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad.c clang/test/DebugInfo/DynamicDebugging/compiler-used.cpp clang/test/DebugInfo/DynamicDebugging/embed.c clang/test/DebugInfo/DynamicDebugging/inner-attrs.c clang/test/DebugInfo/DynamicDebugging/profile-coverage.c clang/test/DebugInfo/DynamicDebugging/symbols-functions.cpp clang/test/DebugInfo/DynamicDebugging/symbols-globals.cpp clang/test/DebugInfo/DynamicDebugging/symbols-internal-comdat.cpp clang/test/Driver/dynamic-debugging-flags.c clang/include/clang/Basic/CodeGenOptions.h clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Misc/warning-flags.c --diff_from_common_commit `` :warning: The reproduction instructions above might return results for more than one PR in a stack if you are using a stacked PR workflow. You can limit the results by changing `origin/main` to the base branch/commit you want to compare against. :warning: View the diff from clang-format here. ``diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7920d1d25..72c3ba96c 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1473,7 +1473,6 @@ void clang::emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, } } - bool EnableDynamicDebugging = CGOpts.DynamicDebugging; // Disable dyndbg if the target isn't available as we're compiling to the // inner module to object regardless of other options. (This may change). `` https://github.com/llvm/llvm-project/pull/194860 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
llvmbot wrote:
@llvm/pr-subscribers-clang-driver
Author: Orlando Cazalet-Hyams (OCHyams)
Changes
A clone of the module is compiled without optimisations and embedded into the
to-be-optimised module using `embedBufferInModule`, similarly to how
`-ffat-lto-objects` and `-fembed-offload-object` work.
That unoptimised-code object is embedded in the optimised-code object in a
section called `.debug_llvm_dyndbg`.
The optimised ELF/module may be referred to as the "outer" ELF/module, and the
unoptimized one the "inner" ELF/module.
The outer module holds global data referred to by both modules and all calls in
the inner module are to outer module functions. To facilitate this the outer
module is modified, adding external-linkage aliases for local symbols.
See RFC https://discourse.llvm.org/t/90113 for more detail (including a
diagram).
To begin with there's a few incompatible compilation modes/flags:
* LTO
* Sanitizers (currently investigating what this looks like)
* Profiling / code-coverage instrumentation
* Split DWARF (where does the inner object's split DWARF go?)
* Non x86 targets (I've only been testing on x86).
---
Patch is 35.22 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/194860.diff
25 Files Affected:
- (modified) clang/include/clang/Basic/CodeGenOptions.h (+3)
- (modified) clang/include/clang/Basic/DebugOptions.def (+7)
- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+4)
- (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+7)
- (modified) clang/include/clang/Options/Options.td (+18)
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+94)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+31)
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (+6)
- (added) clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/globalopt.c (+24)
- (added) clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/lit.local.cfg (+4)
- (added)
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/lit.local.cfg
(+3)
- (added)
clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/no-target.c
(+14)
- (added) clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/section.c (+13)
- (added) clang/test/DebugInfo/DynamicDebugging/attr-outer-no-specialization.c
(+7)
- (added)
clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad-unsupported.c (+9)
- (added) clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad.c (+10)
- (added) clang/test/DebugInfo/DynamicDebugging/compiler-used.cpp (+37)
- (added) clang/test/DebugInfo/DynamicDebugging/embed.c (+12)
- (added) clang/test/DebugInfo/DynamicDebugging/inner-attrs.c (+25)
- (added) clang/test/DebugInfo/DynamicDebugging/profile-coverage.c (+7)
- (added) clang/test/DebugInfo/DynamicDebugging/symbols-functions.cpp (+33)
- (added) clang/test/DebugInfo/DynamicDebugging/symbols-globals.cpp (+72)
- (added) clang/test/DebugInfo/DynamicDebugging/symbols-internal-comdat.cpp
(+27)
- (added) clang/test/Driver/dynamic-debugging-flags.c (+32)
- (modified) clang/test/Misc/warning-flags.c (+3-1)
``diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 9454f7672b7e1..5afc27beaa923 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -359,6 +359,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Prefix to use for -save-temps output.
std::string SaveTempsFilePrefix;
+ /// Prefix to use for -save-dynamic-debugging-temps output.
+ std::string SaveDynDbgTempsFilePrefix;
+
/// Name of file passed with -fcuda-include-gpubinary option to forward to
/// CUDA runtime back-end for incorporating them into host-side object file.
std::string CudaGpuBinaryFileName;
diff --git a/clang/include/clang/Basic/DebugOptions.def
b/clang/include/clang/Basic/DebugOptions.def
index 604e87e615a69..b2fa50a289da9 100644
--- a/clang/include/clang/Basic/DebugOptions.def
+++ b/clang/include/clang/Basic/DebugOptions.def
@@ -62,6 +62,13 @@ ENUM_DEBUGOPT(AssignmentTrackingMode,
AssignmentTrackingOpts, 2,
/// Whether or not to use Key Instructions to determine breakpoint locations.
DEBUGOPT(DebugKeyInstructions, 1, 0, Benign)
+/// Whether or not to use the Dynamic Debugging feature.
+DEBUGOPT(DynamicDebugging, 1, 0, Benign)
+
+/// Flag for testing: discard the dynamic debugging debug module before codegen
+/// if true.
+DEBUGOPT(DiscardDynamicDebuggingDebugModule, 1, 0, Benign)
+
DEBUGOPT(DebugColumnInfo, 1, 0, Compatible) ///< Whether or not to use column
information
///< in debug info.
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ed6a9107002af..def5e194053d6 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -390,6 +390,10 @@ def
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
https://github.com/OCHyams edited https://github.com/llvm/llvm-project/pull/194860 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [dyndbg][Clang] Implement nested-ELF dynamic debugging support (PR #194860)
https://github.com/OCHyams created https://github.com/llvm/llvm-project/pull/194860 A clone of the module is compiled without optimisations and embedded into the to-be-optimised module using `embedBufferInModule`, similarly to how `-ffat-lto-objects` and `-fembed-offload-object` work. That unoptimised-code object is embedded in the optimised-code object in a section called `.debug_llvm_dyndbg`. The optimised ELF/module may be referred to as the "outer" ELF/module, and the unoptimized one the "inner" ELF/module. The outer module holds global data referred to by both modules and all calls in the inner module are to outer module functions. To facilitate this the outer module is modified, adding external-linkage aliases for local symbols. See RFC https://discourse.llvm.org/t/90113 for more detail (including a diagram). To begin with there's a few incompatible compilation modes/flags: * LTO * Sanitizers (currently investigating what this looks like) * Profiling / code-coverage instrumentation * Split DWARF (where does the inner object's split DWARF go?) * Non x86 targets (I've only been testing on x86). >From c2eecc25d5663a2a0fe77816055cd8d38e0ce9ae Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Thu, 2 Apr 2026 15:49:06 +0100 Subject: [PATCH 1/3] [dyndbg][Clang] Implement nested-ELF dynamic debugging support A clone of the module is compiled without optimisations and embedded into the to-be-optimised module using embedBufferInModule, similarly to how -ffat-lto-objects and -fembed-offload-object work. That unoptimised-code object is embedded in the optimised-code object in a section called .debug_llvm_dyndbg. The optimised ELF/module may be referred to as the "outer" ELF/module, and the unoptimized one the "inner" ELF/module. The outer module holds global data referred to by both modules and all calls in the inner module are to outer module functions. To facilitate this the outer module is modified, adding external-linkage aliases for local symbols. See https://discourse.llvm.org/t/90113 for more detail (including a diagram). --- clang/include/clang/Basic/CodeGenOptions.h| 3 + clang/include/clang/Basic/DebugOptions.def| 7 ++ .../clang/Basic/DiagnosticDriverKinds.td | 4 + .../clang/Basic/DiagnosticFrontendKinds.td| 4 + clang/include/clang/Options/Options.td| 18 clang/lib/CodeGen/BackendUtil.cpp | 85 +++ clang/lib/Driver/ToolChains/Clang.cpp | 27 ++ clang/lib/Frontend/CompilerInvocation.cpp | 6 ++ .../DynamicDebugging/EndToEnd/X86/globalopt.c | 24 ++ .../EndToEnd/X86/lit.local.cfg| 4 + .../X86/obj-emission-target/lit.local.cfg | 3 + .../X86/obj-emission-target/no-target.c | 14 +++ .../DynamicDebugging/EndToEnd/X86/section.c | 13 +++ .../attr-outer-no-specialization.c| 7 ++ .../attr-outer-tail-pad-unsupported.c | 9 ++ .../DynamicDebugging/attr-outer-tail-pad.c| 10 +++ .../DynamicDebugging/compiler-used.cpp| 37 clang/test/DebugInfo/DynamicDebugging/embed.c | 12 +++ .../DebugInfo/DynamicDebugging/inner-attrs.c | 25 ++ .../DynamicDebugging/symbols-functions.cpp| 33 +++ .../DynamicDebugging/symbols-globals.cpp | 72 .../symbols-internal-comdat.cpp | 27 ++ clang/test/Driver/dynamic-debugging-flags.c | 28 ++ clang/test/Misc/warning-flags.c | 4 +- 24 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/globalopt.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/lit.local.cfg create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/lit.local.cfg create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/obj-emission-target/no-target.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/EndToEnd/X86/section.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/attr-outer-no-specialization.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad-unsupported.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/attr-outer-tail-pad.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/compiler-used.cpp create mode 100644 clang/test/DebugInfo/DynamicDebugging/embed.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/inner-attrs.c create mode 100644 clang/test/DebugInfo/DynamicDebugging/symbols-functions.cpp create mode 100644 clang/test/DebugInfo/DynamicDebugging/symbols-globals.cpp create mode 100644 clang/test/DebugInfo/DynamicDebugging/symbols-internal-comdat.cpp create mode 100644 clang/test/Driver/dynamic-debugging-flags.c diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 9454f7672b7e1..5afc27beaa923 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/Co
