[lld] [llvm] [dyndbg][LLD][ELF] Initial LLD support for dynamic debugging (PR #214188)
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 12 03:35:00 PDT 2026
================
@@ -0,0 +1,403 @@
+REQUIRES: x86
+
+## This test simulates the input from dynamic debugging objects to test ELF LLD's handling
+## of various specific situations that can arise with such objects. These are mainly
+## related to dependencies from the "inner" unoptimized objects.
+
+RUN: rm -rf %t && split-file %s %t
+
+## Create the "outer" optimized objects.
+RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/main.s -o %t/main.o
+RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/foo.s -o %t/foo.o
+
+## Link only the "outer" optimized objects using `--gc-sections`.
+RUN: ld.lld -e main --gc-sections -o %t/out %t/main.o %t/foo.o
+RUN: llvm-readelf -s %t/out | FileCheck %s
+
+CHECK: Symbol table '.symtab' contains 12 entries:
+CHECK-DAG: {{.*}} 0 FUNC LOCAL DEFAULT [[#]] static_func
+CHECK-DAG: {{.*}} 0 OBJECT LOCAL DEFAULT [[#]] static_data
+CHECK-DAG: {{.*}} 0 FUNC LOCAL HIDDEN [[#]] static_func.dyndbg.main
+CHECK-DAG: {{.*}} 0 OBJECT LOCAL HIDDEN [[#]] static_data.dyndbg.main
+CHECK-DAG: {{.*}} 0 FUNC LOCAL DEFAULT [[#]] static_func
+CHECK-DAG: {{.*}} 0 OBJECT LOCAL DEFAULT [[#]] static_data
+CHECK-DAG: {{.*}} 0 FUNC LOCAL HIDDEN [[#]] static_func.dyndbg.foo
+CHECK-DAG: {{.*}} 0 OBJECT LOCAL HIDDEN [[#]] static_data.dyndbg.foo
+CHECK-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] func
+CHECK-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] main
+CHECK-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] foo
+
+## Create and embed the "inner" unoptimized objects to simulate dynamic debugging objects.
+## Note that the embedded `.debug_llvm_dyndbg` section should be aligned to 8.
+RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/main-unopt.s -o %t/main-unopt.o
+RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/foo-unopt.s -o %t/foo-unopt.o
+RUN: llvm-objcopy --add-section=.debug_llvm_dyndbg=%t/main-unopt.o %t/main.o
+RUN: llvm-objcopy --set-section-type=.debug_llvm_dyndbg=0x6fff4c10 \
+RUN: --set-section-alignment=.debug_llvm_dyndbg=8 %t/main.o
+RUN: llvm-objcopy --add-section=.debug_llvm_dyndbg=%t/foo-unopt.o %t/foo.o
+RUN: llvm-objcopy --set-section-type=.debug_llvm_dyndbg=0x6fff4c10 \
+RUN: --set-section-alignment=.debug_llvm_dyndbg=8 %t/foo.o
+
+## Create shared object to test handling of "inner" only dependencies.
+RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/shared.s -o %t/shared.o
+RUN: ld.lld -shared -o %t/shared.so %t/shared.o
+
+## Link simulated dynamic debugging objects.
+RUN: ld.lld -e main -o %t/out-dd %t/main.o %t/foo.o %t/shared.so
+RUN: llvm-readelf -Srsn %t/out-dd | FileCheck -DNSYM=21 --check-prefixes=DD,NO-GC %s
+
+## Link simulated dynamic debugging objects using `--gc-sections`.
+## Note that `--gc-sections` is not yet supported for the "inner" unoptimized relocatable
+## link.
+RUN: ld.lld -e main --gc-sections -o %t/out-dd-gc %t/main.o %t/foo.o %t/shared.so
+RUN: llvm-readelf -Srsn %t/out-dd-gc | FileCheck -DNSYM=19 --check-prefixes=DD,GC %s
+
+## Check dynamic debugging related sections.
+DD: There are 20 section headers, starting at offset {{.*}}:
+DD: Name Type Address Off Size ES Flg Lk Inf Al
+DD-DAG: .debug_llvm_dyndbg LLVM_DYNDBG_ELF 0000000000000000 {{.*}} {{.*}} 00 0 0 8
+DD-DAG: .note.llvm.dyndbg NOTE 0000000000000000 {{.*}} {{.*}} 00 0 0 4
+
+## Check GOT/PLT entries in "outer" ELF for shared symbols only referenced by "inner"
+## unoptimized objects.
+DD: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entries:
+DD: {{.*}} {{.*}} R_X86_64_GLOB_DAT 0000000000000000 shared_data_for_unopt
+DD: Relocation section '.rela.plt' at offset {{.*}} contains 1 entries:
+DD: {{.*}} {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 shared_func_for_unopt
+
+NO-GC: Symbol table '.dynsym' contains 4 entries:
+GC: Symbol table '.dynsym' contains 3 entries:
+DD-DAG: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND shared_data_for_unopt
+DD-DAG: 0000000000000000 0 FUNC GLOBAL DEFAULT UND shared_func_for_unopt
+NO-GC-DAG: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND undef_used_by_non_alloc
+
+DD: Symbol table '.symtab' contains [[NSYM]] entries:
+DD-DAG: {{.*}} 0 FUNC LOCAL DEFAULT [[#]] static_func
+DD-DAG: {{.*}} 0 OBJECT LOCAL DEFAULT [[#]] static_data
+DD-DAG: {{.*}} 0 FUNC LOCAL HIDDEN [[#]] static_func.dyndbg.main
+DD-DAG: {{.*}} 0 OBJECT LOCAL HIDDEN [[#]] static_data.dyndbg.main
+DD-DAG: {{.*}} 0 FUNC LOCAL DEFAULT [[#]] static_func
+DD-DAG: {{.*}} 0 OBJECT LOCAL DEFAULT [[#]] static_data
+DD-DAG: {{.*}} 0 FUNC LOCAL HIDDEN [[#]] static_func.dyndbg.foo
+DD-DAG: {{.*}} 0 OBJECT LOCAL HIDDEN [[#]] static_data.dyndbg.foo
+DD-DAG: {{.*}} 0 NOTYPE LOCAL HIDDEN [[#]] _DYNAMIC
+DD-DAG: {{.*}} 0 FUNC WEAK DEFAULT [[#]] comdat_func
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] func
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] main
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] foo
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] inlined_in_opt
+NO-GC-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] unused_func
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] used_by_unused_func
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT [[#]] inlined_for_unopt_and_non_alloc
+DD-DAG: {{.*}} 0 OBJECT GLOBAL DEFAULT UND shared_data_for_unopt
+DD-DAG: {{.*}} 0 FUNC GLOBAL DEFAULT UND shared_func_for_unopt
+NO-GC-DAG: {{.*}} 0 NOTYPE GLOBAL DEFAULT UND undef_used_by_non_alloc
+## The following symbols are only present when linking the relocatable link
+## output of the simulated dynamic debugging objects.
+REL-DAG: {{.*}} 0 FILE LOCAL DEFAULT ABS main.o
+REL-DAG: {{.*}} 0 FILE LOCAL DEFAULT ABS foo.o
+REL-DAG: {{.*}} 0 FILE LOCAL DEFAULT ABS
+
+DD: LLVM 0x00000004 Unknown note type: (0x00000004)
----------------
smithp35 wrote:
I guess this is a FIXME for when llvm-objdump recognises the note type?
https://github.com/llvm/llvm-project/pull/214188
More information about the llvm-commits
mailing list