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)
+       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)
+        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