public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Binutils support for split-dwarf and dwarf-5
@ 2022-06-02 14:55 Kumar N, Bhuvanendra
  2022-06-03 12:04 ` Jan Beulich
  0 siblings, 1 reply; 3+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-06-02 14:55 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, George, Jini Susan, Natarajan, Kavitha

[-- Attachment #1: Type: text/plain, Size: 19640 bytes --]

[Public]

Hi,

Binutils support for split-dwarf and dwarf5 is now added for gcc and clang. There are 2 patches. Basic sections dump like .debug_info.dwo, .debug_abbrev.dwo, .debug_str.dwo etc are supported in patch 1/2. location list and ranges list sections dump with split-dwarf and dwarf5 are supported in patch 2/2 and patch 2/2 is continuation of patch 1/2. Both the patches are attached and also inlined below. Separating these issues as individual patches might be easy to review, hence 2 patches are there.

Issues fixed in patch 1/2 :
There are few differences b/w dwarf4 and dwarf5 as shared below, w.r.t. split-dwarf support added like different attributes/forms used to represent DWO name and ID, .debug_str_offsets section etc. All these are addressed. I have tested these changes with gcc and clang compiled objects with split-dwarf and dwarf-5.

DWARF4:

  *   DW_AT_GNU_dwo_name [DW_FORM_strp]
  *   DW_AT_GNU_dwo_id [DW_FORM_data8]
  *   Above attribute are part of DW_TAG_compile_unit

DWARF5:

  *   DW_AT_dwo_name [DW_FORM_strp]
  *   Above attribute is part of DW_TAG_skeleton_unit
  *   .debug_str_offsets is used to refer to .debug_str section

NOTE: DWO ID is not printed for dwarf 5 during initial dwo file dump information summary. But its dumped under .debug_info section dump. Because now there is no separate attribute in dwarf5 for DWO ID like it was there in dwarf4(DW_AT_GNU_dwo_id).

Issues fixed in patch 2/2 :
.debug_loclists.dwo and .debug_rnglists.dwo section dumps are taken care. I have tested these changes for clang compiled objects with split-dwarf and dwarf-5, where .debug_loclists.dwo and .debug_rnglists.dwo sections exist in the separate debug file (.dwo files)

Regards,
bhuvan

Patch 1/2 inlined:

From 1bda1e144f43d1f41fe30a934ba008561083dc07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Thu, 2 Jun 2022 17:44:02 +0530
Subject: [PATCH] [PATCH 1/2] Binutils support for split-dwarf and dwarf-5.

This fix adds support for split-dwarf and dwarf5, for both gcc and clang.
There are 2 patches. Basic sections dump like .debug_info.dwo,
.debug_abbrev.dwo, .debug_str.dwo etc are supported in this patch 1/2.
But location list and ranges list sections dump with split-dwarf and dwarf5
are supported in the next patch 2/2.

There are few differences b/w dwarf4 and dwarf5, w.r.t. split-dwarf support
added like different attributes/forms used to represent DWO name and ID,
.debug_str_offsets section etc. All these are addressed.

      * dwarf.c (fetch_indexed_string): Use str_offsets_base to calculate
      the string offset.
      (read_and_display_attr_value): Set str_offsets_base i.e. string offset
      table base address.
      (process_debug_info): Include DW_TAG_skeleton_unit.
      (load_separate_debug_files): Load .debug_str_offsets if exists.
      Skip DWO ID dump for dwarf-5.
      * testsuite/binutils-all/readelf.exp: Added new test point.
      * testsuite/binutils-all/readelf.k5: New file.
      * testsuite/binutils-all/dwo_5.s: New file.
---
binutils/dwarf.c                            |  11 +-
binutils/testsuite/binutils-all/dwo_5.s     | 257 ++++++++++++++++++++
binutils/testsuite/binutils-all/readelf.exp |  12 +
binutils/testsuite/binutils-all/readelf.k5  |   7 +
4 files changed, 285 insertions(+), 2 deletions(-)
create mode 100644 binutils/testsuite/binutils-all/dwo_5.s
create mode 100644 binutils/testsuite/binutils-all/readelf.k5

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..e8f0ea4cf0c 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,6 +118,8 @@ int dwarf_cutoff_level = -1;
unsigned long dwarf_start_die;
 int dwarf_check = 0;
+static dwarf_vma str_offsets_base = 0;
+#define DEBUG_STR_OFFSETS_HEADER_LEN 8
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -779,7 +781,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
       return _("<index offset is too big>");
     }
-  str_offset = byte_get (curr + index_offset, offset_size);
+  str_offset = byte_get (curr + index_offset + str_offsets_base, offset_size);
   str_offset -= str_section->address;
   if (str_offset >= str_section->size)
     {
@@ -2485,6 +2487,8 @@ read_and_display_attr_value (unsigned long           attribute,
     case DW_FORM_GNU_ref_alt:
     case DW_FORM_GNU_strp_alt:
       SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
+      if (attribute == DW_AT_str_offsets_base)
+        str_offsets_base = uvalue - DEBUG_STR_OFFSETS_HEADER_LEN;
       break;
     case DW_FORM_flag_present:
@@ -4016,6 +4020,7 @@ process_debug_info (struct dwarf_section * section,
           need_base_address = 0;
           break;
         case DW_TAG_compile_unit:
+         case DW_TAG_skeleton_unit:
           need_base_address = 1;
           need_dwo_info = do_loc;
           break;
@@ -4059,6 +4064,7 @@ process_debug_info (struct dwarf_section * section,
                               level);
         }
+       str_offsets_base = 0;
       /* If a locview attribute appears before a location one,
          make sure we don't associate it with an earlier
          loclist. */
@@ -11889,6 +11895,7 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (abbrev, file)
       && load_debug_section (info, file))
     {
+      load_debug_section (str_index, file);
       free_dwo_info ();
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
@@ -11948,7 +11955,7 @@ load_separate_debug_files (void * file, const char * filename)
                printf (_("  Directory: %s\n"), dir ? dir : _("<not-found>"));
                if (id != NULL)
                display_data (printf (_("  ID:       ")), (unsigned char *) id, 8);
-                else
+                else if (debug_information[0].dwarf_version != 5)
                printf (_("  ID:        <not specified>\n"));
                printf ("\n\n");
              }
diff --git a/binutils/testsuite/binutils-all/dwo_5.s b/binutils/testsuite/binutils-all/dwo_5.s
new file mode 100644
index 00000000000..e394467c2be
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dwo_5.s
@@ -0,0 +1,257 @@
+     .file "a.c"
+     .text
+.Ltext0:
+     .globl     a
+     .type a, @function
+a:
+.LFB0:
+     .file 1 "a.c"
+     .loc 1 1 13
+     .cfi_startproc
+     pushq %rbp
+     .cfi_def_cfa_offset 16
+     .cfi_offset 6, -16
+     movq %rsp, %rbp
+     .cfi_def_cfa_register 6
+     .loc 1 1 22
+     movl $111, %eax
+     .loc 1 1 1
+     popq %rbp
+     .cfi_def_cfa 7, 8
+     ret
+     .cfi_endproc
+.LFE0:
+     .size a, .-a
+.Letext0:
+     .section   .debug_addr,"",@progbits
+     .long 0xc
+     .value     0x5
+     .byte 0x8
+     .byte 0
+.Ldebug_addr0:
+     .quad .LFB0
+     .section   .debug_info.dwo,"e",@progbits
+.Ldebug_info0:
+     .long 0x35
+     .value     0x5
+     .byte 0x5
+     .byte 0x8
+     .long .Ldebug_abbrev0
+     .byte 0x46
+     .byte 0x1c
+     .byte 0xf1
+     .byte 0xfb
+     .byte 0xe5
+     .byte 0x96
+     .byte 0x7d
+     .byte 0x2b
+     .uleb128 0x1
+     .uleb128 0x1
+     .byte 0x1d
+     .string    "a.c"
+     .uleb128 0
+     .uleb128 0x2
+     .string    "a"
+     .byte 0x1
+     .byte 0x1
+     .byte 0x5
+     .long 0x31
+     .uleb128 0
+     .quad .LFE0-.LFB0
+     .uleb128 0x1
+     .byte 0x9c
+     .uleb128 0x3
+     .byte 0x4
+     .byte 0x5
+     .string    "int"
+     .byte 0
+     .section   .debug_info,"",@progbits
+.Lskeleton_debug_info0:
+     .long 0x31
+     .value     0x5
+     .byte 0x4
+     .byte 0x8
+     .long .Lskeleton_debug_abbrev0
+     .byte 0x46
+     .byte 0x1c
+     .byte 0xf1
+     .byte 0xfb
+     .byte 0xe5
+     .byte 0x96
+     .byte 0x7d
+     .byte 0x2b
+     .uleb128 0x1
+     .quad .Ltext0
+     .quad .Letext0-.Ltext0
+     .long .Ldebug_line0
+     .long .LASF0
+     .long .LASF1
+     .long .Ldebug_addr0
+     .section   .debug_abbrev,"",@progbits
+.Lskeleton_debug_abbrev0:
+     .uleb128 0x1
+     .uleb128 0x4a
+     .byte 0
+     .uleb128 0x11
+     .uleb128 0x1
+     .uleb128 0x12
+     .uleb128 0x7
+     .uleb128 0x10
+     .uleb128 0x17
+     .uleb128 0x76
+     .uleb128 0xe
+     .uleb128 0x1b
+     .uleb128 0xe
+     .uleb128 0x2134
+     .uleb128 0x19
+     .uleb128 0x73
+     .uleb128 0x17
+     .byte 0
+     .byte 0
+     .byte 0
+     .section   .debug_abbrev.dwo,"e",@progbits
+.Ldebug_abbrev0:
+     .uleb128 0x1
+     .uleb128 0x11
+     .byte 0x1
+     .uleb128 0x25
+     .uleb128 0x1a
+     .uleb128 0x13
+     .uleb128 0xb
+     .uleb128 0x3
+     .uleb128 0x8
+     .uleb128 0x1b
+     .uleb128 0x1a
+     .byte 0
+     .byte 0
+     .uleb128 0x2
+     .uleb128 0x2e
+     .byte 0
+     .uleb128 0x3f
+     .uleb128 0x19
+     .uleb128 0x3
+     .uleb128 0x8
+     .uleb128 0x3a
+     .uleb128 0xb
+     .uleb128 0x3b
+     .uleb128 0xb
+     .uleb128 0x39
+     .uleb128 0xb
+     .uleb128 0x27
+     .uleb128 0x19
+     .uleb128 0x49
+     .uleb128 0x13
+     .uleb128 0x11
+     .uleb128 0x1b
+     .uleb128 0x12
+     .uleb128 0x7
+     .uleb128 0x40
+     .uleb128 0x18
+     .uleb128 0x7a
+     .uleb128 0x19
+     .byte 0
+     .byte 0
+     .uleb128 0x3
+     .uleb128 0x24
+     .byte 0
+     .uleb128 0xb
+     .uleb128 0xb
+     .uleb128 0x3e
+     .uleb128 0xb
+     .uleb128 0x3
+     .uleb128 0x8
+     .byte 0
+     .byte 0
+     .byte 0
+     .section   .debug_gnu_pubnames,"",@progbits
+     .long 0x15
+     .value     0x2
+     .long .Lskeleton_debug_info0
+     .long 0x39
+     .long 0x1c
+     .byte 0x30
+     .string    "a"
+     .long 0
+     .section   .debug_gnu_pubtypes,"",@progbits
+     .long 0x17
+     .value     0x2
+     .long .Lskeleton_debug_info0
+     .long 0x39
+     .long 0x31
+     .byte 0x90
+     .string    "int"
+     .long 0
+     .section   .debug_aranges,"",@progbits
+     .long 0x2c
+     .value     0x2
+     .long .Lskeleton_debug_info0
+     .byte 0x8
+     .byte 0
+     .value     0
+     .value     0
+     .quad .Ltext0
+     .quad .Letext0-.Ltext0
+     .quad 0
+     .quad 0
+     .section   .debug_line,"",@progbits
+.Ldebug_line0:
+     .section   .debug_line.dwo,"e",@progbits
+.Lskeleton_debug_line0:
+     .long .LELT0-.LSLT0
+.LSLT0:
+     .value     0x5
+     .byte 0x8
+     .byte 0
+     .long .LELTP0-.LASLTP0
+.LASLTP0:
+     .byte 0x1
+     .byte 0x1
+     .byte 0x1
+     .byte 0xf6
+     .byte 0xf2
+     .byte 0xd
+     .byte 0
+     .byte 0x1
+     .byte 0x1
+     .byte 0x1
+     .byte 0x1
+     .byte 0
+     .byte 0
+     .byte 0
+     .byte 0x1
+     .byte 0
+     .byte 0
+     .byte 0x1
+     .byte 0x1
+     .uleb128 0x1
+     .uleb128 0x8
+     .uleb128 0x1
+     .string    "/tmp"
+     .byte 0x2
+     .uleb128 0x1
+     .uleb128 0x8
+     .uleb128 0x2
+     .uleb128 0xb
+     .uleb128 0x2
+     .string    "a.c"
+     .byte 0
+     .string    "a.c"
+     .byte 0
+.LELTP0:
+.LELT0:
+     .section   .debug_str,"MS",@progbits,1
+.LASF1:
+     .string    "/tmp"
+.LASF0:
+     .string    "a.dwo"
+     .section      .debug_str_offsets.dwo,"e",@progbits
+     .long 0xc
+     .value     0x5
+     .value     0
+     .long 0
+     .long 0x5
+     .section   .debug_str.dwo,"e",@progbits
+     .string    "/tmp"
+     .string    "GNU C17 10.0.0 20190813 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -gsplit-dwarf"
+     .ident     "GCC: (GNU) 10.0.0 20190813 (experimental)"
+     .section   .note.GNU-stack,"",@progbits
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index 0f7a1f3b5a0..b68224d5019 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -572,6 +572,18 @@ if {![binutils_assemble $srcdir/$subdir/dwo.s tmpdir/dwo.o]} then {
     readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k2
}
+if {![binutils_assemble $srcdir/$subdir/dwo_5.s tmpdir/dwo_5.o]} then {
+    unsupported "readelf --debug-dump=links (failed to assemble dwo_5.s)"
+} else {
+    if ![is_remote host] {
+        set tempfile tmpdir/dwo_5.o
+    } else {
+        set tempfile [remote_download host tmpdir/dwo_5.o]
+    }
+
+    readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k5
+}
+
if {![binutils_assemble $srcdir/$subdir/zero-sec.s tmpdir/zero-sec.o]} then {
     unsupported "readelf --enable-checks (failed to assemble zero-sec.s)"
} else {
diff --git a/binutils/testsuite/binutils-all/readelf.k5 b/binutils/testsuite/binutils-all/readelf.k5
new file mode 100644
index 00000000000..49779224f2c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.k5
@@ -0,0 +1,7 @@
+The .debug_info section contains link\(s\) to dwo file\(s\):
+
+  Name:      a.dwo
+  Directory: /tmp
+
+
+
--
2.17.1


Patch 2/2 inlined:
From dab73681a6e19c16c799d150cc79cace3f8f894c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Thu, 2 Jun 2022 19:19:13 +0530
Subject: [PATCH] [PATCH 2/2] Binutils support for split-dwarf and dwarf-5.

This fix adds support for split-dwarf and dwarf5. There are 2 patches.
Basic sections dump like .debug_info.dwo, .debug_abbrev.dwo, .debug_str.dwo
etc are supported in the previous patch 1/2. location list and ranges list
sections dump with split-dwarf and dwarf5 are supported in this patch 2/2
and its continuation of patch 1/2.

.debug_loclists.dwo and .debug_rnglists.dwo section dumps are taken care in
this patch 2/2.

      * dwarf.c(read_and_display_attr_value): Handle DW_FORM_loclistx
      and DW_FORM_rnglistx for .dwo files.
      (process_debug_info): Load .debug_loclists.dwo and
      .debug_rnglists.dwo if exists.
      (load_separate_debug_files): Load .debug_loclists and
      .debug_rnglists if exists.
      Include 2 entries in debug_displays table.
      * dwarf.h (enum dwarf_section_display_enum): Include 2 entries.
---
binutils/dwarf.c | 39 +++++++++++++++++++++++++++++++++++++--
binutils/dwarf.h |  2 ++
2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index e8f0ea4cf0c..7b4bb445da4 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -120,6 +120,7 @@ unsigned long dwarf_start_die;
int dwarf_check = 0;
static dwarf_vma str_offsets_base = 0;
#define DEBUG_STR_OFFSETS_HEADER_LEN 8
+#define DEBUG_LOC_RNGLISTS_SEC_HDR_LEN 12
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -2792,7 +2793,34 @@ read_and_display_attr_value (unsigned long           attribute,
        offset = base + uvalue * pointer_size;
-       if (do_wide)
+       const char *suffix = strrchr (section->name, '.');
+       bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
+
+       if (form == DW_FORM_loclistx)
+         {
+           if (!dwo)
+             printf (_("%c(index: 0x%s): %s"), delimiter,
+                     dwarf_vmatoa ("x", uvalue),
+                     dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
+           else
+             printf (_("%c(index: 0x%s): %s"), delimiter,
+                     dwarf_vmatoa ("x", uvalue),
+                     dwarf_vmatoa ("x", fetch_indexed_value (uvalue, loclists_dwo)
+                                        + DEBUG_LOC_RNGLISTS_SEC_HDR_LEN));
+         }
+       else if (form == DW_FORM_rnglistx)
+         {
+           if (!dwo)
+             printf (_("%c(index: 0x%s): %s"), delimiter,
+                     dwarf_vmatoa ("x", uvalue),
+                     dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
+           else
+             printf (_("%c(index: 0x%s): %s"), delimiter,
+                     dwarf_vmatoa ("x", uvalue),
+                     dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists_dwo)
+                                        + DEBUG_LOC_RNGLISTS_SEC_HDR_LEN));
+         }
+       else if (do_wide)
         /* We have already displayed the form name.  */
         printf (_("%c(index: 0x%s): %s"), delimiter,
              dwarf_vmatoa ("x", uvalue),
@@ -3608,7 +3636,9 @@ process_debug_info (struct dwarf_section * section,
   load_debug_section_with_follow (abbrev_sec, file);
   load_debug_section_with_follow (loclists, file);
   load_debug_section_with_follow (rnglists, file);
-
+  load_debug_section_with_follow (loclists_dwo, file);
+  load_debug_section_with_follow (rnglists_dwo, file);
+
   if (debug_displays [abbrev_sec].section.start == NULL)
     {
       warn (_("Unable to locate %s section!\n"),
@@ -11896,6 +11926,9 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (info, file))
     {
       load_debug_section (str_index, file);
+      load_debug_section (loclists, file);
+      load_debug_section (rnglists, file);
+
       free_dwo_info ();
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
@@ -12265,10 +12298,12 @@ struct dwarf_section_display debug_displays[] =
   { { ".debug_line_str",    ".zdebug_line_str",      "",  NO_ABBREVS },      display_debug_str,         &do_debug_str,  false },
   { { ".debug_loc",      ".zdebug_loc",         ".dwloc",  NO_ABBREVS },      display_debug_loc,          &do_debug_loc,    true },
   { { ".debug_loclists",    ".zdebug_loclists",      "",  NO_ABBREVS },      display_debug_loc,         &do_debug_loc,  true },
+  { { ".debug_loclists.dwo", ".zdebug_loclists.dwo", "",         NO_ABBREVS },      display_debug_loc,      &do_debug_loc,      true },
   { { ".debug_pubtypes",    ".zdebug_pubtypes",      ".dwpbtyp", NO_ABBREVS },      display_debug_pubnames, &do_debug_pubtypes, false },
   { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", "", NO_ABBREVS },      display_debug_gnu_pubnames, &do_debug_pubtypes, false },
   { { ".debug_ranges",        ".zdebug_ranges",      ".dwrnges", NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,   true },
   { { ".debug_rnglists",    ".zdebug_rnglists",      "",  NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,     true },
+  { { ".debug_rnglists.dwo", ".zdebug_rnglists.dwo", "",         NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,   true },
   { { ".debug_static_func", ".zdebug_static_func",   "",  NO_ABBREVS },      display_debug_not_supported, NULL,          false },
   { { ".debug_static_vars", ".zdebug_static_vars",   "",  NO_ABBREVS },      display_debug_not_supported, NULL,          false },
   { { ".debug_types",         ".zdebug_types",       "",  ABBREV (abbrev) }, display_debug_types,    &do_debug_info, true },
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..86b635ef3c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -92,10 +92,12 @@ enum dwarf_section_display_enum
   line_str,
   loc,
   loclists,
+  loclists_dwo,
   pubtypes,
   gnu_pubtypes,
   ranges,
   rnglists,
+  rnglists_dwo,
   static_func,
   static_vars,
   types,
--
2.17.1





[-- Attachment #2: 0001-PATCH-1-2-Binutils-support-for-split-dwarf-and-dwarf.patch --]
[-- Type: application/octet-stream, Size: 9886 bytes --]

From 1bda1e144f43d1f41fe30a934ba008561083dc07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Thu, 2 Jun 2022 17:44:02 +0530
Subject: [PATCH] [PATCH 1/2] Binutils support for split-dwarf and dwarf-5.

This fix adds support for split-dwarf and dwarf5, for both gcc and clang.
There are 2 patches. Basic sections dump like .debug_info.dwo,
.debug_abbrev.dwo, .debug_str.dwo etc are supported in this patch 1/2.
But location list and ranges list sections dump with split-dwarf and dwarf5
are supported in the next patch 2/2.

There are few differences b/w dwarf4 and dwarf5, w.r.t. split-dwarf support
added like different attributes/forms used to represent DWO name and ID,
.debug_str_offsets section etc. All these are addressed.

	* dwarf.c (fetch_indexed_string): Use str_offsets_base to calculate
	the string offset.
	(read_and_display_attr_value): Set str_offsets_base i.e. string offset
	table base address.
	(process_debug_info): Include DW_TAG_skeleton_unit.
	(load_separate_debug_files): Load .debug_str_offsets if exists.
	Skip DWO ID dump for dwarf-5.
	* testsuite/binutils-all/readelf.exp: Added new test point.
	* testsuite/binutils-all/readelf.k5: New file.
	* testsuite/binutils-all/dwo_5.s: New file.
---
 binutils/dwarf.c                            |  11 +-
 binutils/testsuite/binutils-all/dwo_5.s     | 257 ++++++++++++++++++++
 binutils/testsuite/binutils-all/readelf.exp |  12 +
 binutils/testsuite/binutils-all/readelf.k5  |   7 +
 4 files changed, 285 insertions(+), 2 deletions(-)
 create mode 100644 binutils/testsuite/binutils-all/dwo_5.s
 create mode 100644 binutils/testsuite/binutils-all/readelf.k5

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..e8f0ea4cf0c 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,6 +118,8 @@ int dwarf_cutoff_level = -1;
 unsigned long dwarf_start_die;
 
 int dwarf_check = 0;
+static dwarf_vma str_offsets_base = 0;
+#define DEBUG_STR_OFFSETS_HEADER_LEN 8
 
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -779,7 +781,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
       return _("<index offset is too big>");
     }
 
-  str_offset = byte_get (curr + index_offset, offset_size);
+  str_offset = byte_get (curr + index_offset + str_offsets_base, offset_size);
   str_offset -= str_section->address;
   if (str_offset >= str_section->size)
     {
@@ -2485,6 +2487,8 @@ read_and_display_attr_value (unsigned long           attribute,
     case DW_FORM_GNU_ref_alt:
     case DW_FORM_GNU_strp_alt:
       SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
+      if (attribute == DW_AT_str_offsets_base)
+        str_offsets_base = uvalue - DEBUG_STR_OFFSETS_HEADER_LEN;
       break;
 
     case DW_FORM_flag_present:
@@ -4016,6 +4020,7 @@ process_debug_info (struct dwarf_section * section,
 	      need_base_address = 0;
 	      break;
 	    case DW_TAG_compile_unit:
+	    case DW_TAG_skeleton_unit:
 	      need_base_address = 1;	
 	      need_dwo_info = do_loc;
 	      break;
@@ -4059,6 +4064,7 @@ process_debug_info (struct dwarf_section * section,
 					    level);
 	    }
 
+	  str_offsets_base = 0;
 	  /* If a locview attribute appears before a location one,
 	     make sure we don't associate it with an earlier
 	     loclist. */
@@ -11889,6 +11895,7 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (abbrev, file)
       && load_debug_section (info, file))
     {
+      load_debug_section (str_index, file);
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
@@ -11948,7 +11955,7 @@ load_separate_debug_files (void * file, const char * filename)
 		      printf (_("  Directory: %s\n"), dir ? dir : _("<not-found>"));
 		      if (id != NULL)
 			display_data (printf (_("  ID:       ")), (unsigned char *) id, 8);
-		      else
+		      else if (debug_information[0].dwarf_version != 5)
 			printf (_("  ID:        <not specified>\n"));
 		      printf ("\n\n");
 		    }
diff --git a/binutils/testsuite/binutils-all/dwo_5.s b/binutils/testsuite/binutils-all/dwo_5.s
new file mode 100644
index 00000000000..e394467c2be
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dwo_5.s
@@ -0,0 +1,257 @@
+	.file	"a.c"
+	.text
+.Ltext0:
+	.globl	a
+	.type	a, @function
+a:
+.LFB0:
+	.file 1 "a.c"
+	.loc 1 1 13
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	.loc 1 1 22
+	movl	$111, %eax
+	.loc 1 1 1
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	a, .-a
+.Letext0:
+	.section	.debug_addr,"",@progbits
+	.long	0xc
+	.value	0x5
+	.byte	0x8
+	.byte	0
+.Ldebug_addr0:
+	.quad	.LFB0
+	.section	.debug_info.dwo,"e",@progbits
+.Ldebug_info0:
+	.long	0x35
+	.value	0x5
+	.byte	0x5
+	.byte	0x8
+	.long	.Ldebug_abbrev0
+	.byte	0x46
+	.byte	0x1c
+	.byte	0xf1
+	.byte	0xfb
+	.byte	0xe5
+	.byte	0x96
+	.byte	0x7d
+	.byte	0x2b
+	.uleb128 0x1
+	.uleb128 0x1
+	.byte	0x1d
+	.string	"a.c"
+	.uleb128 0
+	.uleb128 0x2
+	.string	"a"
+	.byte	0x1
+	.byte	0x1
+	.byte	0x5
+	.long	0x31
+	.uleb128 0
+	.quad	.LFE0-.LFB0
+	.uleb128 0x1
+	.byte	0x9c
+	.uleb128 0x3
+	.byte	0x4
+	.byte	0x5
+	.string	"int"
+	.byte	0
+	.section	.debug_info,"",@progbits
+.Lskeleton_debug_info0:
+	.long	0x31
+	.value	0x5
+	.byte	0x4
+	.byte	0x8
+	.long	.Lskeleton_debug_abbrev0
+	.byte	0x46
+	.byte	0x1c
+	.byte	0xf1
+	.byte	0xfb
+	.byte	0xe5
+	.byte	0x96
+	.byte	0x7d
+	.byte	0x2b
+	.uleb128 0x1
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.long	.Ldebug_line0
+	.long	.LASF0
+	.long	.LASF1
+	.long	.Ldebug_addr0
+	.section	.debug_abbrev,"",@progbits
+.Lskeleton_debug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x4a
+	.byte	0
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x10
+	.uleb128 0x17
+	.uleb128 0x76
+	.uleb128 0xe
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x2134
+	.uleb128 0x19
+	.uleb128 0x73
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_abbrev.dwo,"e",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0x1a
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x1b
+	.uleb128 0x1a
+	.byte	0
+	.byte	0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x39
+	.uleb128 0xb
+	.uleb128 0x27
+	.uleb128 0x19
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1b
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x40
+	.uleb128 0x18
+	.uleb128 0x7a
+	.uleb128 0x19
+	.byte	0
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_gnu_pubnames,"",@progbits
+	.long	0x15
+	.value	0x2
+	.long	.Lskeleton_debug_info0
+	.long	0x39
+	.long	0x1c
+	.byte	0x30
+	.string	"a"
+	.long	0
+	.section	.debug_gnu_pubtypes,"",@progbits
+	.long	0x17
+	.value	0x2
+	.long	.Lskeleton_debug_info0
+	.long	0x39
+	.long	0x31
+	.byte	0x90
+	.string	"int"
+	.long	0
+	.section	.debug_aranges,"",@progbits
+	.long	0x2c
+	.value	0x2
+	.long	.Lskeleton_debug_info0
+	.byte	0x8
+	.byte	0
+	.value	0
+	.value	0
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.quad	0
+	.quad	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_line.dwo,"e",@progbits
+.Lskeleton_debug_line0:
+	.long	.LELT0-.LSLT0
+.LSLT0:
+	.value	0x5
+	.byte	0x8
+	.byte	0
+	.long	.LELTP0-.LASLTP0
+.LASLTP0:
+	.byte	0x1
+	.byte	0x1
+	.byte	0x1
+	.byte	0xf6
+	.byte	0xf2
+	.byte	0xd
+	.byte	0
+	.byte	0x1
+	.byte	0x1
+	.byte	0x1
+	.byte	0x1
+	.byte	0
+	.byte	0
+	.byte	0
+	.byte	0x1
+	.byte	0
+	.byte	0
+	.byte	0x1
+	.byte	0x1
+	.uleb128 0x1
+	.uleb128 0x8
+	.uleb128 0x1
+	.string	"/tmp"
+	.byte	0x2
+	.uleb128 0x1
+	.uleb128 0x8
+	.uleb128 0x2
+	.uleb128 0xb
+	.uleb128 0x2
+	.string	"a.c"
+	.byte	0
+	.string	"a.c"
+	.byte	0
+.LELTP0:
+.LELT0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF1:
+	.string	"/tmp"
+.LASF0:
+	.string	"a.dwo"
+	.section	.debug_str_offsets.dwo,"e",@progbits
+	.long	0xc
+	.value	0x5
+	.value	0
+	.long	0
+	.long	0x5
+	.section	.debug_str.dwo,"e",@progbits
+	.string	"/tmp"
+	.string	"GNU C17 10.0.0 20190813 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -gsplit-dwarf"
+	.ident	"GCC: (GNU) 10.0.0 20190813 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index 0f7a1f3b5a0..b68224d5019 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -572,6 +572,18 @@ if {![binutils_assemble $srcdir/$subdir/dwo.s tmpdir/dwo.o]} then {
     readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k2
 }
 
+if {![binutils_assemble $srcdir/$subdir/dwo_5.s tmpdir/dwo_5.o]} then {
+    unsupported "readelf --debug-dump=links (failed to assemble dwo_5.s)"
+} else {
+    if ![is_remote host] {
+        set tempfile tmpdir/dwo_5.o
+    } else {
+        set tempfile [remote_download host tmpdir/dwo_5.o]
+    }
+
+    readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k5
+}
+
 if {![binutils_assemble $srcdir/$subdir/zero-sec.s tmpdir/zero-sec.o]} then {
     unsupported "readelf --enable-checks (failed to assemble zero-sec.s)"
 } else {
diff --git a/binutils/testsuite/binutils-all/readelf.k5 b/binutils/testsuite/binutils-all/readelf.k5
new file mode 100644
index 00000000000..49779224f2c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.k5
@@ -0,0 +1,7 @@
+The .debug_info section contains link\(s\) to dwo file\(s\):
+
+  Name:      a.dwo
+  Directory: /tmp
+
+
+
-- 
2.17.1


[-- Attachment #3: 0001-PATCH-2-2-Binutils-support-for-split-dwarf-and-dwarf.patch --]
[-- Type: application/octet-stream, Size: 5927 bytes --]

From dab73681a6e19c16c799d150cc79cace3f8f894c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Thu, 2 Jun 2022 19:19:13 +0530
Subject: [PATCH] [PATCH 2/2] Binutils support for split-dwarf and dwarf-5.

This fix adds support for split-dwarf and dwarf5. There are 2 patches.
Basic sections dump like .debug_info.dwo, .debug_abbrev.dwo, .debug_str.dwo
etc are supported in the previous patch 1/2. location list and ranges list
sections dump with split-dwarf and dwarf5 are supported in this patch 2/2
and its continuation of patch 1/2.

.debug_loclists.dwo and .debug_rnglists.dwo section dumps are taken care in
this patch 2/2.

	* dwarf.c(read_and_display_attr_value): Handle DW_FORM_loclistx
	and DW_FORM_rnglistx for .dwo files.
	(process_debug_info): Load .debug_loclists.dwo and
	.debug_rnglists.dwo if exists.
	(load_separate_debug_files): Load .debug_loclists and
	.debug_rnglists if exists.
	Include 2 entries in debug_displays table.
	* dwarf.h (enum dwarf_section_display_enum): Include 2 entries.
---
 binutils/dwarf.c | 39 +++++++++++++++++++++++++++++++++++++--
 binutils/dwarf.h |  2 ++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index e8f0ea4cf0c..7b4bb445da4 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -120,6 +120,7 @@ unsigned long dwarf_start_die;
 int dwarf_check = 0;
 static dwarf_vma str_offsets_base = 0;
 #define DEBUG_STR_OFFSETS_HEADER_LEN 8
+#define DEBUG_LOC_RNGLISTS_SEC_HDR_LEN 12
 
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -2792,7 +2793,34 @@ read_and_display_attr_value (unsigned long           attribute,
 
 	  offset = base + uvalue * pointer_size;
 
-	  if (do_wide)
+	  const char *suffix = strrchr (section->name, '.');
+	  bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
+
+	  if (form == DW_FORM_loclistx)
+	    {
+	      if (!dwo)
+	        printf (_("%c(index: 0x%s): %s"), delimiter,
+	                dwarf_vmatoa ("x", uvalue),
+	                dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
+	      else
+	        printf (_("%c(index: 0x%s): %s"), delimiter,
+	                dwarf_vmatoa ("x", uvalue),
+	                dwarf_vmatoa ("x", fetch_indexed_value (uvalue, loclists_dwo)
+	                                   + DEBUG_LOC_RNGLISTS_SEC_HDR_LEN));
+	    }
+	  else if (form == DW_FORM_rnglistx)
+	    {
+	      if (!dwo)
+	        printf (_("%c(index: 0x%s): %s"), delimiter,
+	                dwarf_vmatoa ("x", uvalue),
+	                dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
+	      else
+	        printf (_("%c(index: 0x%s): %s"), delimiter,
+	                dwarf_vmatoa ("x", uvalue),
+	                dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists_dwo)
+	                                   + DEBUG_LOC_RNGLISTS_SEC_HDR_LEN));
+	    }
+	  else if (do_wide)
 	    /* We have already displayed the form name.  */
 	    printf (_("%c(index: 0x%s): %s"), delimiter,
 		    dwarf_vmatoa ("x", uvalue),
@@ -3608,7 +3636,9 @@ process_debug_info (struct dwarf_section * section,
   load_debug_section_with_follow (abbrev_sec, file);
   load_debug_section_with_follow (loclists, file);
   load_debug_section_with_follow (rnglists, file);
-  
+  load_debug_section_with_follow (loclists_dwo, file);
+  load_debug_section_with_follow (rnglists_dwo, file);
+
   if (debug_displays [abbrev_sec].section.start == NULL)
     {
       warn (_("Unable to locate %s section!\n"),
@@ -11896,6 +11926,9 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (info, file))
     {
       load_debug_section (str_index, file);
+      load_debug_section (loclists, file);
+      load_debug_section (rnglists, file);
+
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
@@ -12265,10 +12298,12 @@ struct dwarf_section_display debug_displays[] =
   { { ".debug_line_str",    ".zdebug_line_str",	     "",	 NO_ABBREVS },	    display_debug_str,	    &do_debug_str,	false },
   { { ".debug_loc",	    ".zdebug_loc",	     ".dwloc",	 NO_ABBREVS },	    display_debug_loc,	    &do_debug_loc,	true },
   { { ".debug_loclists",    ".zdebug_loclists",	     "",	 NO_ABBREVS },	    display_debug_loc,	    &do_debug_loc,	true },
+  { { ".debug_loclists.dwo", ".zdebug_loclists.dwo", "",         NO_ABBREVS },      display_debug_loc,      &do_debug_loc,      true },
   { { ".debug_pubtypes",    ".zdebug_pubtypes",	     ".dwpbtyp", NO_ABBREVS },	    display_debug_pubnames, &do_debug_pubtypes, false },
   { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", "",	 NO_ABBREVS },	    display_debug_gnu_pubnames, &do_debug_pubtypes, false },
   { { ".debug_ranges",	    ".zdebug_ranges",	     ".dwrnges", NO_ABBREVS },	    display_debug_ranges,   &do_debug_ranges,	true },
   { { ".debug_rnglists",    ".zdebug_rnglists",	     "",	 NO_ABBREVS },	    display_debug_ranges,   &do_debug_ranges,	true },
+  { { ".debug_rnglists.dwo", ".zdebug_rnglists.dwo", "",         NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,   true },
   { { ".debug_static_func", ".zdebug_static_func",   "",	 NO_ABBREVS },	    display_debug_not_supported, NULL,		false },
   { { ".debug_static_vars", ".zdebug_static_vars",   "",	 NO_ABBREVS },	    display_debug_not_supported, NULL,		false },
   { { ".debug_types",	    ".zdebug_types",	     "",	 ABBREV (abbrev) }, display_debug_types,    &do_debug_info,	true },
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..86b635ef3c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -92,10 +92,12 @@ enum dwarf_section_display_enum
   line_str,
   loc,
   loclists,
+  loclists_dwo,
   pubtypes,
   gnu_pubtypes,
   ranges,
   rnglists,
+  rnglists_dwo,
   static_func,
   static_vars,
   types,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-06-10 17:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 14:55 [PATCH] Binutils support for split-dwarf and dwarf-5 Kumar N, Bhuvanendra
2022-06-03 12:04 ` Jan Beulich
2022-06-10 17:34   ` Kumar N, Bhuvanendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).