[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