Hi Mark,
On Fri, Jul 10, 2026 at 6:35 PM Mark Wielaard <[email protected]> wrote:
>
> DWARF5 supplementary files are the standardized variant of GNU alt (or
> multi) files. They also come with standardized forms for GNU_ref_alt
> (ref_sup4 and ref_sup8) and GNU_strp_alt (strp_sup).
>
> This patch adds support to dwarf_getalt to find sup files and fixes a
> few places where the new ref_sup and strp_sup FORMs weren't handled
> correctly. All tests that checked GNU alt/multi files now got a
> testcase added for a sup file (reference).
>
> * libdw/dwarf_formref_die.c (dwarf_formref_die): Also use alt
> file for DW_FORM_ref_sup4 and DW_FORM_ref_sup8.
> * libdw/dwarf_getalt.c (find_debug_altlink): Look for a
> .debug_sup section using dwelf_dwarf_debug_sup if
> debugaltlink cannot be found.
> * src/readelf.c (attr_callback): Also handle DW_FORM_strp_sup
> as string form.
> * tests/allfcts.c (setup_alt): Call dwelf_dwarf_debug_sup if
> dwelf_dwarf_gnu_debugaltlink failed.
> * tests/run-allfcts-multi.sh: Add testcase for
> testfile-dwarf5-ref-sup.
> * tests/run-buildid.sh: Add testcase for testfile-dwarf5.sup.
> * tests/run-debugaltlink.sh: Add testfile-dwarf5-ref-sup to
> test.
> * tests/run-dwarf-die-addr-die.sh: Add testfile-dwarf5-ref-sup
> testcase.
> * tests/run-eu-search-die.sh: Add testfile-dwarf5-ref-sup and
> testfile-dwarf5.sup.
> * tests/run-get-units-invalid.sh: Add testfile-dwarf5-ref-sup
> and testfile-dwarf5.sup testcases.
> * tests/run-get-units-split.sh: Add testfile-dwarf5-ref-sup
> testcase.
> * tests/run-readelf-dwz-multi.sh: Add testfile-dwarf5-ref-sup
> testcase.
> * tests/run-unit-info.sh: Add testfile-dwarf5-ref-sup
> testcase.
>
> Signed-off-by: Mark Wielaard <[email protected]>
> ---
> libdw/dwarf_formref_die.c | 2 +
> libdw/dwarf_getalt.c | 13 +++++--
> src/readelf.c | 1 +
> tests/allfcts.c | 8 +++-
> tests/run-allfcts-multi.sh | 7 ++++
> tests/run-buildid.sh | 8 ++--
> tests/run-debugaltlink.sh | 8 +++-
> tests/run-dwarf-die-addr-die.sh | 5 +++
> tests/run-eu-search-die.sh | 3 +-
> tests/run-get-units-invalid.sh | 5 +++
> tests/run-get-units-split.sh | 5 +++
> tests/run-readelf-dwz-multi.sh | 68 +++++++++++++++++++++++++++++++++
> tests/run-unit-info.sh | 5 +++
> 13 files changed, 128 insertions(+), 10 deletions(-)
>
> diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
> index 85c484f6560f..1bedf5e9ab06 100644
> --- a/libdw/dwarf_formref_die.c
> +++ b/libdw/dwarf_formref_die.c
> @@ -60,6 +60,8 @@ dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result)
> ref_size = cu->offset_size;
>
> Dwarf *dbg_ret = (attr->form == DW_FORM_GNU_ref_alt
> + || attr->form == DW_FORM_ref_sup4
> + || attr->form == DW_FORM_ref_sup8
> ? INTUSE(dwarf_getalt) (cu->dbg) : cu->dbg);
>
> if (dbg_ret == NULL)
> diff --git a/libdw/dwarf_getalt.c b/libdw/dwarf_getalt.c
> index f4b8ad02acdc..e94595c302a8 100644
> --- a/libdw/dwarf_getalt.c
> +++ b/libdw/dwarf_getalt.c
> @@ -103,10 +103,17 @@ find_debug_altlink (Dwarf *dbg)
> ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (dbg,
> &altname,
> &build_id);
> -
> - /* Couldn't even get the debugaltlink. It probably doesn't exist. */
> if (build_id_len <= 0)
> - return;
> + {
> + uint8_t is_sup;
> + build_id_len = INTUSE(dwelf_dwarf_debug_sup) (dbg, NULL, &is_sup,
> + &altname,
> + ((const uint8_t **)
> + &build_id));
> + /* Does the .debug_sup exist and is this a plain DWARF? */
> + if (build_id_len <= 0 || is_sup != 0)
Here's where the no-ID return value issue from patch 1 comes up. The
ID is not required for .debug_sup to be spec-conformant but in this case
dwarf_getalt will act like the section doesn't exist.
> + return;
> + }
>
> const uint8_t *id = (const uint8_t *) build_id;
> size_t id_len = build_id_len;
> diff --git a/src/readelf.c b/src/readelf.c
> index 9d3bbbf6f240..711342a0b793 100644
> --- a/src/readelf.c
> +++ b/src/readelf.c
> @@ -8022,6 +8022,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
>
> case DW_FORM_indirect:
> case DW_FORM_strp:
> + case DW_FORM_strp_sup:
> case DW_FORM_line_strp:
> case DW_FORM_strx:
> case DW_FORM_strx1:
> diff --git a/tests/allfcts.c b/tests/allfcts.c
> index f637311741bb..dd3bb6d345cd 100644
> --- a/tests/allfcts.c
> +++ b/tests/allfcts.c
> @@ -46,7 +46,13 @@ setup_alt (Dwarf *main)
> const void *build_id;
> ssize_t ret = dwelf_dwarf_gnu_debugaltlink (main, &alt_name, &build_id);
> if (ret == 0)
> - return NULL;
> + {
> + uint8_t is_sup;
> + ret = dwelf_dwarf_debug_sup (main, NULL, &is_sup, &alt_name,
> + (const uint8_t **) &build_id);
> + if (ret == 0 || is_sup != 0)
If ret == -1 then is_sup is read while uninitialized, although this should
never happen with the test binaries being fixed.
> + return NULL;
> + }
> if (ret == -1)
> errx (1, "dwelf_dwarf_gnu_debugaltlink: %s", dwarf_errmsg (-1));
> int fd = open (alt_name, O_RDONLY);
> diff --git a/tests/run-allfcts-multi.sh b/tests/run-allfcts-multi.sh
> index ef7bb30e5282..a6798dbcea52 100755
> --- a/tests/run-allfcts-multi.sh
> +++ b/tests/run-allfcts-multi.sh
> @@ -67,6 +67,13 @@ Warning: no alt file found.
> /tmp/test-offset-loop.c:7:main
> EOF
>
> +# See run-dwelf-dwarf-debug-sup.sh
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +testrun_compare ${abs_builddir}/allfcts testfile-dwarf5-ref-sup <<\EOF
> +/tmp/test-ref-sup.c:13:main
> +/tmp/test-ref-sup.c:8:func
> +EOF
> +
> rm -rf subdir
>
> exit 0
> diff --git a/tests/run-buildid.sh b/tests/run-buildid.sh
> index 31cec24d2d30..9f88ff163e88 100755
> --- a/tests/run-buildid.sh
> +++ b/tests/run-buildid.sh
> @@ -20,19 +20,21 @@
> # Just some random testfiles, four with, one without build-id,
> # and one without shdrs forcing reading the notes through phdrs.
> # eu-strip --strip-sections -g --output=testfile42_noshdrs testfile42
> -# See also run-debugaltlink.sh.
> +# See also run-debugaltlink.sh and run-dwelf-dwarf-debug-sup.sh
> +# supplementary files don't have build IDs, just a .debug_sup section.
> testfiles testfile42 testfile_multi.dwz testfile-dwzstr.multi \
> - test-offset-loop.alt testfile14 testfile42_noshdrs
> + test-offset-loop.alt testfile14 testfile42_noshdrs testfile-dwarf5.sup
>
> testrun_compare ${abs_builddir}/buildid testfile42 testfile42_noshdrs \
> testfile_multi.dwz testfile-dwzstr.multi \
> - test-offset-loop.alt testfile14 <<\EOF
> + test-offset-loop.alt testfile14 testfile-dwarf5.sup <<\EOF
> testfile42: build ID: d826d96c4d097bdc5c254b1f7344a907e36b0439
> testfile42_noshdrs: build ID: d826d96c4d097bdc5c254b1f7344a907e36b0439
> testfile_multi.dwz: build ID: a0d6c06e0d912d74033b6fe2808753cae8f6f594
> testfile-dwzstr.multi: build ID: 6da22627dae55c1d62cf9122827c665e240a056b
> test-offset-loop.alt: build ID: 066bbf1a7bc5676f5015ee1966a088f23bdb83ae
> testfile14: <no NT_GNU_BUILD_ID note>
> +testfile-dwarf5.sup: <no NT_GNU_BUILD_ID note>
> EOF
>
> exit 0
> diff --git a/tests/run-debugaltlink.sh b/tests/run-debugaltlink.sh
> index fa7dd26878a6..cb77e3a1f485 100755
> --- a/tests/run-debugaltlink.sh
> +++ b/tests/run-debugaltlink.sh
> @@ -18,17 +18,21 @@
> . $srcdir/test-subr.sh
>
> # Just some random testfiles, four with, one without .gnu_debugaltlink
> +# And a file with a supplementary file ref
> +# (no .gnu_debugaltlink, only a .debug_sup).
> testfiles testfile42 testfile_multi_main testfile-dwzstr \
> - test-offset-loop libtestfile_multi_shared.so
> + test-offset-loop libtestfile_multi_shared.so testfile-dwarf5-ref-sup
>
> testrun_compare ${abs_builddir}/debugaltlink testfile42 \
> testfile_multi_main testfile-dwzstr \
> - test-offset-loop libtestfile_multi_shared.so <<\EOF
> + test-offset-loop libtestfile_multi_shared.so \
> + testfile-dwarf5-ref-sup <<\EOF
> testfile42: <no .gnu_debugaltlink section>
> testfile_multi_main: testfile_multi.dwz, build ID:
> a0d6c06e0d912d74033b6fe2808753cae8f6f594
> testfile-dwzstr: testfile-dwzstr.multi, build ID:
> 6da22627dae55c1d62cf9122827c665e240a056b
> test-offset-loop: test-offset-loop.alt, build ID:
> 066bbf1a7bc5676f5015ee1966a088f23bdb83ae
> libtestfile_multi_shared.so: testfile_multi.dwz, build ID:
> a0d6c06e0d912d74033b6fe2808753cae8f6f594
> +testfile-dwarf5-ref-sup: <no .gnu_debugaltlink section>
> EOF
>
> exit 0
> diff --git a/tests/run-dwarf-die-addr-die.sh b/tests/run-dwarf-die-addr-die.sh
> index 951d1c52385b..d333cdc9e07a 100755
> --- a/tests/run-dwarf-die-addr-die.sh
> +++ b/tests/run-dwarf-die-addr-die.sh
> @@ -46,6 +46,11 @@ testrun ${abs_builddir}/dwarf-die-addr-die
> testfile-world4.dwo
> testrun ${abs_builddir}/dwarf-die-addr-die testfile-hello5.dwo
> testrun ${abs_builddir}/dwarf-die-addr-die testfile-world5.dwo
>
> +# See run-dwelf-dwarf-debug-sup.sh
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +
> +testrun ${abs_builddir}/dwarf-die-addr-die testfile-dwarf5-ref-sup
> +
> # Self test
> testrun_on_self ${abs_builddir}/dwarf-die-addr-die
>
> diff --git a/tests/run-eu-search-die.sh b/tests/run-eu-search-die.sh
> index bc8a59590c2d..61392dd653f3 100755
> --- a/tests/run-eu-search-die.sh
> +++ b/tests/run-eu-search-die.sh
> @@ -25,7 +25,8 @@ die_test_files=("testfile-debug-types"
> "testfilebazdbgppc64.debug"
> "testfile-dwarf-4" "testfile-dwarf-5"
> "testfile-splitdwarf-4" "testfile-hello4.dwo"
> "testfile-world4.dwo"
> - "testfile-splitdwarf-5" "testfile-hello5.dwo"
> "testfile-world5.dwo")
> + "testfile-splitdwarf-5" "testfile-hello5.dwo"
> "testfile-world5.dwo"
> + "testfile-dwarf5-ref-sup" "testfile-dwarf5.sup")
>
> testfiles "${die_test_files[@]}"
>
> diff --git a/tests/run-get-units-invalid.sh b/tests/run-get-units-invalid.sh
> index 66ef944411d9..4babeb706562 100755
> --- a/tests/run-get-units-invalid.sh
> +++ b/tests/run-get-units-invalid.sh
> @@ -38,6 +38,11 @@ testfiles testfile-dwarf-4 testfile-dwarf-5
> testrun ${abs_builddir}/get-units-invalid testfile-dwarf-4
> testrun ${abs_builddir}/get-units-invalid testfile-dwarf-5
>
> +# see run-dwelf-dwarf-debug-sup.sh
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +testrun ${abs_builddir}/get-units-invalid testfile-dwarf5-ref-sup
> +testrun ${abs_builddir}/get-units-invalid testfile-dwarf5.sup
> +
> # Self test
> testrun_on_self ${abs_builddir}/get-units-invalid
>
> diff --git a/tests/run-get-units-split.sh b/tests/run-get-units-split.sh
> index 6c7a4f25df10..52361fa8f874 100755
> --- a/tests/run-get-units-split.sh
> +++ b/tests/run-get-units-split.sh
> @@ -27,6 +27,11 @@ testfiles testfile_multi_main testfile_multi.dwz
>
> testrun ${abs_builddir}/get-units-split testfile_multi_main
>
> +# see run-dwelf-dwarf-debug-sup.sh
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +
> +testrun ${abs_builddir}/get-units-split testfile-dwarf5-ref-sup
> +
> # see tests/run-dwflsyms.sh
> testfiles testfilebazdbgppc64.debug
>
> diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh
> index 4f317ac9ab11..a36ee2ab2773 100755
> --- a/tests/run-readelf-dwz-multi.sh
> +++ b/tests/run-readelf-dwz-multi.sh
> @@ -329,4 +329,72 @@ DWARF section [28] '.debug_info' at offset 0x1088:
> [ 0] fbreg -32
> EOF
>
> +# See run-dwelf-dwarf-debug-sup.sh
> +# Supplementary files are the DWARF5 standardized variant of multi (GNU alt).
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +
> +testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info
> testfile-dwarf5-ref-sup <<\EOF
> +
> +DWARF section [28] '.debug_info' at offset 0x22f8:
> + [Offset]
> + Compilation unit at offset 0:
> + Version: 5, Abbreviation section offset: 0, Address size: 8, Offset size: 4
> + Unit type: compile (1)
> + [ c] compile_unit abbrev: 1
> + producer (strp_sup) "GNU C23 16.1.1 20260515 (Red Hat
> 16.1.1-2) -mtune=generic -march=x86-64 -mtls-dialect=gnu2 -gdwarf-5"
> + language (data1) C11 (29)
> + language_name (data1) C (3)
> + language_version (data4) 202311
> + name (line_strp) "test-ref-sup.c"
> + comp_dir (line_strp) "/tmp"
> + low_pc (addr) 0x0000000000400446 <func>
> + high_pc (udata) 69 (0x000000000040048b)
> + stmt_list (sec_offset) 0
> + [ 2c] imported_unit abbrev: 2
> + import (ref_sup4) [ c]
> + [ 31] subprogram abbrev: 6
> + external (flag_present) yes
> + name (strp_sup) "main"
> + decl_file (data1) test-ref-sup.c (1)
> + decl_line (data1) 13
> + decl_column (data1) 5
> + prototyped (flag_present) yes
> + type (ref_sup4) [ 32]
> + low_pc (addr) 0x000000000040045f <main>
> + high_pc (udata) 44 (0x000000000040048b)
> + frame_base (exprloc)
> + [ 0] call_frame_cfa
> + call_all_tail_calls (flag_present) yes
> + sibling (ref_udata) [ 57]
> + [ 49] variable abbrev: 3
> + name (string) "x"
> + decl_file (data1) test-ref-sup.c (1)
> + decl_line (data1) 15
> + decl_column (data1) 14
> + type (ref_sup4) [ 11]
> + location (exprloc)
> + [ 0] fbreg -32
> + [ 57] subprogram abbrev: 5
> + external (flag_present) yes
> + name (strp_sup) "func"
> + decl_file (data1) test-ref-sup.c (1)
> + decl_line (data1) 8
> + decl_column (data1) 5
> + prototyped (flag_present) yes
> + type (ref_sup4) [ 32]
> + low_pc (addr) 0x0000000000400446 <func>
> + high_pc (udata) 25 (0x000000000040045f <main>)
> + frame_base (exprloc)
> + [ 0] call_frame_cfa
> + call_all_calls (flag_present) yes
> + [ 6e] formal_parameter abbrev: 4
> + name (string) "f"
> + decl_file (data1) test-ref-sup.c (1)
> + decl_line (data1) 8
> + decl_column (data1) 22
> + type (ref_sup4) [ 39]
> + location (exprloc)
> + [ 0] fbreg -24
> +EOF
> +
> exit 0
> diff --git a/tests/run-unit-info.sh b/tests/run-unit-info.sh
> index 328fe78be59b..158b633d311f 100755
> --- a/tests/run-unit-info.sh
> +++ b/tests/run-unit-info.sh
> @@ -27,6 +27,11 @@ testfiles testfile_multi_main testfile_multi.dwz
>
> testrun ${abs_builddir}/unit-info testfile_multi_main
>
> +# see run-dwelf-dwarf-debug-sup.sh
> +testfiles testfile-dwarf5-ref-sup testfile-dwarf5.sup
> +
> +testrun ${abs_builddir}/unit-info testfile-dwarf5-ref-sup
> +
> # see tests/run-dwflsyms.sh
> testfiles testfilebazdbgppc64.debug
>
> --
> 2.55.0
>