Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 0/3] Support DWARF 5 .debug_sup section
@ 2025-03-23 19:19 Tom Tromey
  2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-23 19:19 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This is a refresh of a patch I sent a long time ago and then forgot
about:

https://sourceware.org/pipermail/gdb-patches/2021-February/176508.html

It adds support for the DWARF 5 .debug_sup section and related forms.

See patch #3 for testing.  I regression tested this on x86-64 Fedora
40, comparing the new "dwz -5" results against a "dwz -m" baseline.

There are a handful of regressions, due to the decision about build-id
that's noted in patch #2.

Signed-off-by: Tom Tromey <tom@tromey.com>
---
Tom Tromey (3):
      Remove 'read' call from dwz_file::read_string
      Handle DWARF 5 separate debug sections
      Add "-5" flag to cc-with-tweaks

 gdb/contrib/cc-with-tweaks.sh                 |   5 +-
 gdb/dwarf2/attribute.c                        |   5 +-
 gdb/dwarf2/attribute.h                        |  14 +-
 gdb/dwarf2/cooked-indexer.c                   |   4 +-
 gdb/dwarf2/die.c                              |   3 +
 gdb/dwarf2/dwz.c                              | 193 +++++++++++++++++++++-----
 gdb/dwarf2/dwz.h                              |  25 ++--
 gdb/dwarf2/macro.c                            |   1 +
 gdb/dwarf2/read.c                             |  19 ++-
 gdb/dwarf2/read.h                             |   8 +-
 gdb/testsuite/boards/cc-with-dwz-5.exp        |  28 ++++
 gdb/testsuite/gdb.dwarf2/dwzbuildid.exp       | 159 +--------------------
 gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl       | 184 ++++++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp      |  17 +++
 gdb/testsuite/gdb.dwarf2/dwznolink.exp        |   2 +-
 gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp |   2 +-
 gdb/testsuite/lib/dwarf.exp                   |  18 +++
 17 files changed, 469 insertions(+), 218 deletions(-)
---
base-commit: df1ed5c0d4935c62b8951fd83a1e37e775ba90a5
change-id: 20250323-dwz-dwarf-5-v2-7d84ad21b045

Best regards,
-- 
Tom Tromey <tom@tromey.com>


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

* [PATCH 1/3] Remove 'read' call from dwz_file::read_string
  2025-03-23 19:19 [PATCH 0/3] Support DWARF 5 .debug_sup section Tom Tromey
@ 2025-03-23 19:20 ` Tom Tromey
  2025-03-24 14:25   ` Alexandra Petlanova Hajkova
  2025-03-24 20:30   ` Simon Marchi
  2025-03-23 19:20 ` [PATCH 2/3] Handle DWARF 5 separate debug sections Tom Tromey
  2025-03-23 19:20 ` [PATCH 3/3] Add "-5" flag to cc-with-tweaks Tom Tromey
  2 siblings, 2 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-23 19:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

dwz_file::read_string calls 'read' on the section, but this isn't
needed as the sections have all been pre-read.

This patch makes this change, and refactors dwz_file a bit to make
this more obvious -- by making it clear that only the "static
constructor" can create a dwz_file.
---
 gdb/dwarf2/dwz.c  |  8 +++++---
 gdb/dwarf2/dwz.h  | 25 +++++++++++++------------
 gdb/dwarf2/read.c |  2 +-
 3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c
index f36d6a6418a4220d7d531e3bf5b6e047b40edd6e..14cd8e882ba6bc16b57a82aa31296f4025261f15 100644
--- a/gdb/dwarf2/dwz.c
+++ b/gdb/dwarf2/dwz.c
@@ -34,7 +34,9 @@
 const char *
 dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
 {
-  str.read (objfile);
+  /* This must be true because the sections are read in when the
+     dwz_file is created.  */
+  gdb_assert (str.readin);
 
   if (str.buffer == NULL)
     error (_("DW_FORM_GNU_strp_alt used without .debug_str "
@@ -177,7 +179,7 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
 /* See dwz.h.  */
 
 void
-dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
+dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
 {
   bfd_size_type buildid_len_arg;
   size_t buildid_len;
@@ -261,7 +263,7 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
     error (_("could not find '.gnu_debugaltlink' file for %s"),
 	   per_bfd->filename ());
 
-  auto result = std::make_unique<dwz_file> (std::move (dwz_bfd));
+  dwz_file_up result (new dwz_file (std::move (dwz_bfd)));
 
   for (asection *sec : gdb_bfd_sections (result->dwz_bfd))
     locate_dwz_sections (per_objfile->objfile, result->dwz_bfd.get (),
diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h
index cd5143ff0848564e1c831f4eb7ddccd7231d28e6..639eea3a41850249a44259e454daa770b246ef2b 100644
--- a/gdb/dwarf2/dwz.h
+++ b/gdb/dwarf2/dwz.h
@@ -31,10 +31,12 @@ struct dwarf2_per_objfile;
 
 struct dwz_file
 {
-  dwz_file (gdb_bfd_ref_ptr &&bfd)
-    : dwz_bfd (std::move (bfd))
-  {
-  }
+  /* Open the separate '.dwz' debug file, if needed.  This will set
+     the appropriate field in the per-BFD structure.  If the DWZ file
+     exists, the relevant sections are read in as well.  Throws an
+     error if the .gnu_debugaltlink section exists but the file cannot
+     be found.  */
+  static void read_dwz_file (dwarf2_per_objfile *per_objfile);
 
   const char *filename () const
   {
@@ -64,16 +66,15 @@ struct dwz_file
      return a pointer to the string.  */
 
   const char *read_string (struct objfile *objfile, LONGEST str_offset);
-};
 
-using dwz_file_up = std::unique_ptr<dwz_file>;
+private:
 
-/* Open the separate '.dwz' debug file, if needed.  This just sets the
-   appropriate field in the per-BFD structure.  If the DWZ file
-   exists, the relevant sections are read in as well.  Throws an error
-   if the .gnu_debugaltlink section exists but the file cannot be
-   found.  */
+  explicit dwz_file (gdb_bfd_ref_ptr &&bfd)
+    : dwz_bfd (std::move (bfd))
+  {
+  }
+};
 
-extern void dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile);
+using dwz_file_up = std::unique_ptr<dwz_file>;
 
 #endif /* GDB_DWARF2_DWZ_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8875e97a7b3303c5c8bf7ca90ed21f22f4d23b34..f4198d71ca28811bd02c5fb87b5206629f118874 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1289,7 +1289,7 @@ dwarf2_has_info (struct objfile *objfile,
 	 BFD, to avoid races.  */
       try
 	{
-	  dwarf2_read_dwz_file (per_objfile);
+	  dwz_file::read_dwz_file (per_objfile);
 	}
       catch (const gdb_exception_error &err)
 	{

-- 
2.46.1


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

* [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-23 19:19 [PATCH 0/3] Support DWARF 5 .debug_sup section Tom Tromey
  2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
@ 2025-03-23 19:20 ` Tom Tromey
  2025-03-24 15:45   ` Alexandra Petlanova Hajkova
  2025-03-24 20:52   ` Simon Marchi
  2025-03-23 19:20 ` [PATCH 3/3] Add "-5" flag to cc-with-tweaks Tom Tromey
  2 siblings, 2 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-23 19:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

DWARF 5 standardized the .gnu_debugaltlink section that dwz emits in
multi-file mode.  This is handled via some new forms, and a new
.debug_sup section.

This patch adds support for this to gdb.  It is largely
straightforward, I think, though one oddity is that I chose not to
have this code search the system build-id directories for the
supplementary file.  My feeling was that, while it makes sense for a
distro to unify the build-id concept with the hash stored in the
.debug_sup section, there's no intrinsic need to do so.

This in turn means that a few tests -- for example those that test the
index cache -- will not work in this mode.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32808
---
 gdb/dwarf2/attribute.c                        |   5 +-
 gdb/dwarf2/attribute.h                        |  14 +-
 gdb/dwarf2/cooked-indexer.c                   |   4 +-
 gdb/dwarf2/die.c                              |   3 +
 gdb/dwarf2/dwz.c                              | 185 ++++++++++++++++++++++----
 gdb/dwarf2/dwz.h                              |   4 +-
 gdb/dwarf2/macro.c                            |   1 +
 gdb/dwarf2/read.c                             |  17 ++-
 gdb/dwarf2/read.h                             |   8 +-
 gdb/testsuite/gdb.dwarf2/dwzbuildid.exp       | 159 +---------------------
 gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl       | 184 +++++++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp      |  17 +++
 gdb/testsuite/gdb.dwarf2/dwznolink.exp        |   2 +-
 gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp |   2 +-
 gdb/testsuite/lib/dwarf.exp                   |  18 +++
 15 files changed, 420 insertions(+), 203 deletions(-)

diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 49c0bc07d75dd23f5b4f952f4ccb7c46cebc5265..3aa4790d4f7214233d1d9fe52db80f658ac6fcd8 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -73,7 +73,8 @@ attribute::form_is_string () const
 	  || form == DW_FORM_strx3
 	  || form == DW_FORM_strx4
 	  || form == DW_FORM_GNU_str_index
-	  || form == DW_FORM_GNU_strp_alt);
+	  || form == DW_FORM_GNU_strp_alt
+	  || form == DW_FORM_strp_sup);
 }
 
 /* See attribute.h.  */
@@ -190,6 +191,8 @@ attribute::form_is_unsigned () const
 {
   return (form == DW_FORM_ref_addr
 	  || form == DW_FORM_GNU_ref_alt
+	  || form == DW_FORM_ref_sup4
+	  || form == DW_FORM_ref_sup8
 	  || form == DW_FORM_data2
 	  || form == DW_FORM_data4
 	  || form == DW_FORM_data8
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index ce6c5639c1ae25644844447399988648842d8f58..b89136678f5fe824c21082e39242fec6d945f169 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -144,7 +144,9 @@ struct attribute
 	    || form == DW_FORM_ref4
 	    || form == DW_FORM_ref8
 	    || form == DW_FORM_ref_udata
-	    || form == DW_FORM_GNU_ref_alt);
+	    || form == DW_FORM_GNU_ref_alt
+	    || form == DW_FORM_ref_sup4
+	    || form == DW_FORM_ref_sup8);
   }
 
   /* Check if the attribute's form is a DW_FORM_block*
@@ -168,6 +170,16 @@ struct attribute
      "reprocessing".  */
   bool form_requires_reprocessing () const;
 
+  /* Check if attribute's form refers to the separate "dwz" file.
+     This is only useful for references to the .debug_info section,
+     not to the supplementary .debug_str section.  */
+  bool form_is_alt () const
+  {
+    return (form == DW_FORM_GNU_ref_alt
+	    || form == DW_FORM_ref_sup4
+	    || form == DW_FORM_ref_sup8);
+  }
+
   /* Return DIE offset of this attribute.  Return 0 with complaint if
      the attribute is not of the required kind.  */
 
diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c
index 3b80cd6c50089c82963881845713b93655b25ec4..327db33593d6f3e284ac708f9c55a6aa11ed129d 100644
--- a/gdb/dwarf2/cooked-indexer.c
+++ b/gdb/dwarf2/cooked-indexer.c
@@ -222,7 +222,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
 	case DW_AT_abstract_origin:
 	case DW_AT_extension:
 	  origin_offset = attr.get_ref_die_offset ();
-	  origin_is_dwz = attr.form == DW_FORM_GNU_ref_alt;
+	  origin_is_dwz = attr.form_is_alt ();
 	  break;
 
 	case DW_AT_external:
@@ -423,7 +423,7 @@ cooked_indexer::index_imported_unit (cutu_reader *reader,
       if (attr.name == DW_AT_import)
 	{
 	  sect_off = attr.get_ref_die_offset ();
-	  is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+	  is_dwz = (attr.form_is_alt ()
 		    || reader->cu ()->per_cu->is_dwz);
 	}
     }
diff --git a/gdb/dwarf2/die.c b/gdb/dwarf2/die.c
index 9437c2f985871769156c132d96826e9527e4c14b..4cdf535f8ac438a6df1aaa8d03c7010dde3b9a09 100644
--- a/gdb/dwarf2/die.c
+++ b/gdb/dwarf2/die.c
@@ -90,6 +90,8 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 	  gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
 	  break;
 	case DW_FORM_GNU_ref_alt:
+	case DW_FORM_ref_sup4:
+	case DW_FORM_ref_sup8:
 	  gdb_printf (f, "alt ref address: ");
 	  gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
 	  break;
@@ -123,6 +125,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 	case DW_FORM_strx:
 	case DW_FORM_GNU_str_index:
 	case DW_FORM_GNU_strp_alt:
+	case DW_FORM_strp_sup:
 	  gdb_printf (f, "string: \"%s\" (%s canonicalized)",
 		      die->attrs[i].as_string ()
 		      ? die->attrs[i].as_string () : "",
diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c
index 14cd8e882ba6bc16b57a82aa31296f4025261f15..76274b630e484624a6d1a97b7a5f32feb83019e1 100644
--- a/gdb/dwarf2/dwz.c
+++ b/gdb/dwarf2/dwz.c
@@ -21,6 +21,7 @@
 
 #include "build-id.h"
 #include "debuginfod-support.h"
+#include "dwarf2/leb.h"
 #include "dwarf2/read.h"
 #include "dwarf2/sect-names.h"
 #include "filenames.h"
@@ -39,12 +40,12 @@ dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
   gdb_assert (str.readin);
 
   if (str.buffer == NULL)
-    error (_("DW_FORM_GNU_strp_alt used without .debug_str "
+    error (_("supplementary DWARF file missing .debug_str "
 	     "section [in module %s]"),
 	   this->filename ());
   if (str_offset >= str.size)
-    error (_("DW_FORM_GNU_strp_alt pointing outside of "
-	     ".debug_str section [in module %s]"),
+    error (_("invalid string reference to supplementary DWARF file "
+	     "[in module %s]"),
 	   this->filename ());
   gdb_assert (HOST_CHAR_BIT == 8);
   if (str.buffer[str_offset] == '\0')
@@ -87,6 +88,139 @@ locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
     }
 }
 
+/* Helper that throws an exception when reading the .debug_sup
+   section.  */
+
+static void
+debug_sup_failure (const char *text, bfd *abfd)
+{
+  error (_("%s [in modules %s]"), text, bfd_get_filename (abfd));
+}
+
+/* Look for the .debug_sup section and read it.  If the section does
+   not exist, this returns false.  If the section does exist but fails
+   to parse for some reason, an exception is thrown.  Otherwise, if
+   everything goes well, this returns true and fills in the out
+   parameters.  */
+
+static bool
+get_debug_sup_info (bfd *abfd,
+		    std::string *filename,
+		    size_t *buildid_len,
+		    gdb::unique_xmalloc_ptr<bfd_byte> *buildid)
+{
+  asection *sect = bfd_get_section_by_name (abfd, ".debug_sup");
+  if (sect == nullptr)
+    return false;
+
+  bfd_byte *contents;
+  if (!bfd_malloc_and_get_section (abfd, sect, &contents))
+    debug_sup_failure (_("could not read .debug_sup section"), abfd);
+
+  gdb::unique_xmalloc_ptr<bfd_byte> content_holder (contents);
+  bfd_size_type size = bfd_section_size (sect);
+
+  /* Version of this section.  */
+  if (size < 4)
+    debug_sup_failure (_(".debug_sup section too short"), abfd);
+  unsigned int version = read_2_bytes (abfd, contents);
+  contents += 2;
+  size -= 2;
+  if (version != 5)
+    debug_sup_failure (_(".debug_sup has wrong version number"), abfd);
+
+  /* Skip the is_supplementary value.  We already ensured there were
+     enough bytes, above.  */
+  ++contents;
+  --size;
+
+  /* The spec says that in the supplementary file, this must be \0,
+     but it doesn't seem very important.  */
+  const char *fname = (const char *) contents;
+  size_t len = strlen (fname) + 1;
+  if (filename != nullptr)
+    *filename = fname;
+  contents += len;
+  size -= len;
+
+  if (size == 0)
+    debug_sup_failure (_(".debug_sup section missing ID"), abfd);
+
+  unsigned int bytes_read;
+  *buildid_len = read_unsigned_leb128 (abfd, contents, &bytes_read);
+  contents += bytes_read;
+  size -= bytes_read;
+
+  if (size < *buildid_len)
+    debug_sup_failure (_("extra data after .debug_sup section ID"), abfd);
+
+  if (*buildid_len != 0)
+    buildid->reset ((bfd_byte *) xmemdup (contents, *buildid_len,
+					  *buildid_len));
+
+  return true;
+}
+
+/* Validate that ABFD matches the given BUILDID.  If DWARF5 is true,
+   then this is done by examining the .debug_sup data.  */
+
+static bool
+verify_id (bfd *abfd, size_t len, const bfd_byte *buildid, bool dwarf5)
+{
+  if (!bfd_check_format (abfd, bfd_object))
+    return false;
+
+  if (dwarf5)
+    {
+      size_t new_len;
+      gdb::unique_xmalloc_ptr<bfd_byte> new_id;
+
+      if (!get_debug_sup_info (abfd, nullptr, &new_len, &new_id))
+	return false;
+      return (len == new_len
+	      && memcmp (buildid, new_id.get (), len) == 0);
+    }
+  else
+    return build_id_verify (abfd, len, buildid);
+}
+
+/* Find either the .debug_sup or .gnu_debugaltlink section and return
+   its contents.  Returns true on success and sets out parameters, or
+   false if nothing is found.  */
+
+static bool
+read_alt_info (bfd *abfd, std::string *filename,
+	       size_t *buildid_len,
+	       gdb::unique_xmalloc_ptr<bfd_byte> *buildid,
+	       bool *dwarf5)
+{
+  if (get_debug_sup_info (abfd, filename, buildid_len, buildid))
+    {
+      *dwarf5 = true;
+      return true;
+    }
+
+  bfd_size_type buildid_len_arg;
+  bfd_set_error (bfd_error_no_error);
+  bfd_byte *buildid_out;
+  gdb::unique_xmalloc_ptr<char> new_filename
+    (bfd_get_alt_debug_link_info (abfd, &buildid_len_arg,
+				  &buildid_out));
+  if (new_filename == nullptr)
+    {
+      if (bfd_get_error () == bfd_error_no_error)
+	return false;
+      error (_("could not read '.gnu_debugaltlink' section: %s"),
+	     bfd_errmsg (bfd_get_error ()));
+    }
+  *filename = new_filename.get ();
+
+  *buildid_len = buildid_len_arg;
+  buildid->reset (buildid_out);
+  *dwarf5 = false;
+  return true;
+}
+
 /* Attempt to find a .dwz file (whose full path is represented by
    FILENAME) in all of the specified debug file directories provided.
 
@@ -95,7 +229,7 @@ locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
 
 static gdb_bfd_ref_ptr
 dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
-			    size_t buildid_len)
+			    size_t buildid_len, bool dwarf5)
 {
   /* Let's assume that the path represented by FILENAME has the
      "/.dwz/" subpath in it.  This is what (most) GNU/Linux
@@ -163,7 +297,7 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
       if (dwz_bfd == nullptr)
 	continue;
 
-      if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+      if (!verify_id (dwz_bfd.get (), buildid_len, buildid, dwarf5))
 	{
 	  dwz_bfd.reset (nullptr);
 	  continue;
@@ -181,9 +315,6 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
 void
 dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
 {
-  bfd_size_type buildid_len_arg;
-  size_t buildid_len;
-  bfd_byte *buildid;
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
   /* This may query the user via the debuginfod support, so it may
@@ -195,24 +326,17 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
   /* Set this early, so that on error it remains NULL.  */
   per_bfd->dwz_file.emplace (nullptr);
 
-  bfd_set_error (bfd_error_no_error);
-  gdb::unique_xmalloc_ptr<char> data
-    (bfd_get_alt_debug_link_info (per_bfd->obfd,
-				  &buildid_len_arg, &buildid));
-  if (data == NULL)
+  size_t buildid_len;
+  gdb::unique_xmalloc_ptr<bfd_byte> buildid;
+  std::string filename;
+  bool dwarf5;
+  if (!read_alt_info (per_bfd->obfd, &filename, &buildid_len, &buildid,
+		      &dwarf5))
     {
-      if (bfd_get_error () == bfd_error_no_error)
-	return;
-      error (_("could not read '.gnu_debugaltlink' section: %s"),
-	     bfd_errmsg (bfd_get_error ()));
+      /* Nothing found, nothing to do.  */
+      return;
     }
 
-  gdb::unique_xmalloc_ptr<bfd_byte> buildid_holder (buildid);
-
-  buildid_len = (size_t) buildid_len_arg;
-
-  std::string filename = data.get ();
-
   if (!IS_ABSOLUTE_PATH (filename.c_str ()))
     {
       gdb::unique_xmalloc_ptr<char> abs = gdb_realpath (per_bfd->filename ());
@@ -225,25 +349,26 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
   gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename.c_str (), gnutarget));
   if (dwz_bfd != NULL)
     {
-      if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+      if (!verify_id (dwz_bfd.get (), buildid_len, buildid.get (), dwarf5))
 	dwz_bfd.reset (nullptr);
     }
 
   if (dwz_bfd == NULL)
-    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
+    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid.get ());
 
   if (dwz_bfd == nullptr)
     {
       /* If the user has provided us with different
 	 debug file directories, we can try them in order.  */
-      dwz_bfd = dwz_search_other_debugdirs (filename, buildid, buildid_len);
+      dwz_bfd = dwz_search_other_debugdirs (filename, buildid.get (),
+					    buildid_len, dwarf5);
     }
 
   if (dwz_bfd == nullptr)
     {
       gdb::unique_xmalloc_ptr<char> alt_filename;
       scoped_fd fd
-	= debuginfod_debuginfo_query (buildid, buildid_len,
+	= debuginfod_debuginfo_query (buildid.get (), buildid_len,
 				      per_bfd->filename (), &alt_filename);
 
       if (fd.get () >= 0)
@@ -254,13 +379,15 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
 	  if (dwz_bfd == nullptr)
 	    warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
 		     alt_filename.get ());
-	  else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+	  else if (!verify_id (dwz_bfd.get (), buildid_len, buildid.get (),
+			       dwarf5))
 	    dwz_bfd.reset (nullptr);
 	}
     }
 
   if (dwz_bfd == NULL)
-    error (_("could not find '.gnu_debugaltlink' file for %s"),
+    error (_("could not find supplementary DWARF file (%s) for %s"),
+	   filename.c_str (),
 	   per_bfd->filename ());
 
   dwz_file_up result (new dwz_file (std::move (dwz_bfd)));
diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h
index 639eea3a41850249a44259e454daa770b246ef2b..381d8dad427aab4a04d2db6608b15862aad8130b 100644
--- a/gdb/dwarf2/dwz.h
+++ b/gdb/dwarf2/dwz.h
@@ -34,8 +34,8 @@ struct dwz_file
   /* Open the separate '.dwz' debug file, if needed.  This will set
      the appropriate field in the per-BFD structure.  If the DWZ file
      exists, the relevant sections are read in as well.  Throws an
-     error if the .gnu_debugaltlink section exists but the file cannot
-     be found.  */
+     exception if the .gnu_debugaltlink or .debug_sup section exists
+     but is invalid or if the file cannot be found.  */
   static void read_dwz_file (dwarf2_per_objfile *per_objfile);
 
   const char *filename () const
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 2d9d4b7bbcf0e79da203fb23ecc21925f7c5ead3..7924fd2ed5160de72954360e86b560025ab12a86 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -259,6 +259,7 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
     case DW_FORM_sec_offset:
     case DW_FORM_strp:
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_strp_sup:
       bytes += offset_size;
       break;
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f4198d71ca28811bd02c5fb87b5206629f118874..e8a8c9d030282033bbcaf9d234188d06dfc32c2c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -3920,11 +3920,13 @@ cutu_reader::skip_one_attribute (dwarf_form form, const gdb_byte *info_ptr)
     case DW_FORM_data4:
     case DW_FORM_ref4:
     case DW_FORM_strx4:
+    case DW_FORM_ref_sup4:
       return info_ptr + 4;
 
     case DW_FORM_data8:
     case DW_FORM_ref8:
     case DW_FORM_ref_sig8:
+    case DW_FORM_ref_sup8:
       return info_ptr + 8;
 
     case DW_FORM_data16:
@@ -3937,6 +3939,7 @@ cutu_reader::skip_one_attribute (dwarf_form form, const gdb_byte *info_ptr)
     case DW_FORM_sec_offset:
     case DW_FORM_strp:
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_strp_sup:
       return info_ptr + m_cu->header.offset_size;
 
     case DW_FORM_exprloc:
@@ -5047,7 +5050,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
   if (attr != NULL)
     {
       sect_offset sect_off = attr->get_ref_die_offset ();
-      bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+      bool is_dwz = attr->form_is_alt () || cu->per_cu->is_dwz;
       dwarf2_per_objfile *per_objfile = cu->per_objfile;
       dwarf2_per_cu *per_cu
 	= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
@@ -14951,10 +14954,12 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form,
       info_ptr += 2;
       break;
     case DW_FORM_data4:
+    case DW_FORM_ref_sup4:
       attr->set_unsigned (read_4_bytes (m_abfd, info_ptr));
       info_ptr += 4;
       break;
     case DW_FORM_data8:
+    case DW_FORM_ref_sup8:
       attr->set_unsigned (read_8_bytes (m_abfd, info_ptr));
       info_ptr += 8;
       break;
@@ -15006,6 +15011,7 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form,
 	}
       [[fallthrough]];
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_strp_sup:
       {
 	dwz_file *dwz = per_objfile->per_bfd->get_dwz_file (true);
 	LONGEST str_offset
@@ -17288,6 +17294,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
     case DW_FORM_strx:
     case DW_FORM_GNU_str_index:
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_strp_sup:
       /* The string is already allocated on the objfile obstack, point
 	 directly to it.  */
       *bytes = (const gdb_byte *) attr->as_string ();
@@ -17494,7 +17501,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
 
   /* First see if we have it cached.  */
 
-  if (attr->form == DW_FORM_GNU_ref_alt)
+  if (attr->form_is_alt ())
     {
       sect_offset sect_off = attr->get_ref_die_offset ();
       dwarf2_per_cu *per_cu
@@ -18278,15 +18285,14 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
   struct dwarf2_cu *cu = *ref_cu;
   struct die_info *die;
 
-  if (attr->form != DW_FORM_GNU_ref_alt && src_die->sect_off == sect_off)
+  if (!attr->form_is_alt () && src_die->sect_off == sect_off)
     {
       /* Self-reference, we're done.  */
       return src_die;
     }
 
   die = follow_die_offset (sect_off,
-			   (attr->form == DW_FORM_GNU_ref_alt
-			    || cu->per_cu->is_dwz),
+			   attr->form_is_alt () || cu->per_cu->is_dwz,
 			   ref_cu);
   if (!die)
     error (_(DWARF_ERROR_PREFIX
@@ -18497,6 +18503,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
     case DW_FORM_strx:
     case DW_FORM_GNU_str_index:
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_strp_sup:
       /* The string is already allocated on the objfile obstack, point
 	 directly to it.  */
       {
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index ba2dd07a2ee278228fc8ffadd56bbfe290844e74..895ebee633e8c06fce9180b81743ae249072024d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -533,9 +533,9 @@ struct dwarf2_per_bfd
   }
 
   /* Return the separate '.dwz' debug file.  If there is no
-     .gnu_debugaltlink section in the file, then the result depends on
-     REQUIRE: if REQUIRE is true, error out; if REQUIRE is false,
-     return nullptr.  */
+     .gnu_debugaltlink or .debug_sup section in the file, then the
+     result depends on REQUIRE: if REQUIRE is true, error out; if
+     REQUIRE is false, return nullptr.  */
   struct dwz_file *get_dwz_file (bool require = false)
   {
     gdb_assert (!require || this->dwz_file.has_value ());
@@ -546,7 +546,7 @@ struct dwarf2_per_bfd
       {
 	result = this->dwz_file->get ();
 	if (require && result == nullptr)
-	  error (_("could not read '.gnu_debugaltlink' section"));
+	  error (_("could not find supplementary DWARF file"));
       }
 
     return result;
diff --git a/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp b/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp
index e54508a56e7e616a56d53c2ef17dcc3198fd1cba..6cb5a709855a41b418a0861b045bda23c36ec645 100644
--- a/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp
+++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp
@@ -13,160 +13,5 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-load_lib dwarf.exp
-
-# This test can only be run on targets which support DWARF-2 and use gas.
-require dwarf2_support
-
-# No remote host testing either.
-require {!is_remote host}
-
-
-# Lots of source files since we test a few cases and make new files
-# for each.
-# The tests are:
-#     ok - the main file refers to a dwz and the buildids match
-#     mismatch - the buildids do not match
-#     fallback - the buildids do not match but a match is found via buildid
-standard_testfile main.c \
-    dwzbuildid-ok-base.S dwzbuildid-ok-sep.S \
-    dwzbuildid-mismatch-base.S dwzbuildid-mismatch-sep.S \
-    dwzbuildid-fallback-base.S dwzbuildid-fallback-sep.S \
-    dwzbuildid-fallback-ok.S
-    
-# Write some assembly that just has a .gnu_debugaltlink section.
-proc write_just_debugaltlink {filename dwzname buildid} {
-    set asm_file [standard_output_file $filename]
-
-    Dwarf::assemble $asm_file {
-	upvar dwzname dwzname
-	upvar buildid buildid
-
-	gnu_debugaltlink $dwzname $buildid
-
-	# Only the DWARF reader checks .gnu_debugaltlink, so make sure
-	# there is a bit of DWARF in here.
-	cu { label cu_start } {
-	    compile_unit {{language @DW_LANG_C}} {
-	    }
-	}
-	aranges {} cu_start {
-	    arange {} 0 0
-	}
-    }
-}
-
-# Write some DWARF that also sets the buildid.
-proc write_dwarf_file {filename buildid {value 99}} {
-    set asm_file [standard_output_file $filename]
-
-    Dwarf::assemble $asm_file {
-	declare_labels int_label int_label2
-
-	upvar buildid buildid
-	upvar value value
-
-	build_id $buildid
-
-	cu { label cu_start } {
-	    compile_unit {{language @DW_LANG_C}} {
-		int_label2: base_type {
-		    {name int}
-		    {byte_size 4 sdata}
-		    {encoding @DW_ATE_signed}
-		}
-
-		constant {
-		    {name the_int}
-		    {type :$int_label2}
-		    {const_value $value data1}
-		}
-	    }
-	}
-
-	aranges {} cu_start {
-	    arange {} 0 0
-	}
-    }
-}
-
-if  { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
-	   object {nodebug}] != "" } {
-    return -1
-}
-
-# The values don't really matter, just whether they are equal.
-set ok_prefix 01
-set ok_suffix 02030405060708091011121314151617181920
-set ok_suffix2 020304050607080910111213141516171819ff
-set ok_buildid ${ok_prefix}${ok_suffix}
-set ok_buildid2 ${ok_prefix}${ok_suffix2}
-set bad_buildid [string repeat ff 20]
-
-set debugdir [standard_output_file {}]
-set basedir $debugdir/.build-id
-file mkdir $basedir $basedir/$ok_prefix
-
-# Test where the separate debuginfo's buildid matches.
-write_just_debugaltlink $srcfile2 ${binfile}3.o $ok_buildid
-write_dwarf_file $srcfile3 $ok_buildid
-
-# Test where the separate debuginfo's buildid does not match.
-write_just_debugaltlink $srcfile4 ${binfile}5.o $ok_buildid
-write_dwarf_file $srcfile5 $bad_buildid
-
-# Test where the separate debuginfo's buildid does not match, but then
-# we find a match in the .build-id directory.
-write_just_debugaltlink $srcfile6 ${binfile}7.o $ok_buildid2
-# Use 77 as the value so that if we load the bad debuginfo, we will
-# see the wrong result.
-write_dwarf_file $srcfile7 $bad_buildid 77
-write_dwarf_file $srcfile8 $ok_buildid2
-
-# Compile everything.
-for {set i 2} {$i <= 8} {incr i} {
-    if {[gdb_compile [standard_output_file [set srcfile$i]] \
-	     ${binfile}$i.o object nodebug] != ""} {
-	return -1
-    }
-}
-
-# Copy a file into the .build-id place for the "fallback" test.
-file copy -force -- ${binfile}8.o $basedir/$ok_prefix/$ok_suffix2.debug
-
-proc do_test {} {
-    clean_restart
-
-    gdb_test_no_output "set debug-file-directory $::debugdir" \
-	"set debug-file-directory"
-
-    gdb_load ${::binfile}-${::testname}
-
-    if {![runto_main]} {
-	return
-    }
-
-    if {$::testname == "mismatch"} {
-	gdb_test "print the_int" \
-	    "(No symbol table is loaded|No symbol \"the_int\" in current context).*"
-    } else {
-	gdb_test "print the_int" " = 99"
-    }
-}
-
-foreach_with_prefix testname { ok mismatch fallback } {
-    if { $testname == "ok" } {
-	set objs [list ${binfile}1.o ${binfile}2.o]
-    } elseif { $testname == "mismatch" } {
-	set objs [list ${binfile}1.o ${binfile}4.o]
-    } elseif { $testname == "fallback" } {
-	set objs [list ${binfile}1.o ${binfile}6.o]
-    }
-
-    if {[gdb_compile $objs ${binfile}-$testname executable {quiet}] != ""} {
-	unsupported "compilation failed"
-	continue
-    }
-
-    do_test
-}
+set scenario gnu
+source $srcdir/$subdir/dwzbuildid.tcl
diff --git a/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl b/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..b4c26a3d60022d21e806dc9400f507ffe9dbe386
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl
@@ -0,0 +1,184 @@
+# Copyright 2013-2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+# No remote host testing either.
+require {!is_remote host}
+
+
+# Lots of source files since we test a few cases and make new files
+# for each.
+# The tests are:
+#     ok - the main file refers to a dwz and the buildids match
+#     mismatch - the buildids do not match
+#     fallback - the buildids do not match but a match is found via buildid
+standard_testfile main.c \
+    dwzbuildid-ok-base.S dwzbuildid-ok-sep.S \
+    dwzbuildid-mismatch-base.S dwzbuildid-mismatch-sep.S \
+    dwzbuildid-fallback-base.S dwzbuildid-fallback-sep.S \
+    dwzbuildid-fallback-ok.S
+    
+# Write some assembly that just has a .gnu_debugaltlink section.
+proc write_just_debugaltlink {filename dwzname buildid} {
+    set asm_file [standard_output_file $filename]
+
+    Dwarf::assemble $asm_file {
+	upvar dwzname dwzname
+	upvar buildid buildid
+
+	if {$::scenario == "gnu"} {
+	    gnu_debugaltlink $dwzname $buildid
+	} else {
+	    debug_sup 0 $dwzname $buildid
+	}
+
+	# Only the DWARF reader checks .gnu_debugaltlink, so make sure
+	# there is a bit of DWARF in here.
+	cu { label cu_start } {
+	    compile_unit {{language @DW_LANG_C}} {
+	    }
+	}
+	aranges {} cu_start {
+	    arange {} 0 0
+	}
+    }
+}
+
+# Write some DWARF that also sets the buildid.
+proc write_dwarf_file {filename buildid {value 99}} {
+    set asm_file [standard_output_file $filename]
+
+    Dwarf::assemble $asm_file {
+	declare_labels int_label int_label2
+
+	upvar buildid buildid
+	upvar value value
+
+	if {$::scenario == "gnu"} {
+	    build_id $buildid
+	} else {
+	    debug_sup 1 "" $buildid
+	}
+
+	cu { label cu_start } {
+	    compile_unit {{language @DW_LANG_C}} {
+		int_label2: base_type {
+		    {name int}
+		    {byte_size 4 sdata}
+		    {encoding @DW_ATE_signed}
+		}
+
+		constant {
+		    {name the_int}
+		    {type :$int_label2}
+		    {const_value $value data1}
+		}
+	    }
+	}
+
+	aranges {} cu_start {
+	    arange {} 0 0
+	}
+    }
+}
+
+if  { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
+	   object {nodebug}] != "" } {
+    return -1
+}
+
+# The values don't really matter, just whether they are equal.
+set ok_prefix 01
+set ok_suffix 02030405060708091011121314151617181920
+set ok_suffix2 020304050607080910111213141516171819ff
+set ok_buildid ${ok_prefix}${ok_suffix}
+set ok_buildid2 ${ok_prefix}${ok_suffix2}
+set bad_buildid [string repeat ff 20]
+
+set debugdir [standard_output_file {}]
+set basedir $debugdir/.build-id
+file mkdir $basedir $basedir/$ok_prefix
+
+# Test where the separate debuginfo's buildid matches.
+write_just_debugaltlink $srcfile2 ${binfile}3.o $ok_buildid
+write_dwarf_file $srcfile3 $ok_buildid
+
+# Test where the separate debuginfo's buildid does not match.
+write_just_debugaltlink $srcfile4 ${binfile}5.o $ok_buildid
+write_dwarf_file $srcfile5 $bad_buildid
+
+# Test where the separate debuginfo's buildid does not match, but then
+# we find a match in the .build-id directory.
+write_just_debugaltlink $srcfile6 ${binfile}7.o $ok_buildid2
+# Use 77 as the value so that if we load the bad debuginfo, we will
+# see the wrong result.
+write_dwarf_file $srcfile7 $bad_buildid 77
+write_dwarf_file $srcfile8 $ok_buildid2
+
+# Compile everything.
+for {set i 2} {$i <= 8} {incr i} {
+    if {[gdb_compile [standard_output_file [set srcfile$i]] \
+	     ${binfile}$i.o object nodebug] != ""} {
+	return -1
+    }
+}
+
+# Copy a file into the .build-id place for the "fallback" test.
+file copy -force -- ${binfile}8.o $basedir/$ok_prefix/$ok_suffix2.debug
+
+proc do_test {} {
+    clean_restart
+
+    gdb_test_no_output "set debug-file-directory $::debugdir" \
+	"set debug-file-directory"
+
+    gdb_load ${::binfile}-${::testname}
+
+    if {![runto_main]} {
+	return
+    }
+
+    if {$::testname == "mismatch"} {
+	gdb_test "print the_int" \
+	    "(No symbol table is loaded|No symbol \"the_int\" in current context).*"
+    } else {
+	gdb_test "print the_int" " = 99"
+    }
+}
+
+set tests {ok mismatch}
+if {$scenario == "gnu"} {
+    lappend tests fallback
+}
+foreach_with_prefix testname $tests {
+    if { $testname == "ok" } {
+	set objs [list ${binfile}1.o ${binfile}2.o]
+    } elseif { $testname == "mismatch" } {
+	set objs [list ${binfile}1.o ${binfile}4.o]
+    } elseif { $testname == "fallback" } {
+	set objs [list ${binfile}1.o ${binfile}6.o]
+    }
+
+    if {[gdb_compile $objs ${binfile}-$testname executable {quiet}] != ""} {
+	unsupported "compilation failed"
+	continue
+    }
+
+    do_test
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp b/gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp
new file mode 100644
index 0000000000000000000000000000000000000000..047626c003dc4824a8b3664b68a0aaff4b434da8
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp
@@ -0,0 +1,17 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set scenario dwarf5
+source $srcdir/$subdir/dwzbuildid.tcl
diff --git a/gdb/testsuite/gdb.dwarf2/dwznolink.exp b/gdb/testsuite/gdb.dwarf2/dwznolink.exp
index cbabe8f828d4f2e46004eb41a1e6d091cabd06ae..88fa7c03fe6cb53b7d658f76175a678342454983 100644
--- a/gdb/testsuite/gdb.dwarf2/dwznolink.exp
+++ b/gdb/testsuite/gdb.dwarf2/dwznolink.exp
@@ -49,5 +49,5 @@ if {[build_executable $testfile.exp $testfile \
 
 clean_restart
 gdb_test "file -readnow $binfile" \
-    "could not read '.gnu_debugaltlink' section" \
+    "could not find supplementary DWARF file" \
     "file $testfile"
diff --git a/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp b/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp
index 54cd199a9473998dfab08a14f27f6e82529a9ea4..1dd98174df81f650e9a276b617c575041d32560a 100644
--- a/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp
+++ b/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp
@@ -38,7 +38,7 @@ if { [build_executable $testfile.exp $testfile [list $srcfile $asm_file]] } {
 clean_restart
 gdb_test_no_output "maint set dwarf synchronous on"
 
-set msg "\r\nwarning: could not find '\.gnu_debugaltlink' file for \[^\r\n\]*"
+set msg "\r\nwarning: could not find supplementary DWARF file \[^\r\n\]*"
 gdb_test "file $binfile" "$msg" "file command"
 
 set question "Load new symbol table from .*\? .y or n. "
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 7dcf13f2ce7bdbdd78c4972ac0e6c7a55958afdd..0b1f01c50b92fae176b97e063ffed7f57f03dc91 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -3006,6 +3006,24 @@ namespace eval Dwarf {
 	}
     }
 
+    # Emit a .debug_sup section with the given file name and build-id.
+    # The buildid should be represented as a hexadecimal string, like
+    # "ffeeddcc".
+    proc debug_sup {is_sup filename buildid} {
+	_defer_output .debug_sup {
+	    # The version.
+	    _op .2byte 0x5
+	    # Supplementary marker.
+	    _op .byte $is_sup
+	    _op .ascii [_quote $filename]
+	    set len [expr {[string length $buildid] / 2}]
+	    _op .uleb128 $len
+	    foreach {a b} [split $buildid {}] {
+		_op .byte 0x$a$b
+	    }
+	}
+    }
+
     proc _note {type name hexdata} {
 	set namelen [expr [string length $name] + 1]
 	set datalen [expr [string length $hexdata] / 2]

-- 
2.46.1


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

* [PATCH 3/3] Add "-5" flag to cc-with-tweaks
  2025-03-23 19:19 [PATCH 0/3] Support DWARF 5 .debug_sup section Tom Tromey
  2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
  2025-03-23 19:20 ` [PATCH 2/3] Handle DWARF 5 separate debug sections Tom Tromey
@ 2025-03-23 19:20 ` Tom Tromey
  2 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-23 19:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This adds a "-5" flag to cc-with-tweaks, mirroring dwz's "-5" flag,
and also adds a new cc-with-dwz-5 target board.

The "-5" flag tells dwz to use the DWARF 5 .debug_sup section in
multi-file mode.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32808
---
 gdb/contrib/cc-with-tweaks.sh          |  5 ++++-
 gdb/testsuite/boards/cc-with-dwz-5.exp | 28 ++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/gdb/contrib/cc-with-tweaks.sh b/gdb/contrib/cc-with-tweaks.sh
index 4214b9292955a8b5f4602d329a93ee0ab606a70a..5677f29493828a9e9fb6041fd03cb85452e04199 100755
--- a/gdb/contrib/cc-with-tweaks.sh
+++ b/gdb/contrib/cc-with-tweaks.sh
@@ -42,6 +42,7 @@
 # -Z invoke objcopy --compress-debug-sections
 # -z compress using dwz
 # -m compress using dwz -m
+# -5 compress using dwz -m -5
 # -i make an index (.gdb_index)
 # -c make an index (currently .gdb_index) in a cache dir
 # -n make a dwarf5 index (.debug_names)
@@ -88,6 +89,7 @@ want_index=false
 index_options=""
 want_index_cache=false
 want_dwz=false
+dwz_5flag=
 want_multi=false
 want_dwp=false
 want_objcopy_compress=false
@@ -101,6 +103,7 @@ while [ $# -gt 0 ]; do
 	-n) want_index=true; index_options=-dwarf-5;;
 	-c) want_index_cache=true ;;
 	-m) want_multi=true ;;
+	-5) want_multi=true; dwz_5flag=-5 ;;
 	-p) want_dwp=true ;;
 	-l) want_gnu_debuglink=true ;;
 	*) break ;;
@@ -269,7 +272,7 @@ elif [ "$want_multi" = true ]; then
     rm -f "$dwz_file"
 
     cp "$output_file" "${output_file}.alt"
-    $DWZ -m "$dwz_file" "$output_file" "${output_file}.alt" > /dev/null
+    $DWZ $dwz_5flag -m "$dwz_file" "$output_file" "${output_file}.alt" > /dev/null
     rm -f "${output_file}.alt"
 
     # Validate dwz's work by checking if the expected output file exists.
diff --git a/gdb/testsuite/boards/cc-with-dwz-5.exp b/gdb/testsuite/boards/cc-with-dwz-5.exp
new file mode 100644
index 0000000000000000000000000000000000000000..b254f91e79557a5600a894f0bb0727fd2bcf02f1
--- /dev/null
+++ b/gdb/testsuite/boards/cc-with-dwz-5.exp
@@ -0,0 +1,28 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is a dejagnu "board file" and is used to run the testsuite
+# with contrib/cc-with-tweaks.sh -5.
+#
+# NOTE: We assume dwz is in $PATH.
+#
+# Example usage:
+# bash$ cd $objdir
+# bash$ make check-gdb \
+#   RUNTESTFLAGS='--target_board=cc-with-dwz-5'
+#
+
+set CC_WITH_TWEAKS_FLAGS "-5"
+load_board_description "cc-with-tweaks"

-- 
2.46.1


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

* Re: [PATCH 1/3] Remove 'read' call from dwz_file::read_string
  2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
@ 2025-03-24 14:25   ` Alexandra Petlanova Hajkova
  2025-03-24 20:30   ` Simon Marchi
  1 sibling, 0 replies; 15+ messages in thread
From: Alexandra Petlanova Hajkova @ 2025-03-24 14:25 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

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

On Sun, Mar 23, 2025 at 8:21 PM Tom Tromey <tom@tromey.com> wrote:

> dwz_file::read_string calls 'read' on the section, but this isn't
> needed as the sections have all been pre-read.
>
> This patch makes this change, and refactors dwz_file a bit to make
> this more obvious -- by making it clear that only the "static
> constructor" can create a dwz_file.
> ---
>
>
Hi Tom,

I tested this on aarch64, Fedora 40 and this change causes no regressions.

Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>

[-- Attachment #2: Type: text/html, Size: 1020 bytes --]

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-23 19:20 ` [PATCH 2/3] Handle DWARF 5 separate debug sections Tom Tromey
@ 2025-03-24 15:45   ` Alexandra Petlanova Hajkova
  2025-03-24 17:16     ` Tom Tromey
  2025-03-24 20:52   ` Simon Marchi
  1 sibling, 1 reply; 15+ messages in thread
From: Alexandra Petlanova Hajkova @ 2025-03-24 15:45 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

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

On Sun, Mar 23, 2025 at 8:23 PM Tom Tromey <tom@tromey.com> wrote:

> DWARF 5 standardized the .gnu_debugaltlink section that dwz emits in
> multi-file mode.  This is handled via some new forms, and a new
> .debug_sup section.
>
> This patch adds support for this to gdb.  It is largely
> straightforward, I think, though one oddity is that I chose not to
> have this code search the system build-id directories for the
> supplementary file.  My feeling was that, while it makes sense for a
> distro to unify the build-id concept with the hash stored in the
> .debug_sup section, there's no intrinsic need to do so.
>
> This in turn means that a few tests -- for example those that test the
> index cache -- will not work in this mode.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32808
>
>
Hi Tom,

I tested this on aarch64, Fedora 40 and  this change causes
gdb.base/bp-cmds-continue-ctrl-c.exp
to fail. I can provide you with the logs if you are interested.

[-- Attachment #2: Type: text/html, Size: 1527 bytes --]

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-24 15:45   ` Alexandra Petlanova Hajkova
@ 2025-03-24 17:16     ` Tom Tromey
  2025-04-03 14:39       ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2025-03-24 17:16 UTC (permalink / raw)
  To: Alexandra Petlanova Hajkova; +Cc: Tom Tromey, gdb-patches

>>>>> "Alexandra" == Alexandra Petlanova Hajkova <ahajkova@redhat.com> writes:

Alexandra> I tested this on aarch64, Fedora 40 and this change causes
Alexandra> gdb.base/bp-cmds-continue-ctrl-c.exp to fail. I can provide
Alexandra> you with the logs if you are interested.

Sure, that may be helpful.
I have no idea why this patch would affect that, unless maybe you were
testing the new mode?

Tom

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

* Re: [PATCH 1/3] Remove 'read' call from dwz_file::read_string
  2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
  2025-03-24 14:25   ` Alexandra Petlanova Hajkova
@ 2025-03-24 20:30   ` Simon Marchi
  2025-03-24 20:52     ` Tom Tromey
  1 sibling, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2025-03-24 20:30 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches



On 2025-03-23 15:20, Tom Tromey wrote:
> dwz_file::read_string calls 'read' on the section, but this isn't
> needed as the sections have all been pre-read.

In the long term, to remove unnecessary 'read' calls in a safe way, I
was thinking of introducing some kind of 'dwarf2_read_section_info' type
that would be a thin wrapper around a `dwarf2_section_info`, but one
that you could only obtain by calling `dwarf2_section_info::read`.  That
would be a kind of "token" to make sure that the section is safe to read
from.  A bit like when a function accepts an std::lock_guard object, it
is guaranteed that the lock is taken.

> @@ -261,7 +263,7 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
>      error (_("could not find '.gnu_debugaltlink' file for %s"),
>  	   per_bfd->filename ());
>  
> -  auto result = std::make_unique<dwz_file> (std::move (dwz_bfd));
> +  dwz_file_up result (new dwz_file (std::move (dwz_bfd)));

Why this change?

Otherwise, LGTM.

Approved-By: Simon Marchi <simon.marchi@efficios.com>

Simon

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

* Re: [PATCH 1/3] Remove 'read' call from dwz_file::read_string
  2025-03-24 20:30   ` Simon Marchi
@ 2025-03-24 20:52     ` Tom Tromey
  0 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-24 20:52 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>> -  auto result = std::make_unique<dwz_file> (std::move (dwz_bfd));
>> +  dwz_file_up result (new dwz_file (std::move (dwz_bfd)));

Simon> Why this change?

make_unique can't access a private constructor.
It's a bit of a wart on C++ IMO.

Tom

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-23 19:20 ` [PATCH 2/3] Handle DWARF 5 separate debug sections Tom Tromey
  2025-03-24 15:45   ` Alexandra Petlanova Hajkova
@ 2025-03-24 20:52   ` Simon Marchi
  2025-03-25 13:37     ` Tom Tromey
  1 sibling, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2025-03-24 20:52 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches



On 2025-03-23 15:20, Tom Tromey wrote:
> DWARF 5 standardized the .gnu_debugaltlink section that dwz emits in
> multi-file mode.  This is handled via some new forms, and a new
> .debug_sup section.
> 
> This patch adds support for this to gdb.  It is largely
> straightforward, I think, though one oddity is that I chose not to
> have this code search the system build-id directories for the
> supplementary file.  My feeling was that, while it makes sense for a
> distro to unify the build-id concept with the hash stored in the
> .debug_sup section, there's no intrinsic need to do so.
> 
> This in turn means that a few tests -- for example those that test the
> index cache -- will not work in this mode.
> 
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32808

I just had a few minutes to spare, so I just scanned the patch, I'm
happy with it.  More support for standard DWARF is nice.

Acked-By: Simon Marchi <simon.marchi@efficios.com>

Some random comments:

> @@ -87,6 +88,139 @@ locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
>      }
>  }
>  
> +/* Helper that throws an exception when reading the .debug_sup
> +   section.  */
> +
> +static void
> +debug_sup_failure (const char *text, bfd *abfd)
> +{
> +  error (_("%s [in modules %s]"), text, bfd_get_filename (abfd));

modules -> module?

> +  if (*buildid_len != 0)
> +    buildid->reset ((bfd_byte *) xmemdup (contents, *buildid_len,
> +					  *buildid_len));

Could we return a view inside the section, instead of copying the bytes?
It seems like we are just copying the bytes as is.

Simon

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-24 20:52   ` Simon Marchi
@ 2025-03-25 13:37     ` Tom Tromey
  0 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2025-03-25 13:37 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> +  if (*buildid_len != 0)
>> +    buildid->reset ((bfd_byte *) xmemdup (contents, *buildid_len,
>> +					  *buildid_len));

Simon> Could we return a view inside the section, instead of copying the bytes?
Simon> It seems like we are just copying the bytes as is.

In this code, the section isn't mapped but instead just read in and then
discarded.  That's done because it's only needed for a moment while
reading -- once the file is found the .debug_sup contents aren't needed.

Tom

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-03-24 17:16     ` Tom Tromey
@ 2025-04-03 14:39       ` Tom Tromey
  2025-04-22 14:55         ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2025-04-03 14:39 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Alexandra Petlanova Hajkova, gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

>>>>> "Alexandra" == Alexandra Petlanova Hajkova <ahajkova@redhat.com> writes:
Alexandra> I tested this on aarch64, Fedora 40 and this change causes
Alexandra> gdb.base/bp-cmds-continue-ctrl-c.exp to fail. I can provide
Alexandra> you with the logs if you are interested.

Tom> Sure, that may be helpful.
Tom> I have no idea why this patch would affect that, unless maybe you were
Tom> testing the new mode?

Hi, I wanted to land this series, but I need to investigate this first.
Could you send me this log?

thanks,
Tom

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-04-03 14:39       ` Tom Tromey
@ 2025-04-22 14:55         ` Tom Tromey
  2025-04-22 15:10           ` Simon Marchi
  0 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2025-04-22 14:55 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Alexandra Petlanova Hajkova, gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>>>>> "Alexandra" == Alexandra Petlanova Hajkova <ahajkova@redhat.com> writes:
Alexandra> I tested this on aarch64, Fedora 40 and this change causes
Alexandra> gdb.base/bp-cmds-continue-ctrl-c.exp to fail. I can provide
Alexandra> you with the logs if you are interested.

Tom> Sure, that may be helpful.
Tom> I have no idea why this patch would affect that, unless maybe you were
Tom> testing the new mode?

Tom> Hi, I wanted to land this series, but I need to investigate this first.
Tom> Could you send me this log?

Ping.

Tom

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-04-22 14:55         ` Tom Tromey
@ 2025-04-22 15:10           ` Simon Marchi
  2025-04-28 11:35             ` Tom de Vries
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2025-04-22 15:10 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Alexandra Petlanova Hajkova, gdb-patches

On 4/22/25 10:55 AM, Tom Tromey wrote:
>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
> 
>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>>>>>> "Alexandra" == Alexandra Petlanova Hajkova <ahajkova@redhat.com> writes:
> Alexandra> I tested this on aarch64, Fedora 40 and this change causes
> Alexandra> gdb.base/bp-cmds-continue-ctrl-c.exp to fail. I can provide
> Alexandra> you with the logs if you are interested.
> 
> Tom> Sure, that may be helpful.
> Tom> I have no idea why this patch would affect that, unless maybe you were
> Tom> testing the new mode?
> 
> Tom> Hi, I wanted to land this series, but I need to investigate this first.
> Tom> Could you send me this log?
> 
> Ping.
> 
> Tom

FWIW, I think it's pretty likely that it's a flaky test.  I think you
can go ahead and push your series.  If it turns out it's really a bug,
we can always fix it later.

Simon

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

* Re: [PATCH 2/3] Handle DWARF 5 separate debug sections
  2025-04-22 15:10           ` Simon Marchi
@ 2025-04-28 11:35             ` Tom de Vries
  0 siblings, 0 replies; 15+ messages in thread
From: Tom de Vries @ 2025-04-28 11:35 UTC (permalink / raw)
  To: Simon Marchi, Tom Tromey; +Cc: Alexandra Petlanova Hajkova, gdb-patches

On 4/22/25 17:10, Simon Marchi wrote:
> On 4/22/25 10:55 AM, Tom Tromey wrote:
>>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>>
>>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>>>>>>> "Alexandra" == Alexandra Petlanova Hajkova <ahajkova@redhat.com> writes:
>> Alexandra> I tested this on aarch64, Fedora 40 and this change causes
>> Alexandra> gdb.base/bp-cmds-continue-ctrl-c.exp to fail. I can provide
>> Alexandra> you with the logs if you are interested.
>>
>> Tom> Sure, that may be helpful.
>> Tom> I have no idea why this patch would affect that, unless maybe you were
>> Tom> testing the new mode?
>>
>> Tom> Hi, I wanted to land this series, but I need to investigate this first.
>> Tom> Could you send me this log?
>>
>> Ping.
>>
>> Tom
> 
> FWIW, I think it's pretty likely that it's a flaky test.  I think you
> can go ahead and push your series.  If it turns out it's really a bug,
> we can always fix it later.

My guess is that this is PR32167 ( 
https://sourceware.org/bugzilla/show_bug.cgi?id=32167 ).

Thanks,
- Tom

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

end of thread, other threads:[~2025-04-28 11:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-23 19:19 [PATCH 0/3] Support DWARF 5 .debug_sup section Tom Tromey
2025-03-23 19:20 ` [PATCH 1/3] Remove 'read' call from dwz_file::read_string Tom Tromey
2025-03-24 14:25   ` Alexandra Petlanova Hajkova
2025-03-24 20:30   ` Simon Marchi
2025-03-24 20:52     ` Tom Tromey
2025-03-23 19:20 ` [PATCH 2/3] Handle DWARF 5 separate debug sections Tom Tromey
2025-03-24 15:45   ` Alexandra Petlanova Hajkova
2025-03-24 17:16     ` Tom Tromey
2025-04-03 14:39       ` Tom Tromey
2025-04-22 14:55         ` Tom Tromey
2025-04-22 15:10           ` Simon Marchi
2025-04-28 11:35             ` Tom de Vries
2025-03-24 20:52   ` Simon Marchi
2025-03-25 13:37     ` Tom Tromey
2025-03-23 19:20 ` [PATCH 3/3] Add "-5" flag to cc-with-tweaks Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox