public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Some minor dwz-handling improvements & cleanups
@ 2021-02-21  3:16 Tom Tromey
  2021-02-21  3:16 ` [PATCH 1/5] Create new file dwarf2/sect-names.h Tom Tromey
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches

I was looking at adding support for DWARF 5's equivalent to
.gnu_debugaltlink, and found that I could provoke a gdb crash.  In
particular, if gdb tries to process a form requiring a "dwz" file, but
no .gnu_debugaltlink section exists, then that will cause a failure.
See patch #3 for some more info on this.

While fixing this, I found a number of small cleanups that made the
result a bit prettier.  There are more like this that are possible,
for example basically none of the DWARF code should be in symfile.h.

Let me know what you think.

Tom



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

* [PATCH 1/5] Create new file dwarf2/sect-names.h
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
@ 2021-02-21  3:16 ` Tom Tromey
  2021-02-21  3:16 ` [PATCH 2/5] Change section_is_p to a method on dwarf2_section_names Tom Tromey
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This creates a new file, dwarf2/sect-names.h, and moves some
DWARF-specific type definitions from symfile.h into it.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* xcoffread.c: Include sect-names.h.
	* symfile.h (struct dwarf2_section_names, struct
	dwarf2_debug_sections): Move to dwarf2/sect-names.h.
	* dwarf2/sect-names.h: New file, from symfile.h.
	* dwarf2/read.c: Include sect-names.h.
---
 gdb/ChangeLog           |  8 +++++
 gdb/dwarf2/read.c       |  1 +
 gdb/dwarf2/sect-names.h | 68 +++++++++++++++++++++++++++++++++++++++++
 gdb/symfile.h           | 46 +---------------------------
 gdb/xcoffread.c         |  1 +
 5 files changed, 79 insertions(+), 45 deletions(-)
 create mode 100644 gdb/dwarf2/sect-names.h

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 51bf0fbeea5..d747286f2e3 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -40,6 +40,7 @@
 #include "dwarf2/dwz.h"
 #include "dwarf2/macro.h"
 #include "dwarf2/die.h"
+#include "dwarf2/sect-names.h"
 #include "dwarf2/stringify.h"
 #include "bfd.h"
 #include "elf-bfd.h"
diff --git a/gdb/dwarf2/sect-names.h b/gdb/dwarf2/sect-names.h
new file mode 100644
index 00000000000..63cf2cafef7
--- /dev/null
+++ b/gdb/dwarf2/sect-names.h
@@ -0,0 +1,68 @@
+/* DWARF 2 section names.
+
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef GDB_DWARF2_SECT_NAMES_H
+#define GDB_DWARF2_SECT_NAMES_H
+
+/* Names for a dwarf2 debugging section.  The field NORMAL is the normal
+   section name (usually from the DWARF standard), while the field COMPRESSED
+   is the name of compressed sections.  If your object file format doesn't
+   support compressed sections, the field COMPRESSED can be NULL.  Likewise,
+   the debugging section is not supported, the field NORMAL can be NULL too.
+   It doesn't make sense to have a NULL NORMAL field but a non-NULL COMPRESSED
+   field.  */
+
+struct dwarf2_section_names {
+  const char *normal;
+  const char *compressed;
+};
+
+/* List of names for dward2 debugging sections.  Also most object file formats
+   use the standardized (ie ELF) names, some (eg XCOFF) have customized names
+   due to restrictions.
+   The table for the standard names is defined in dwarf2read.c.  Please
+   update all instances of dwarf2_debug_sections if you add a field to this
+   structure.  It is always safe to use { NULL, NULL } in this case.  */
+
+struct dwarf2_debug_sections {
+  struct dwarf2_section_names info;
+  struct dwarf2_section_names abbrev;
+  struct dwarf2_section_names line;
+  struct dwarf2_section_names loc;
+  struct dwarf2_section_names loclists;
+  struct dwarf2_section_names macinfo;
+  struct dwarf2_section_names macro;
+  struct dwarf2_section_names str;
+  struct dwarf2_section_names str_offsets;
+  struct dwarf2_section_names line_str;
+  struct dwarf2_section_names ranges;
+  struct dwarf2_section_names rnglists;
+  struct dwarf2_section_names types;
+  struct dwarf2_section_names addr;
+  struct dwarf2_section_names frame;
+  struct dwarf2_section_names eh_frame;
+  struct dwarf2_section_names gdb_index;
+  struct dwarf2_section_names debug_names;
+  struct dwarf2_section_names debug_aranges;
+  /* This field has no meaning, but exists solely to catch changes to
+     this structure which are not reflected in some instance.  */
+  int sentinel;
+};
+
+#endif /* GDB_DWARF2_SECT_NAMES_H */
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 23e2ad8c3a9..7f5545dc5ba 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -554,51 +554,7 @@ extern void generic_load (const char *args, int from_tty);
 
 /* From dwarf2read.c */
 
-/* Names for a dwarf2 debugging section.  The field NORMAL is the normal
-   section name (usually from the DWARF standard), while the field COMPRESSED
-   is the name of compressed sections.  If your object file format doesn't
-   support compressed sections, the field COMPRESSED can be NULL.  Likewise,
-   the debugging section is not supported, the field NORMAL can be NULL too.
-   It doesn't make sense to have a NULL NORMAL field but a non-NULL COMPRESSED
-   field.  */
-
-struct dwarf2_section_names {
-  const char *normal;
-  const char *compressed;
-};
-
-/* List of names for dward2 debugging sections.  Also most object file formats
-   use the standardized (ie ELF) names, some (eg XCOFF) have customized names
-   due to restrictions.
-   The table for the standard names is defined in dwarf2read.c.  Please
-   update all instances of dwarf2_debug_sections if you add a field to this
-   structure.  It is always safe to use { NULL, NULL } in this case.  */
-
-struct dwarf2_debug_sections {
-  struct dwarf2_section_names info;
-  struct dwarf2_section_names abbrev;
-  struct dwarf2_section_names line;
-  struct dwarf2_section_names loc;
-  struct dwarf2_section_names loclists;
-  struct dwarf2_section_names macinfo;
-  struct dwarf2_section_names macro;
-  struct dwarf2_section_names str;
-  struct dwarf2_section_names str_offsets;
-  struct dwarf2_section_names line_str;
-  struct dwarf2_section_names ranges;
-  struct dwarf2_section_names rnglists;
-  struct dwarf2_section_names types;
-  struct dwarf2_section_names addr;
-  struct dwarf2_section_names frame;
-  struct dwarf2_section_names eh_frame;
-  struct dwarf2_section_names gdb_index;
-  struct dwarf2_section_names debug_names;
-  struct dwarf2_section_names debug_aranges;
-  /* This field has no meaning, but exists solely to catch changes to
-     this structure which are not reflected in some instance.  */
-  int sentinel;
-};
-
+struct dwarf2_debug_sections;
 extern int dwarf2_has_info (struct objfile *,
 			    const struct dwarf2_debug_sections *,
 			    bool = false);
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index cd93943a812..b1768702e26 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -47,6 +47,7 @@
 #include "expression.h"
 #include "complaints.h"
 #include "psympriv.h"
+#include "dwarf2/sect-names.h"
 
 #include "gdb-stabs.h"
 
-- 
2.26.2


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

* [PATCH 2/5] Change section_is_p to a method on dwarf2_section_names
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
  2021-02-21  3:16 ` [PATCH 1/5] Create new file dwarf2/sect-names.h Tom Tromey
@ 2021-02-21  3:16 ` Tom Tromey
  2021-02-21  3:16 ` [PATCH 3/5] Avoid crash on missing dwz file Tom Tromey
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This replaces section_is_p with a method on dwarf2_section_names.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* dwarf2/sect-names.h (struct dwarf2_section_names) <matches>: New
	method.
	* dwarf2/read.c (section_is_p): Remove.
	(dwarf2_per_bfd::locate_sections)
	(dwarf2_per_bfd::locate_sections, locate_dwz_sections)
	(locate_v1_virtual_dwo_sections, dwarf2_locate_dwo_sections)
	(dwarf2_locate_common_dwp_sections)
	(dwarf2_locate_v2_dwp_sections, dwarf2_locate_v5_dwp_sections):
	Update.
---
 gdb/ChangeLog           |  12 ++++
 gdb/dwarf2/read.c       | 142 ++++++++++++++++++----------------------
 gdb/dwarf2/sect-names.h |   7 ++
 3 files changed, 82 insertions(+), 79 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index d747286f2e3..0347f91947e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1977,22 +1977,6 @@ dwarf2_has_info (struct objfile *objfile,
 	  && per_objfile->per_bfd->abbrev.s.section != NULL);
 }
 
-/* When loading sections, we look either for uncompressed section or for
-   compressed section names.  */
-
-static int
-section_is_p (const char *section_name,
-	      const struct dwarf2_section_names *names)
-{
-  if (names->normal != NULL
-      && strcmp (section_name, names->normal) == 0)
-    return 1;
-  if (names->compressed != NULL
-      && strcmp (section_name, names->compressed) == 0)
-    return 1;
-  return 0;
-}
-
 /* See declaration.  */
 
 void
@@ -2013,82 +1997,82 @@ dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
 	       bfd_section_name (sectp), phex_nz (size, sizeof (size)),
 	       bfd_get_filename (abfd));
     }
-  else if (section_is_p (sectp->name, &names.info))
+  else if (names.info.matches (sectp->name))
     {
       this->info.s.section = sectp;
       this->info.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.abbrev))
+  else if (names.abbrev.matches (sectp->name))
     {
       this->abbrev.s.section = sectp;
       this->abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.line))
+  else if (names.line.matches (sectp->name))
     {
       this->line.s.section = sectp;
       this->line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.loc))
+  else if (names.loc.matches (sectp->name))
     {
       this->loc.s.section = sectp;
       this->loc.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.loclists))
+  else if (names.loclists.matches (sectp->name))
     {
       this->loclists.s.section = sectp;
       this->loclists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.macinfo))
+  else if (names.macinfo.matches (sectp->name))
     {
       this->macinfo.s.section = sectp;
       this->macinfo.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.macro))
+  else if (names.macro.matches (sectp->name))
     {
       this->macro.s.section = sectp;
       this->macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.str))
+  else if (names.str.matches (sectp->name))
     {
       this->str.s.section = sectp;
       this->str.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.str_offsets))
+  else if (names.str_offsets.matches (sectp->name))
     {
       this->str_offsets.s.section = sectp;
       this->str_offsets.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.line_str))
+  else if (names.line_str.matches (sectp->name))
     {
       this->line_str.s.section = sectp;
       this->line_str.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.addr))
+  else if (names.addr.matches (sectp->name))
     {
       this->addr.s.section = sectp;
       this->addr.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.frame))
+  else if (names.frame.matches (sectp->name))
     {
       this->frame.s.section = sectp;
       this->frame.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.eh_frame))
+  else if (names.eh_frame.matches (sectp->name))
     {
       this->eh_frame.s.section = sectp;
       this->eh_frame.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.ranges))
+  else if (names.ranges.matches (sectp->name))
     {
       this->ranges.s.section = sectp;
       this->ranges.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.rnglists))
+  else if (names.rnglists.matches (sectp->name))
     {
       this->rnglists.s.section = sectp;
       this->rnglists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.types))
+  else if (names.types.matches (sectp->name))
     {
       struct dwarf2_section_info type_section;
 
@@ -2098,17 +2082,17 @@ dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
 
       this->types.push_back (type_section);
     }
-  else if (section_is_p (sectp->name, &names.gdb_index))
+  else if (names.gdb_index.matches (sectp->name))
     {
       this->gdb_index.s.section = sectp;
       this->gdb_index.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.debug_names))
+  else if (names.debug_names.matches (sectp->name))
     {
       this->debug_names.s.section = sectp;
       this->debug_names.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names.debug_aranges))
+  else if (names.debug_aranges.matches (sectp->name))
     {
       this->debug_aranges.s.section = sectp;
       this->debug_aranges.size = bfd_section_size (sectp);
@@ -2166,37 +2150,37 @@ locate_dwz_sections (bfd *abfd, asection *sectp, dwz_file *dwz_file)
 {
   /* Note that we only support the standard ELF names, because .dwz
      is ELF-only (at the time of writing).  */
-  if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev))
+  if (dwarf2_elf_names.abbrev.matches (sectp->name))
     {
       dwz_file->abbrev.s.section = sectp;
       dwz_file->abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.info))
+  else if (dwarf2_elf_names.info.matches (sectp->name))
     {
       dwz_file->info.s.section = sectp;
       dwz_file->info.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.str))
+  else if (dwarf2_elf_names.str.matches (sectp->name))
     {
       dwz_file->str.s.section = sectp;
       dwz_file->str.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.line))
+  else if (dwarf2_elf_names.line.matches (sectp->name))
     {
       dwz_file->line.s.section = sectp;
       dwz_file->line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.macro))
+  else if (dwarf2_elf_names.macro.matches (sectp->name))
     {
       dwz_file->macro.s.section = sectp;
       dwz_file->macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index))
+  else if (dwarf2_elf_names.gdb_index.matches (sectp->name))
     {
       dwz_file->gdb_index.s.section = sectp;
       dwz_file->gdb_index.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &dwarf2_elf_names.debug_names))
+  else if (dwarf2_elf_names.debug_names.matches (sectp->name))
     {
       dwz_file->debug_names.s.section = sectp;
       dwz_file->debug_names.size = bfd_section_size (sectp);
@@ -12069,7 +12053,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
 {
   const struct dwop_section_names *names = &dwop_section_names;
 
-  if (section_is_p (sectp->name, &names->abbrev_dwo))
+  if (names->abbrev_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->abbrev.s.section != NULL)
@@ -12077,8 +12061,8 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->abbrev.s.section = sectp;
       sections->abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->info_dwo)
-	   || section_is_p (sectp->name, &names->types_dwo))
+  else if (names->info_dwo.matches (sectp->name)
+	   || names->types_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->info_or_types.s.section != NULL)
@@ -12086,7 +12070,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->info_or_types.s.section = sectp;
       sections->info_or_types.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->line_dwo))
+  else if (names->line_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->line.s.section != NULL)
@@ -12094,7 +12078,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->line.s.section = sectp;
       sections->line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->loc_dwo))
+  else if (names->loc_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->loc.s.section != NULL)
@@ -12102,7 +12086,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->loc.s.section = sectp;
       sections->loc.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macinfo_dwo))
+  else if (names->macinfo_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->macinfo.s.section != NULL)
@@ -12110,7 +12094,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->macinfo.s.section = sectp;
       sections->macinfo.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macro_dwo))
+  else if (names->macro_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->macro.s.section != NULL)
@@ -12118,7 +12102,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
       sections->macro.s.section = sectp;
       sections->macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+  else if (names->str_offsets_dwo.matches (sectp->name))
     {
       /* There can be only one.  */
       if (sections->str_offsets.s.section != NULL)
@@ -12853,57 +12837,57 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp,
 {
   const struct dwop_section_names *names = &dwop_section_names;
 
-  if (section_is_p (sectp->name, &names->abbrev_dwo))
+  if (names->abbrev_dwo.matches (sectp->name))
     {
       dwo_sections->abbrev.s.section = sectp;
       dwo_sections->abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->info_dwo))
+  else if (names->info_dwo.matches (sectp->name))
     {
       dwo_sections->info.s.section = sectp;
       dwo_sections->info.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->line_dwo))
+  else if (names->line_dwo.matches (sectp->name))
     {
       dwo_sections->line.s.section = sectp;
       dwo_sections->line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->loc_dwo))
+  else if (names->loc_dwo.matches (sectp->name))
     {
       dwo_sections->loc.s.section = sectp;
       dwo_sections->loc.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->loclists_dwo))
+  else if (names->loclists_dwo.matches (sectp->name))
     {
       dwo_sections->loclists.s.section = sectp;
       dwo_sections->loclists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macinfo_dwo))
+  else if (names->macinfo_dwo.matches (sectp->name))
     {
       dwo_sections->macinfo.s.section = sectp;
       dwo_sections->macinfo.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macro_dwo))
+  else if (names->macro_dwo.matches (sectp->name))
     {
       dwo_sections->macro.s.section = sectp;
       dwo_sections->macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->rnglists_dwo))
+  else if (names->rnglists_dwo.matches (sectp->name))
     {
       dwo_sections->rnglists.s.section = sectp;
       dwo_sections->rnglists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->str_dwo))
+  else if (names->str_dwo.matches (sectp->name))
     {
       dwo_sections->str.s.section = sectp;
       dwo_sections->str.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+  else if (names->str_offsets_dwo.matches (sectp->name))
     {
       dwo_sections->str_offsets.s.section = sectp;
       dwo_sections->str_offsets.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->types_dwo))
+  else if (names->types_dwo.matches (sectp->name))
     {
       struct dwarf2_section_info type_section;
 
@@ -12978,17 +12962,17 @@ dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
-  if (section_is_p (sectp->name, &names->str_dwo))
+  if (names->str_dwo.matches (sectp->name))
     {
       dwp_file->sections.str.s.section = sectp;
       dwp_file->sections.str.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->cu_index))
+  else if (names->cu_index.matches (sectp->name))
     {
       dwp_file->sections.cu_index.s.section = sectp;
       dwp_file->sections.cu_index.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->tu_index))
+  else if (names->tu_index.matches (sectp->name))
     {
       dwp_file->sections.tu_index.s.section = sectp;
       dwp_file->sections.tu_index.size = bfd_section_size (sectp);
@@ -13013,42 +12997,42 @@ dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
-  if (section_is_p (sectp->name, &names->abbrev_dwo))
+  if (names->abbrev_dwo.matches (sectp->name))
     {
       dwp_file->sections.abbrev.s.section = sectp;
       dwp_file->sections.abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->info_dwo))
+  else if (names->info_dwo.matches (sectp->name))
     {
       dwp_file->sections.info.s.section = sectp;
       dwp_file->sections.info.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->line_dwo))
+  else if (names->line_dwo.matches (sectp->name))
     {
       dwp_file->sections.line.s.section = sectp;
       dwp_file->sections.line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->loc_dwo))
+  else if (names->loc_dwo.matches (sectp->name))
     {
       dwp_file->sections.loc.s.section = sectp;
       dwp_file->sections.loc.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macinfo_dwo))
+  else if (names->macinfo_dwo.matches (sectp->name))
     {
       dwp_file->sections.macinfo.s.section = sectp;
       dwp_file->sections.macinfo.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macro_dwo))
+  else if (names->macro_dwo.matches (sectp->name))
     {
       dwp_file->sections.macro.s.section = sectp;
       dwp_file->sections.macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+  else if (names->str_offsets_dwo.matches (sectp->name))
     {
       dwp_file->sections.str_offsets.s.section = sectp;
       dwp_file->sections.str_offsets.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->types_dwo))
+  else if (names->types_dwo.matches (sectp->name))
     {
       dwp_file->sections.types.s.section = sectp;
       dwp_file->sections.types.size = bfd_section_size (sectp);
@@ -13073,37 +13057,37 @@ dwarf2_locate_v5_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
-  if (section_is_p (sectp->name, &names->abbrev_dwo))
+  if (names->abbrev_dwo.matches (sectp->name))
     {
       dwp_file->sections.abbrev.s.section = sectp;
       dwp_file->sections.abbrev.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->info_dwo))
+  else if (names->info_dwo.matches (sectp->name))
     {
       dwp_file->sections.info.s.section = sectp;
       dwp_file->sections.info.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->line_dwo))
+  else if (names->line_dwo.matches (sectp->name))
    {
      dwp_file->sections.line.s.section = sectp;
      dwp_file->sections.line.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->loclists_dwo))
+  else if (names->loclists_dwo.matches (sectp->name))
     {
       dwp_file->sections.loclists.s.section = sectp;
       dwp_file->sections.loclists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->macro_dwo))
+  else if (names->macro_dwo.matches (sectp->name))
     {
       dwp_file->sections.macro.s.section = sectp;
       dwp_file->sections.macro.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->rnglists_dwo))
+  else if (names->rnglists_dwo.matches (sectp->name))
     {
       dwp_file->sections.rnglists.s.section = sectp;
       dwp_file->sections.rnglists.size = bfd_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+  else if (names->str_offsets_dwo.matches (sectp->name))
     {
       dwp_file->sections.str_offsets.s.section = sectp;
       dwp_file->sections.str_offsets.size = bfd_section_size (sectp);
diff --git a/gdb/dwarf2/sect-names.h b/gdb/dwarf2/sect-names.h
index 63cf2cafef7..b75328358c2 100644
--- a/gdb/dwarf2/sect-names.h
+++ b/gdb/dwarf2/sect-names.h
@@ -31,6 +31,13 @@
 struct dwarf2_section_names {
   const char *normal;
   const char *compressed;
+
+  /* Return true if NAME matches either of this section's names.  */
+  bool matches (const char *name) const
+  {
+    return ((normal != nullptr && strcmp (name, normal) == 0)
+	    || (compressed != nullptr && strcmp (name, compressed) == 0));
+  }
 };
 
 /* List of names for dward2 debugging sections.  Also most object file formats
-- 
2.26.2


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

* [PATCH 3/5] Avoid crash on missing dwz file
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
  2021-02-21  3:16 ` [PATCH 1/5] Create new file dwarf2/sect-names.h Tom Tromey
  2021-02-21  3:16 ` [PATCH 2/5] Change section_is_p to a method on dwarf2_section_names Tom Tromey
@ 2021-02-21  3:16 ` Tom Tromey
  2021-02-21 16:23   ` Tom Tromey
  2021-02-21  3:16 ` [PATCH 4/5] Include scoped_fd.h in debuginfod-support.h Tom Tromey
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

If DWARF contains a reference to a "dwz" file, but there is no
.gnu_debugaltlink section, then gdb will crash.  This happens because
dwarf2_get_dwz_file will return NULL, but some callers do not expect
this.

This patch changes dwarf2_get_dwz_file so that callers can require a
dwz file.  Then, it updates the callers that are attempting to process
references to the dwz file to require one.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.h (dwarf2_get_dwz_file): Add 'require' parameter.
	* dwarf2/read.c (dwarf2_get_dwz_file): Add 'require' parameter.
	(get_abbrev_section_for_cu, read_attribute_value)
	(get_debug_line_section): Update.
	* dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
---
 gdb/ChangeLog      |  8 ++++++++
 gdb/dwarf2/macro.c |  6 ++++--
 gdb/dwarf2/read.c  | 14 +++++++++-----
 gdb/dwarf2/read.h  | 13 ++++++++-----
 4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index afe2f91168b..2ecebe6173c 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -509,7 +509,8 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 		    || macinfo_type == DW_MACRO_undef_sup
 		    || section_is_dwz)
 		  {
-		    dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+		    dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd,
+							 true);
 
 		    body = dwz->read_string (objfile, str_offset);
 		  }
@@ -693,7 +694,8 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 
 	    if (macinfo_type == DW_MACRO_import_sup)
 	      {
-		dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+		dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd,
+						     true);
 
 		dwz->macro.read (objfile);
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0347f91947e..6a755f716d1 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2279,7 +2279,7 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
 /* See dwarf2read.h.  */
 
 struct dwz_file *
-dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
+dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
 {
   bfd_size_type buildid_len_arg;
   size_t buildid_len;
@@ -2295,7 +2295,11 @@ dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
   if (data == NULL)
     {
       if (bfd_get_error () == bfd_error_no_error)
-	return NULL;
+	{
+	  if (!require)
+	    return nullptr;
+	  error (_("could not read '.gnu_debugaltlink' section"));
+	}
       error (_("could not read '.gnu_debugaltlink' section: %s"),
 	     bfd_errmsg (bfd_get_error ()));
     }
@@ -6300,7 +6304,7 @@ get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
   dwarf2_per_bfd *per_bfd = this_cu->per_bfd;
 
   if (this_cu->is_dwz)
-    abbrev = &dwarf2_get_dwz_file (per_bfd)->abbrev;
+    abbrev = &dwarf2_get_dwz_file (per_bfd, true)->abbrev;
   else
     abbrev = &per_bfd->abbrev;
 
@@ -20515,7 +20519,7 @@ read_attribute_value (const struct die_reader_specs *reader,
       /* FALLTHROUGH */
     case DW_FORM_GNU_strp_alt:
       {
-	dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+	dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
 	LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
 						     &bytes_read);
 
@@ -21113,7 +21117,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
     section = &cu->dwo_unit->dwo_file->sections.line;
   else if (cu->per_cu->is_dwz)
     {
-      dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+      dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
 
       section = &dwz->line;
     }
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index d2bae5a7ee8..86ac6b50cc0 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -633,11 +633,14 @@ struct signatured_type
   struct dwo_unit *dwo_unit;
 };
 
-/* Open the separate '.dwz' debug file, if needed.  Return NULL if
-   there is no .gnu_debugaltlink section in the file.  Error if there
-   is such a section but the file cannot be found.  */
-
-extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd);
+/* Open the separate '.dwz' debug file, if needed.  If there is no
+   .gnu_debugaltlink section in the file, then the result depends on
+   REQUIRE: if REQUIRE is true, then error; if REQUIRE is false,
+   return NULL.  Always error if there is such a section but the file
+   cannot be found.  */
+
+extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd,
+				      bool require = false);
 
 /* Return the type of the DIE at DIE_OFFSET in the CU named by
    PER_CU.  */
-- 
2.26.2


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

* [PATCH 4/5] Include scoped_fd.h in debuginfod-support.h
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
                   ` (2 preceding siblings ...)
  2021-02-21  3:16 ` [PATCH 3/5] Avoid crash on missing dwz file Tom Tromey
@ 2021-02-21  3:16 ` Tom Tromey
  2021-02-21  3:16 ` [PATCH 5/5] Move dwarf2_get_dwz_file to dwarf2/dwz.h Tom Tromey
  2021-03-06 16:28 ` [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
  5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

debuginfod-support.h requires scoped_fd, so include the header here.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* debuginfod-support.h: Include scoped_fd.h.
---
 gdb/ChangeLog            | 4 ++++
 gdb/debuginfod-support.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h
index e90b78a745b..5e5aab56e74 100644
--- a/gdb/debuginfod-support.h
+++ b/gdb/debuginfod-support.h
@@ -19,6 +19,8 @@
 #ifndef DEBUGINFOD_SUPPORT_H
 #define DEBUGINFOD_SUPPORT_H
 
+#include "gdbsupport/scoped_fd.h"
+
 /* Query debuginfod servers for a source file associated with an
    executable with BUILD_ID.  BUILD_ID can be given as a binary blob or
    a null-terminated string.  If given as a binary blob, BUILD_ID_LEN
-- 
2.26.2


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

* [PATCH 5/5] Move dwarf2_get_dwz_file to dwarf2/dwz.h
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
                   ` (3 preceding siblings ...)
  2021-02-21  3:16 ` [PATCH 4/5] Include scoped_fd.h in debuginfod-support.h Tom Tromey
@ 2021-02-21  3:16 ` Tom Tromey
  2021-03-06 16:28 ` [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
  5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21  3:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This moves dwarf2_get_dwz_file and some helper code to dwarf2/dwz.h.
The main benefit of this is just shrinking dwarf2/read.c a little bit.

gdb/ChangeLog
2021-02-20  Tom Tromey  <tom@tromey.com>

	* dwarf2/sect-names.h (dwarf2_elf_names): Declare.
	* dwarf2/read.h (dwarf2_get_dwz_file): Move to dwz.h.
	* dwarf2/read.c (dwarf2_elf_names): No longer static.
	(locate_dwz_sections, dwz_search_other_debugdirs)
	(dwarf2_get_dwz_file): Move to dwz.c.
	* dwarf2/dwz.h (dwarf2_get_dwz_file): Move declaration from
	read.h.
	* dwarf2/dwz.c (locate_dwz_sections, dwz_search_other_debugdirs)
	(dwarf2_get_dwz_file): Move from read.c.
---
 gdb/ChangeLog           |  12 ++
 gdb/dwarf2/dwz.c        | 242 ++++++++++++++++++++++++++++++++++++++++
 gdb/dwarf2/dwz.h        |  11 ++
 gdb/dwarf2/read.c       | 234 +-------------------------------------
 gdb/dwarf2/read.h       |   9 --
 gdb/dwarf2/sect-names.h |   3 +
 6 files changed, 269 insertions(+), 242 deletions(-)

diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c
index 6be2fa92456..f9d5db6b48a 100644
--- a/gdb/dwarf2/dwz.c
+++ b/gdb/dwarf2/dwz.c
@@ -20,6 +20,16 @@
 #include "defs.h"
 #include "dwarf2/dwz.h"
 
+#include "build-id.h"
+#include "debuginfod-support.h"
+#include "dwarf2/read.h"
+#include "dwarf2/sect-names.h"
+#include "filenames.h"
+#include "gdb_bfd.h"
+#include "gdbcore.h"
+#include "gdbsupport/pathstuff.h"
+#include "gdbsupport/scoped_fd.h"
+
 const char *
 dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
 {
@@ -38,3 +48,235 @@ dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
     return NULL;
   return (const char *) (str.buffer + str_offset);
 }
+
+/* A helper function to find the sections for a .dwz file.  */
+
+static void
+locate_dwz_sections (bfd *abfd, asection *sectp, dwz_file *dwz_file)
+{
+  /* Note that we only support the standard ELF names, because .dwz
+     is ELF-only (at the time of writing).  */
+  if (dwarf2_elf_names.abbrev.matches (sectp->name))
+    {
+      dwz_file->abbrev.s.section = sectp;
+      dwz_file->abbrev.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.info.matches (sectp->name))
+    {
+      dwz_file->info.s.section = sectp;
+      dwz_file->info.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.str.matches (sectp->name))
+    {
+      dwz_file->str.s.section = sectp;
+      dwz_file->str.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.line.matches (sectp->name))
+    {
+      dwz_file->line.s.section = sectp;
+      dwz_file->line.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.macro.matches (sectp->name))
+    {
+      dwz_file->macro.s.section = sectp;
+      dwz_file->macro.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.gdb_index.matches (sectp->name))
+    {
+      dwz_file->gdb_index.s.section = sectp;
+      dwz_file->gdb_index.size = bfd_section_size (sectp);
+    }
+  else if (dwarf2_elf_names.debug_names.matches (sectp->name))
+    {
+      dwz_file->debug_names.s.section = sectp;
+      dwz_file->debug_names.size = bfd_section_size (sectp);
+    }
+}
+
+/* Attempt to find a .dwz file (whose full path is represented by
+   FILENAME) in all of the specified debug file directories provided.
+
+   Return the equivalent gdb_bfd_ref_ptr of the .dwz file found, or
+   nullptr if it could not find anything.  */
+
+static gdb_bfd_ref_ptr
+dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
+			    size_t buildid_len)
+{
+  /* Let's assume that the path represented by FILENAME has the
+     "/.dwz/" subpath in it.  This is what (most) GNU/Linux
+     distributions do, anyway.  */
+  size_t dwz_pos = filename.find ("/.dwz/");
+
+  if (dwz_pos == std::string::npos)
+    return nullptr;
+
+  /* This is an obvious assertion, but it's here more to educate
+     future readers of this code that FILENAME at DWZ_POS *must*
+     contain a directory separator.  */
+  gdb_assert (IS_DIR_SEPARATOR (filename[dwz_pos]));
+
+  gdb_bfd_ref_ptr dwz_bfd;
+  std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
+    = dirnames_to_char_ptr_vec (debug_file_directory);
+
+  for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
+    {
+      /* The idea is to iterate over the
+	 debug file directories provided by the user and
+	 replace the hard-coded path in the "filename" by each
+	 debug-file-directory.
+
+	 For example, suppose that filename is:
+
+	   /usr/lib/debug/.dwz/foo.dwz
+
+	 And suppose that we have "$HOME/bar" as the
+	 debug-file-directory.  We would then adjust filename
+	 to look like:
+
+	   $HOME/bar/.dwz/foo.dwz
+
+	 which would hopefully allow us to find the alt debug
+	 file.  */
+      std::string ddir = debugdir.get ();
+
+      if (ddir.empty ())
+	continue;
+
+      /* Make sure the current debug-file-directory ends with a
+	 directory separator.  This is needed because, if FILENAME
+	 contains something like "/usr/lib/abcde/.dwz/foo.dwz" and
+	 DDIR is "/usr/lib/abc", then could wrongfully skip it
+	 below.  */
+      if (!IS_DIR_SEPARATOR (ddir.back ()))
+	ddir += SLASH_STRING;
+
+      /* Check whether the beginning of FILENAME is DDIR.  If it is,
+	 then we are dealing with a file which we already attempted to
+	 open before, so we just skip it and continue processing the
+	 remaining debug file directories.  */
+      if (filename.size () > ddir.size ()
+	  && filename.compare (0, ddir.size (), ddir) == 0)
+	continue;
+
+      /* Replace FILENAME's default debug-file-directory with
+	 DDIR.  */
+      std::string new_filename = ddir + &filename[dwz_pos + 1];
+
+      dwz_bfd = gdb_bfd_open (new_filename.c_str (), gnutarget);
+
+      if (dwz_bfd == nullptr)
+	continue;
+
+      if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+	{
+	  dwz_bfd.reset (nullptr);
+	  continue;
+	}
+
+      /* Found it.  */
+      break;
+    }
+
+  return dwz_bfd;
+}
+
+/* See dwz.h.  */
+
+struct dwz_file *
+dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
+{
+  bfd_size_type buildid_len_arg;
+  size_t buildid_len;
+  bfd_byte *buildid;
+
+  if (per_bfd->dwz_file != NULL)
+    return per_bfd->dwz_file.get ();
+
+  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)
+    {
+      if (bfd_get_error () == bfd_error_no_error)
+	{
+	  if (!require)
+	    return nullptr;
+	  error (_("could not read '.gnu_debugaltlink' section"));
+	}
+      error (_("could not read '.gnu_debugaltlink' section: %s"),
+	     bfd_errmsg (bfd_get_error ()));
+    }
+
+  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 (bfd_get_filename (per_bfd->obfd));
+
+      filename = ldirname (abs.get ()) + SLASH_STRING + filename;
+    }
+
+  /* First try the file name given in the section.  If that doesn't
+     work, try to use the build-id instead.  */
+  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))
+	dwz_bfd.reset (nullptr);
+    }
+
+  if (dwz_bfd == NULL)
+    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
+
+  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);
+    }
+
+  if (dwz_bfd == nullptr)
+    {
+      gdb::unique_xmalloc_ptr<char> alt_filename;
+      const char *origname = bfd_get_filename (per_bfd->obfd);
+
+      scoped_fd fd (debuginfod_debuginfo_query (buildid,
+						buildid_len,
+						origname,
+						&alt_filename));
+
+      if (fd.get () >= 0)
+	{
+	  /* File successfully retrieved from server.  */
+	  dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget);
+
+	  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))
+	    dwz_bfd.reset (nullptr);
+	}
+    }
+
+  if (dwz_bfd == NULL)
+    error (_("could not find '.gnu_debugaltlink' file for %s"),
+	   bfd_get_filename (per_bfd->obfd));
+
+  std::unique_ptr<struct dwz_file> result
+    (new struct dwz_file (std::move (dwz_bfd)));
+
+  for (asection *sec : gdb_bfd_sections (result->dwz_bfd))
+    locate_dwz_sections (result->dwz_bfd.get (), sec, result.get ());
+
+  gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ());
+  per_bfd->dwz_file = std::move (result);
+  return per_bfd->dwz_file.get ();
+}
diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h
index c50aab8676c..634afbbfbcf 100644
--- a/gdb/dwarf2/dwz.h
+++ b/gdb/dwarf2/dwz.h
@@ -24,6 +24,8 @@
 #include "dwarf2/index-cache.h"
 #include "dwarf2/section.h"
 
+struct dwarf2_per_bfd;
+
 /* This represents a '.dwz' file.  */
 
 struct dwz_file
@@ -62,4 +64,13 @@ struct dwz_file
   const char *read_string (struct objfile *objfile, LONGEST str_offset);
 };
 
+/* Open the separate '.dwz' debug file, if needed.  If there is no
+   .gnu_debugaltlink section in the file, then the result depends on
+   REQUIRE: if REQUIRE is true, then error; if REQUIRE is false,
+   return NULL.  Always error if there is such a section but the file
+   cannot be found.  */
+
+extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd,
+				      bool require = false);
+
 #endif /* GDB_DWARF2_DWZ_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6a755f716d1..31f34dc6047 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -87,7 +87,6 @@
 #include "rust-lang.h"
 #include "gdbsupport/pathstuff.h"
 #include "count-one-bits.h"
-#include "debuginfod-support.h"
 
 /* When == 1, print basic high level tracing messages.
    When > 1, be more verbose.
@@ -324,7 +323,7 @@ get_dwarf2_per_objfile (struct objfile *objfile)
 /* Note that if the debugging section has been compressed, it might
    have a name like .zdebug_info.  */
 
-static const struct dwarf2_debug_sections dwarf2_elf_names =
+const struct dwarf2_debug_sections dwarf2_elf_names =
 {
   { ".debug_info", ".zdebug_info" },
   { ".debug_abbrev", ".zdebug_abbrev" },
@@ -2143,237 +2142,6 @@ dwarf2_get_section_info (struct objfile *objfile,
   *sizep = info->size;
 }
 
-/* A helper function to find the sections for a .dwz file.  */
-
-static void
-locate_dwz_sections (bfd *abfd, asection *sectp, dwz_file *dwz_file)
-{
-  /* Note that we only support the standard ELF names, because .dwz
-     is ELF-only (at the time of writing).  */
-  if (dwarf2_elf_names.abbrev.matches (sectp->name))
-    {
-      dwz_file->abbrev.s.section = sectp;
-      dwz_file->abbrev.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.info.matches (sectp->name))
-    {
-      dwz_file->info.s.section = sectp;
-      dwz_file->info.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.str.matches (sectp->name))
-    {
-      dwz_file->str.s.section = sectp;
-      dwz_file->str.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.line.matches (sectp->name))
-    {
-      dwz_file->line.s.section = sectp;
-      dwz_file->line.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.macro.matches (sectp->name))
-    {
-      dwz_file->macro.s.section = sectp;
-      dwz_file->macro.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.gdb_index.matches (sectp->name))
-    {
-      dwz_file->gdb_index.s.section = sectp;
-      dwz_file->gdb_index.size = bfd_section_size (sectp);
-    }
-  else if (dwarf2_elf_names.debug_names.matches (sectp->name))
-    {
-      dwz_file->debug_names.s.section = sectp;
-      dwz_file->debug_names.size = bfd_section_size (sectp);
-    }
-}
-
-/* Attempt to find a .dwz file (whose full path is represented by
-   FILENAME) in all of the specified debug file directories provided.
-
-   Return the equivalent gdb_bfd_ref_ptr of the .dwz file found, or
-   nullptr if it could not find anything.  */
-
-static gdb_bfd_ref_ptr
-dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
-			    size_t buildid_len)
-{
-  /* Let's assume that the path represented by FILENAME has the
-     "/.dwz/" subpath in it.  This is what (most) GNU/Linux
-     distributions do, anyway.  */
-  size_t dwz_pos = filename.find ("/.dwz/");
-
-  if (dwz_pos == std::string::npos)
-    return nullptr;
-
-  /* This is an obvious assertion, but it's here more to educate
-     future readers of this code that FILENAME at DWZ_POS *must*
-     contain a directory separator.  */
-  gdb_assert (IS_DIR_SEPARATOR (filename[dwz_pos]));
-
-  gdb_bfd_ref_ptr dwz_bfd;
-  std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
-    = dirnames_to_char_ptr_vec (debug_file_directory);
-
-  for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
-    {
-      /* The idea is to iterate over the
-	 debug file directories provided by the user and
-	 replace the hard-coded path in the "filename" by each
-	 debug-file-directory.
-
-	 For example, suppose that filename is:
-
-	   /usr/lib/debug/.dwz/foo.dwz
-
-	 And suppose that we have "$HOME/bar" as the
-	 debug-file-directory.  We would then adjust filename
-	 to look like:
-
-	   $HOME/bar/.dwz/foo.dwz
-
-	 which would hopefully allow us to find the alt debug
-	 file.  */
-      std::string ddir = debugdir.get ();
-
-      if (ddir.empty ())
-	continue;
-
-      /* Make sure the current debug-file-directory ends with a
-	 directory separator.  This is needed because, if FILENAME
-	 contains something like "/usr/lib/abcde/.dwz/foo.dwz" and
-	 DDIR is "/usr/lib/abc", then could wrongfully skip it
-	 below.  */
-      if (!IS_DIR_SEPARATOR (ddir.back ()))
-	ddir += SLASH_STRING;
-
-      /* Check whether the beginning of FILENAME is DDIR.  If it is,
-	 then we are dealing with a file which we already attempted to
-	 open before, so we just skip it and continue processing the
-	 remaining debug file directories.  */
-      if (filename.size () > ddir.size ()
-	  && filename.compare (0, ddir.size (), ddir) == 0)
-	continue;
-
-      /* Replace FILENAME's default debug-file-directory with
-	 DDIR.  */
-      std::string new_filename = ddir + &filename[dwz_pos + 1];
-
-      dwz_bfd = gdb_bfd_open (new_filename.c_str (), gnutarget);
-
-      if (dwz_bfd == nullptr)
-	continue;
-
-      if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
-	{
-	  dwz_bfd.reset (nullptr);
-	  continue;
-	}
-
-      /* Found it.  */
-      break;
-    }
-
-  return dwz_bfd;
-}
-
-/* See dwarf2read.h.  */
-
-struct dwz_file *
-dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
-{
-  bfd_size_type buildid_len_arg;
-  size_t buildid_len;
-  bfd_byte *buildid;
-
-  if (per_bfd->dwz_file != NULL)
-    return per_bfd->dwz_file.get ();
-
-  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)
-    {
-      if (bfd_get_error () == bfd_error_no_error)
-	{
-	  if (!require)
-	    return nullptr;
-	  error (_("could not read '.gnu_debugaltlink' section"));
-	}
-      error (_("could not read '.gnu_debugaltlink' section: %s"),
-	     bfd_errmsg (bfd_get_error ()));
-    }
-
-  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 (bfd_get_filename (per_bfd->obfd));
-
-      filename = ldirname (abs.get ()) + SLASH_STRING + filename;
-    }
-
-  /* First try the file name given in the section.  If that doesn't
-     work, try to use the build-id instead.  */
-  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))
-	dwz_bfd.reset (nullptr);
-    }
-
-  if (dwz_bfd == NULL)
-    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
-
-  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);
-    }
-
-  if (dwz_bfd == nullptr)
-    {
-      gdb::unique_xmalloc_ptr<char> alt_filename;
-      const char *origname = bfd_get_filename (per_bfd->obfd);
-
-      scoped_fd fd (debuginfod_debuginfo_query (buildid,
-						buildid_len,
-						origname,
-						&alt_filename));
-
-      if (fd.get () >= 0)
-	{
-	  /* File successfully retrieved from server.  */
-	  dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget);
-
-	  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))
-	    dwz_bfd.reset (nullptr);
-	}
-    }
-
-  if (dwz_bfd == NULL)
-    error (_("could not find '.gnu_debugaltlink' file for %s"),
-	   bfd_get_filename (per_bfd->obfd));
-
-  std::unique_ptr<struct dwz_file> result
-    (new struct dwz_file (std::move (dwz_bfd)));
-
-  for (asection *sec : gdb_bfd_sections (result->dwz_bfd))
-    locate_dwz_sections (result->dwz_bfd.get (), sec, result.get ());
-
-  gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ());
-  per_bfd->dwz_file = std::move (result);
-  return per_bfd->dwz_file.get ();
-}
 \f
 /* DWARF quick_symbols_functions support.  */
 
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 86ac6b50cc0..1d0f0a4995b 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -633,15 +633,6 @@ struct signatured_type
   struct dwo_unit *dwo_unit;
 };
 
-/* Open the separate '.dwz' debug file, if needed.  If there is no
-   .gnu_debugaltlink section in the file, then the result depends on
-   REQUIRE: if REQUIRE is true, then error; if REQUIRE is false,
-   return NULL.  Always error if there is such a section but the file
-   cannot be found.  */
-
-extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd,
-				      bool require = false);
-
 /* Return the type of the DIE at DIE_OFFSET in the CU named by
    PER_CU.  */
 
diff --git a/gdb/dwarf2/sect-names.h b/gdb/dwarf2/sect-names.h
index b75328358c2..bf7ea2cd4b2 100644
--- a/gdb/dwarf2/sect-names.h
+++ b/gdb/dwarf2/sect-names.h
@@ -72,4 +72,7 @@ struct dwarf2_debug_sections {
   int sentinel;
 };
 
+/* Section names for ELF.  */
+extern const struct dwarf2_debug_sections dwarf2_elf_names;
+
 #endif /* GDB_DWARF2_SECT_NAMES_H */
-- 
2.26.2


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

* Re: [PATCH 3/5] Avoid crash on missing dwz file
  2021-02-21  3:16 ` [PATCH 3/5] Avoid crash on missing dwz file Tom Tromey
@ 2021-02-21 16:23   ` Tom Tromey
  2021-02-21 17:19     ` Tom Tromey
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2021-02-21 16:23 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

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

Tom> If DWARF contains a reference to a "dwz" file, but there is no
Tom> .gnu_debugaltlink section, then gdb will crash.  This happens because
Tom> dwarf2_get_dwz_file will return NULL, but some callers do not expect
Tom> this.

I didn't write a test for this, but it should probably have one, so I
will.

Tom

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

* Re: [PATCH 3/5] Avoid crash on missing dwz file
  2021-02-21 16:23   ` Tom Tromey
@ 2021-02-21 17:19     ` Tom Tromey
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-02-21 17:19 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom> I didn't write a test for this, but it should probably have one, so I
Tom> will.

Here's the updated patch.

Tom

commit be6b917e5997b2c5ed0ced04f0363e02e7e430bd
Author: Tom Tromey <tom@tromey.com>
Date:   Sat Feb 20 19:41:14 2021 -0700

    Avoid crash on missing dwz file
    
    If DWARF contains a reference to a "dwz" file, but there is no
    .gnu_debugaltlink section, then gdb will crash.  This happens because
    dwarf2_get_dwz_file will return NULL, but some callers do not expect
    this.
    
    This patch changes dwarf2_get_dwz_file so that callers can require a
    dwz file.  Then, it updates the callers that are attempting to process
    references to the dwz file to require one.
    
    This includes a new testcase.  The dwarf.exp changes don't handle the
    new forms exactly correctly -- they are only handled well enough to
    let this test case complete.
    
    gdb/ChangeLog
    2021-02-20  Tom Tromey  <tom@tromey.com>
    
            * dwarf2/read.h (dwarf2_get_dwz_file): Add 'require' parameter.
            * dwarf2/read.c (dwarf2_get_dwz_file): Add 'require' parameter.
            (get_abbrev_section_for_cu, read_attribute_value)
            (get_debug_line_section): Update.
            * dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
    
    gdb/testsuite/ChangeLog
    2021-02-21  Tom Tromey  <tom@tromey.com>
    
            * lib/dwarf.exp (_handle_DW_FORM): Treat DW_FORM_GNU_ref_alt and
            DW_FORM_GNU_strp_alt like DW_FORM_sec_offset.
            * gdb.dwarf2/dwznolink.exp: New file.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c9e1d0f4b02..89ca0daf76e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2021-02-20  Tom Tromey  <tom@tromey.com>
+
+	* dwarf2/read.h (dwarf2_get_dwz_file): Add 'require' parameter.
+	* dwarf2/read.c (dwarf2_get_dwz_file): Add 'require' parameter.
+	(get_abbrev_section_for_cu, read_attribute_value)
+	(get_debug_line_section): Update.
+	* dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
+
 2021-02-20  Tom Tromey  <tom@tromey.com>
 
 	* dwarf2/sect-names.h (struct dwarf2_section_names) <matches>: New
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index afe2f91168b..2ecebe6173c 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -509,7 +509,8 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 		    || macinfo_type == DW_MACRO_undef_sup
 		    || section_is_dwz)
 		  {
-		    dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+		    dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd,
+							 true);
 
 		    body = dwz->read_string (objfile, str_offset);
 		  }
@@ -693,7 +694,8 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 
 	    if (macinfo_type == DW_MACRO_import_sup)
 	      {
-		dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+		dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd,
+						     true);
 
 		dwz->macro.read (objfile);
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0347f91947e..6a755f716d1 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2279,7 +2279,7 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid,
 /* See dwarf2read.h.  */
 
 struct dwz_file *
-dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
+dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
 {
   bfd_size_type buildid_len_arg;
   size_t buildid_len;
@@ -2295,7 +2295,11 @@ dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
   if (data == NULL)
     {
       if (bfd_get_error () == bfd_error_no_error)
-	return NULL;
+	{
+	  if (!require)
+	    return nullptr;
+	  error (_("could not read '.gnu_debugaltlink' section"));
+	}
       error (_("could not read '.gnu_debugaltlink' section: %s"),
 	     bfd_errmsg (bfd_get_error ()));
     }
@@ -6300,7 +6304,7 @@ get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
   dwarf2_per_bfd *per_bfd = this_cu->per_bfd;
 
   if (this_cu->is_dwz)
-    abbrev = &dwarf2_get_dwz_file (per_bfd)->abbrev;
+    abbrev = &dwarf2_get_dwz_file (per_bfd, true)->abbrev;
   else
     abbrev = &per_bfd->abbrev;
 
@@ -20515,7 +20519,7 @@ read_attribute_value (const struct die_reader_specs *reader,
       /* FALLTHROUGH */
     case DW_FORM_GNU_strp_alt:
       {
-	dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+	dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
 	LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
 						     &bytes_read);
 
@@ -21113,7 +21117,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
     section = &cu->dwo_unit->dwo_file->sections.line;
   else if (cu->per_cu->is_dwz)
     {
-      dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+      dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
 
       section = &dwz->line;
     }
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index d2bae5a7ee8..86ac6b50cc0 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -633,11 +633,14 @@ struct signatured_type
   struct dwo_unit *dwo_unit;
 };
 
-/* Open the separate '.dwz' debug file, if needed.  Return NULL if
-   there is no .gnu_debugaltlink section in the file.  Error if there
-   is such a section but the file cannot be found.  */
-
-extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd);
+/* Open the separate '.dwz' debug file, if needed.  If there is no
+   .gnu_debugaltlink section in the file, then the result depends on
+   REQUIRE: if REQUIRE is true, then error; if REQUIRE is false,
+   return NULL.  Always error if there is such a section but the file
+   cannot be found.  */
+
+extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd,
+				      bool require = false);
 
 /* Return the type of the DIE at DIE_OFFSET in the CU named by
    PER_CU.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 70b836b8c2f..27f475525ac 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2021-02-21  Tom Tromey  <tom@tromey.com>
+
+	* lib/dwarf.exp (_handle_DW_FORM): Treat DW_FORM_GNU_ref_alt and
+	DW_FORM_GNU_strp_alt like DW_FORM_sec_offset.
+	* gdb.dwarf2/dwznolink.exp: New file.
+
 2021-02-18  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.arch/i386-biarch-core.exp: Add target check.
diff --git a/gdb/testsuite/gdb.dwarf2/dwznolink.exp b/gdb/testsuite/gdb.dwarf2/dwznolink.exp
new file mode 100644
index 00000000000..98976d7e59c
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dwznolink.exp
@@ -0,0 +1,60 @@
+# Copyright 2021 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.
+if {![dwarf2_support]} {
+    return 0
+}
+
+# No remote host testing either.
+if {[is_remote host]} {
+    return 0
+}
+
+standard_testfile main.c dwznolink.S
+
+set asm_file [standard_output_file $srcfile2]
+
+# The DWARF should contain a reference to a supplementary ("dwz")
+# file, but the section that links to the file should be missing.  At
+# one point, this caused gdb crashes.
+Dwarf::assemble $asm_file {
+    cu {} {
+	compile_unit {{language @DW_LANG_C}} {
+	    constant {
+		{name 0 DW_FORM_GNU_strp_alt}
+		{type 97 DW_FORM_GNU_ref_alt}
+		{const_value 99 data1}
+	    }
+	}
+    }
+}
+
+# We can't use prepare_for_testing here because we need to check the
+# 'file' command's output.
+if {[build_executable $testfile.exp $testfile \
+	 [list $srcfile $asm_file] {nodebug quiet}]} {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "file -readnow $binfile" \
+    "could not read '.gnu_debugaltlink' section" \
+    "file $testfile"
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index c1c07be0b98..f8fbd381810 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -456,6 +456,8 @@ namespace eval Dwarf {
 		_op .${size}byte $value
 	    }
 
+	    DW_FORM_GNU_ref_alt -
+	    DW_FORM_GNU_strp_alt -
 	    DW_FORM_sec_offset {
 		variable _cu_offset_size
 		_op .${_cu_offset_size}byte $value
@@ -553,8 +555,6 @@ namespace eval Dwarf {
 
 	    DW_FORM_GNU_addr_index -
 	    DW_FORM_GNU_str_index -
-	    DW_FORM_GNU_ref_alt -
-	    DW_FORM_GNU_strp_alt -
 
 	    default {
 		error "unhandled form $form"

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

* Re: [PATCH 0/5] Some minor dwz-handling improvements & cleanups
  2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
                   ` (4 preceding siblings ...)
  2021-02-21  3:16 ` [PATCH 5/5] Move dwarf2_get_dwz_file to dwarf2/dwz.h Tom Tromey
@ 2021-03-06 16:28 ` Tom Tromey
  5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2021-03-06 16:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

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

Tom> I was looking at adding support for DWARF 5's equivalent to
Tom> .gnu_debugaltlink, and found that I could provoke a gdb crash.  In
Tom> particular, if gdb tries to process a form requiring a "dwz" file, but
Tom> no .gnu_debugaltlink section exists, then that will cause a failure.
Tom> See patch #3 for some more info on this.

Tom> While fixing this, I found a number of small cleanups that made the
Tom> result a bit prettier.  There are more like this that are possible,
Tom> for example basically none of the DWARF code should be in symfile.h.

I'm checking these in now.

Tom

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

end of thread, other threads:[~2021-03-06 16:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-21  3:16 [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey
2021-02-21  3:16 ` [PATCH 1/5] Create new file dwarf2/sect-names.h Tom Tromey
2021-02-21  3:16 ` [PATCH 2/5] Change section_is_p to a method on dwarf2_section_names Tom Tromey
2021-02-21  3:16 ` [PATCH 3/5] Avoid crash on missing dwz file Tom Tromey
2021-02-21 16:23   ` Tom Tromey
2021-02-21 17:19     ` Tom Tromey
2021-02-21  3:16 ` [PATCH 4/5] Include scoped_fd.h in debuginfod-support.h Tom Tromey
2021-02-21  3:16 ` [PATCH 5/5] Move dwarf2_get_dwz_file to dwarf2/dwz.h Tom Tromey
2021-03-06 16:28 ` [PATCH 0/5] Some minor dwz-handling improvements & cleanups Tom Tromey

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