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
>

Reply via email to