Move some code from dwarf2/read.c to die.c
authorTom Tromey <tom@tromey.com>
Fri, 27 Jan 2023 04:13:20 +0000 (21:13 -0700)
committerTom Tromey <tom@tromey.com>
Sun, 12 Feb 2023 20:03:58 +0000 (13:03 -0700)
This patch introduces a new file, dwarf2/die.c, and moves some
DIE-related code out of dwarf2/read.c and into this new file.  This is
just a small part of the long-term project to split up read.c.
(According to 'wc', dwarf2/read.c is the largest file in gdb by around
8000 LOC.)

Regression tested on x86-64 Fedora 36.

gdb/Makefile.in
gdb/dwarf2/die.c [new file with mode: 0644]
gdb/dwarf2/die.h
gdb/dwarf2/read.c
gdb/gdb-gdb.gdb.in

index 049a14fe40a3b7367064c4330bfe34d02682ac10..dac5a66e9adaf587a3aa85057ec75a5da5d62de4 100644 (file)
@@ -1069,6 +1069,7 @@ COMMON_SFILES = \
        dwarf2/comp-unit-head.c \
        dwarf2/cooked-index.c \
        dwarf2/cu.c \
+       dwarf2/die.c \
        dwarf2/dwz.c \
        dwarf2/expr.c \
        dwarf2/frame-tailcall.c \
diff --git a/gdb/dwarf2/die.c b/gdb/dwarf2/die.c
new file mode 100644 (file)
index 0000000..d409d24
--- /dev/null
@@ -0,0 +1,229 @@
+/* DWARF DIEs
+
+   Copyright (C) 1994-2023 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/>.  */
+
+#include "defs.h"
+#include "dwarf2/die.h"
+#include "dwarf2/stringify.h"
+
+/* See die.h.  */
+
+struct die_info *
+die_info::allocate (struct obstack *obstack, int num_attrs)
+{
+  size_t size = sizeof (struct die_info);
+
+  if (num_attrs > 1)
+    size += (num_attrs - 1) * sizeof (struct attribute);
+
+  struct die_info *die = (struct die_info *) obstack_alloc (obstack, size);
+  memset (die, 0, size);
+  return die;
+}
+
+/* See die.h.  */
+
+hashval_t
+die_info::hash (const void *item)
+{
+  const struct die_info *die = (const struct die_info *) item;
+
+  return to_underlying (die->sect_off);
+}
+
+/* See die.h.  */
+
+int
+die_info::eq (const void *item_lhs, const void *item_rhs)
+{
+  const struct die_info *die_lhs = (const struct die_info *) item_lhs;
+  const struct die_info *die_rhs = (const struct die_info *) item_rhs;
+
+  return die_lhs->sect_off == die_rhs->sect_off;
+}
+
+static void
+dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
+{
+  unsigned int i;
+
+  gdb_printf (f, "%*sDie: %s (abbrev %d, offset %s)\n",
+             indent, "",
+             dwarf_tag_name (die->tag), die->abbrev,
+             sect_offset_str (die->sect_off));
+
+  if (die->parent != NULL)
+    gdb_printf (f, "%*s  parent at offset: %s\n",
+               indent, "",
+               sect_offset_str (die->parent->sect_off));
+
+  gdb_printf (f, "%*s  has children: %s\n",
+             indent, "",
+             dwarf_bool_name (die->child != NULL));
+
+  gdb_printf (f, "%*s  attributes:\n", indent, "");
+
+  for (i = 0; i < die->num_attrs; ++i)
+    {
+      gdb_printf (f, "%*s    %s (%s) ",
+                 indent, "",
+                 dwarf_attr_name (die->attrs[i].name),
+                 dwarf_form_name (die->attrs[i].form));
+
+      switch (die->attrs[i].form)
+       {
+       case DW_FORM_addr:
+       case DW_FORM_addrx:
+       case DW_FORM_GNU_addr_index:
+         gdb_printf (f, "address: ");
+         gdb_puts (hex_string (die->attrs[i].as_address ()), f);
+         break;
+       case DW_FORM_block2:
+       case DW_FORM_block4:
+       case DW_FORM_block:
+       case DW_FORM_block1:
+         gdb_printf (f, "block: size %s",
+                     pulongest (die->attrs[i].as_block ()->size));
+         break;
+       case DW_FORM_exprloc:
+         gdb_printf (f, "expression: size %s",
+                     pulongest (die->attrs[i].as_block ()->size));
+         break;
+       case DW_FORM_data16:
+         gdb_printf (f, "constant of 16 bytes");
+         break;
+       case DW_FORM_ref_addr:
+         gdb_printf (f, "ref address: ");
+         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
+         break;
+       case DW_FORM_GNU_ref_alt:
+         gdb_printf (f, "alt ref address: ");
+         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
+         break;
+       case DW_FORM_ref1:
+       case DW_FORM_ref2:
+       case DW_FORM_ref4:
+       case DW_FORM_ref8:
+       case DW_FORM_ref_udata:
+         gdb_printf (f, "constant ref: 0x%lx (adjusted)",
+                     (long) (die->attrs[i].as_unsigned ()));
+         break;
+       case DW_FORM_data1:
+       case DW_FORM_data2:
+       case DW_FORM_data4:
+       case DW_FORM_data8:
+       case DW_FORM_udata:
+         gdb_printf (f, "constant: %s",
+                     pulongest (die->attrs[i].as_unsigned ()));
+         break;
+       case DW_FORM_sec_offset:
+         gdb_printf (f, "section offset: %s",
+                     pulongest (die->attrs[i].as_unsigned ()));
+         break;
+       case DW_FORM_ref_sig8:
+         gdb_printf (f, "signature: %s",
+                     hex_string (die->attrs[i].as_signature ()));
+         break;
+       case DW_FORM_string:
+       case DW_FORM_strp:
+       case DW_FORM_line_strp:
+       case DW_FORM_strx:
+       case DW_FORM_GNU_str_index:
+       case DW_FORM_GNU_strp_alt:
+         gdb_printf (f, "string: \"%s\" (%s canonicalized)",
+                     die->attrs[i].as_string ()
+                     ? die->attrs[i].as_string () : "",
+                     die->attrs[i].canonical_string_p () ? "is" : "not");
+         break;
+       case DW_FORM_flag:
+         if (die->attrs[i].as_boolean ())
+           gdb_printf (f, "flag: TRUE");
+         else
+           gdb_printf (f, "flag: FALSE");
+         break;
+       case DW_FORM_flag_present:
+         gdb_printf (f, "flag: TRUE");
+         break;
+       case DW_FORM_indirect:
+         /* The reader will have reduced the indirect form to
+            the "base form" so this form should not occur.  */
+         gdb_printf (f,
+                     "unexpected attribute form: DW_FORM_indirect");
+         break;
+       case DW_FORM_sdata:
+       case DW_FORM_implicit_const:
+         gdb_printf (f, "constant: %s",
+                     plongest (die->attrs[i].as_signed ()));
+         break;
+       default:
+         gdb_printf (f, "unsupported attribute form: %d.",
+                     die->attrs[i].form);
+         break;
+       }
+      gdb_printf (f, "\n");
+    }
+}
+
+static void
+dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die)
+{
+  int indent = level * 4;
+
+  gdb_assert (die != NULL);
+
+  if (level >= max_level)
+    return;
+
+  dump_die_shallow (f, indent, die);
+
+  if (die->child != NULL)
+    {
+      gdb_printf (f, "%*s  Children:", indent, "");
+      if (level + 1 < max_level)
+       {
+         gdb_printf (f, "\n");
+         dump_die_1 (f, level + 1, max_level, die->child);
+       }
+      else
+       {
+         gdb_printf (f,
+                     " [not printed, max nesting level reached]\n");
+       }
+    }
+
+  if (die->sibling != NULL && level > 0)
+    {
+      dump_die_1 (f, level, max_level, die->sibling);
+    }
+}
+
+/* See die.h.  */
+
+void
+die_info::dump (int max_level)
+{
+  dump_die_1 (gdb_stdlog, 0, max_level, this);
+}
+
+/* See die.h.  */
+
+void
+die_info::error_dump ()
+{
+  dump_die_shallow (gdb_stderr, 0, this);
+}
index ae46514c85967633f53d9f20343617ab931902c8..cdee46996d6a34221b4923df4b9181dd6ece69f1 100644 (file)
 #define GDB_DWARF2_DIE_H
 
 #include "complaints.h"
+#include "dwarf2/attribute.h"
 
 /* This data structure holds a complete die structure.  */
 struct die_info
 {
+  /* Allocate a new die_info on OBSTACK.  NUM_ATTRS is the number of
+     attributes that are needed.  */
+  static die_info *allocate (struct obstack *obstack, int num_attrs);
+
+  /* Trivial hash function for die_info: the hash value of a DIE is
+     its offset in .debug_info for this objfile.  */
+  static hashval_t hash (const void *item);
+
+  /* Trivial comparison function for die_info structures: two DIEs
+     are equal if they have the same offset.  */
+  static int eq (const void *item_lhs, const void *item_rhs);
+
+  /* Dump this DIE and any children to MAX_LEVEL.  They are written to
+     gdb_stdlog.  Note this is called from the pdie user command in
+     gdb-gdb.gdb.  */
+  void dump (int max_level);
+
+  /* Shallowly dump this DIE to gdb_stderr.  */
+  void error_dump ();
+
   /* Return the named attribute or NULL if not there, but do not
      follow DW_AT_specification, etc.  */
   struct attribute *attr (dwarf_attribute name)
index fb5aa7b8e5bbc85a9e71be005ea747581e537fae..ce6c01ac77148a854be9562e67c8346c29a613eb 100644 (file)
@@ -1127,15 +1127,6 @@ static const char *dwarf2_physname (const char *name, struct die_info *die,
 static struct die_info *dwarf2_extension (struct die_info *die,
                                          struct dwarf2_cu **);
 
-static void dump_die_shallow (struct ui_file *, int indent, struct die_info *);
-
-static void dump_die_for_error (struct die_info *);
-
-static void dump_die_1 (struct ui_file *, int level, int max_level,
-                       struct die_info *);
-
-/*static*/ void dump_die (struct die_info *, int max_level);
-
 static void store_in_ref_table (struct die_info *,
                                struct dwarf2_cu *);
 
@@ -1172,8 +1163,6 @@ static int attr_to_dynamic_prop (const struct attribute *attr,
 
 static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
 
-static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
-
 static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, int);
 
 static void fill_in_loclist_baton (struct dwarf2_cu *cu,
@@ -6065,7 +6054,7 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
                  section->get_name (),
                  (unsigned) (begin_info_ptr - section->buffer),
                  bfd_get_filename (abfd));
-      dump_die (comp_unit_die, dwarf_die_debug);
+      comp_unit_die->dump (dwarf_die_debug);
     }
 
   /* Skip dummy compilation units.  */
@@ -7687,29 +7676,6 @@ process_queue (dwarf2_per_objfile *per_objfile)
                           objfile_name (per_objfile->objfile));
 }
 
-/* Trivial hash function for die_info: the hash value of a DIE
-   is its offset in .debug_info for this objfile.  */
-
-static hashval_t
-die_hash (const void *item)
-{
-  const struct die_info *die = (const struct die_info *) item;
-
-  return to_underlying (die->sect_off);
-}
-
-/* Trivial comparison function for die_info structures: two DIEs
-   are equal if they have the same offset.  */
-
-static int
-die_eq (const void *item_lhs, const void *item_rhs)
-{
-  const struct die_info *die_lhs = (const struct die_info *) item_lhs;
-  const struct die_info *die_rhs = (const struct die_info *) item_rhs;
-
-  return die_lhs->sect_off == die_rhs->sect_off;
-}
-
 /* Load the DIEs associated with PER_CU into memory.
 
    In some cases, the caller, while reading partial symbols, will need to load
@@ -7736,8 +7702,8 @@ load_full_comp_unit (dwarf2_per_cu_data *this_cu,
   gdb_assert (cu->die_hash == NULL);
   cu->die_hash =
     htab_create_alloc_ex (cu->header.get_length_without_initial () / 12,
-                         die_hash,
-                         die_eq,
+                         die_info::hash,
+                         die_info::eq,
                          NULL,
                          &cu->comp_unit_obstack,
                          hashtab_obstack_allocate,
@@ -17884,7 +17850,7 @@ read_die_and_siblings (const struct die_reader_specs *reader,
                  reader->die_section->get_name (),
                  (unsigned) (info_ptr - reader->die_section->buffer),
                  bfd_get_filename (reader->abfd));
-      dump_die (die, dwarf_die_debug);
+      die->dump (dwarf_die_debug);
     }
 
   return die;
@@ -17923,7 +17889,8 @@ read_full_die_1 (const struct die_reader_specs *reader,
           abbrev_number,
           bfd_get_filename (abfd));
 
-  die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs);
+  die = die_info::allocate (&cu->comp_unit_obstack,
+                           abbrev->num_attrs + num_extra_attrs);
   die->sect_off = sect_off;
   die->tag = abbrev->tag;
   die->abbrev = abbrev_number;
@@ -17990,7 +17957,7 @@ read_full_die (const struct die_reader_specs *reader,
                  reader->die_section->get_name (),
                  (unsigned) (info_ptr - reader->die_section->buffer),
                  bfd_get_filename (reader->abfd));
-      dump_die (*diep, dwarf_die_debug);
+      (*diep)->dump (dwarf_die_debug);
     }
 
   return result;
@@ -22192,176 +22159,6 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu)
   return follow_die_ref (die, attr, ext_cu);
 }
 
-static void
-dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
-{
-  unsigned int i;
-
-  gdb_printf (f, "%*sDie: %s (abbrev %d, offset %s)\n",
-             indent, "",
-             dwarf_tag_name (die->tag), die->abbrev,
-             sect_offset_str (die->sect_off));
-
-  if (die->parent != NULL)
-    gdb_printf (f, "%*s  parent at offset: %s\n",
-               indent, "",
-               sect_offset_str (die->parent->sect_off));
-
-  gdb_printf (f, "%*s  has children: %s\n",
-             indent, "",
-             dwarf_bool_name (die->child != NULL));
-
-  gdb_printf (f, "%*s  attributes:\n", indent, "");
-
-  for (i = 0; i < die->num_attrs; ++i)
-    {
-      gdb_printf (f, "%*s    %s (%s) ",
-                 indent, "",
-                 dwarf_attr_name (die->attrs[i].name),
-                 dwarf_form_name (die->attrs[i].form));
-
-      switch (die->attrs[i].form)
-       {
-       case DW_FORM_addr:
-       case DW_FORM_addrx:
-       case DW_FORM_GNU_addr_index:
-         gdb_printf (f, "address: ");
-         gdb_puts (hex_string (die->attrs[i].as_address ()), f);
-         break;
-       case DW_FORM_block2:
-       case DW_FORM_block4:
-       case DW_FORM_block:
-       case DW_FORM_block1:
-         gdb_printf (f, "block: size %s",
-                     pulongest (die->attrs[i].as_block ()->size));
-         break;
-       case DW_FORM_exprloc:
-         gdb_printf (f, "expression: size %s",
-                     pulongest (die->attrs[i].as_block ()->size));
-         break;
-       case DW_FORM_data16:
-         gdb_printf (f, "constant of 16 bytes");
-         break;
-       case DW_FORM_ref_addr:
-         gdb_printf (f, "ref address: ");
-         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
-         break;
-       case DW_FORM_GNU_ref_alt:
-         gdb_printf (f, "alt ref address: ");
-         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
-         break;
-       case DW_FORM_ref1:
-       case DW_FORM_ref2:
-       case DW_FORM_ref4:
-       case DW_FORM_ref8:
-       case DW_FORM_ref_udata:
-         gdb_printf (f, "constant ref: 0x%lx (adjusted)",
-                     (long) (die->attrs[i].as_unsigned ()));
-         break;
-       case DW_FORM_data1:
-       case DW_FORM_data2:
-       case DW_FORM_data4:
-       case DW_FORM_data8:
-       case DW_FORM_udata:
-         gdb_printf (f, "constant: %s",
-                     pulongest (die->attrs[i].as_unsigned ()));
-         break;
-       case DW_FORM_sec_offset:
-         gdb_printf (f, "section offset: %s",
-                     pulongest (die->attrs[i].as_unsigned ()));
-         break;
-       case DW_FORM_ref_sig8:
-         gdb_printf (f, "signature: %s",
-                     hex_string (die->attrs[i].as_signature ()));
-         break;
-       case DW_FORM_string:
-       case DW_FORM_strp:
-       case DW_FORM_line_strp:
-       case DW_FORM_strx:
-       case DW_FORM_GNU_str_index:
-       case DW_FORM_GNU_strp_alt:
-         gdb_printf (f, "string: \"%s\" (%s canonicalized)",
-                     die->attrs[i].as_string ()
-                     ? die->attrs[i].as_string () : "",
-                     die->attrs[i].canonical_string_p () ? "is" : "not");
-         break;
-       case DW_FORM_flag:
-         if (die->attrs[i].as_boolean ())
-           gdb_printf (f, "flag: TRUE");
-         else
-           gdb_printf (f, "flag: FALSE");
-         break;
-       case DW_FORM_flag_present:
-         gdb_printf (f, "flag: TRUE");
-         break;
-       case DW_FORM_indirect:
-         /* The reader will have reduced the indirect form to
-            the "base form" so this form should not occur.  */
-         gdb_printf (f,
-                     "unexpected attribute form: DW_FORM_indirect");
-         break;
-       case DW_FORM_sdata:
-       case DW_FORM_implicit_const:
-         gdb_printf (f, "constant: %s",
-                     plongest (die->attrs[i].as_signed ()));
-         break;
-       default:
-         gdb_printf (f, "unsupported attribute form: %d.",
-                     die->attrs[i].form);
-         break;
-       }
-      gdb_printf (f, "\n");
-    }
-}
-
-static void
-dump_die_for_error (struct die_info *die)
-{
-  dump_die_shallow (gdb_stderr, 0, die);
-}
-
-static void
-dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die)
-{
-  int indent = level * 4;
-
-  gdb_assert (die != NULL);
-
-  if (level >= max_level)
-    return;
-
-  dump_die_shallow (f, indent, die);
-
-  if (die->child != NULL)
-    {
-      gdb_printf (f, "%*s  Children:", indent, "");
-      if (level + 1 < max_level)
-       {
-         gdb_printf (f, "\n");
-         dump_die_1 (f, level + 1, max_level, die->child);
-       }
-      else
-       {
-         gdb_printf (f,
-                     " [not printed, max nesting level reached]\n");
-       }
-    }
-
-  if (die->sibling != NULL && level > 0)
-    {
-      dump_die_1 (f, level, max_level, die->sibling);
-    }
-}
-
-/* This is called from the pdie macro in gdbinit.in.
-   It's not static so gcc will keep a copy callable from gdb.  */
-
-void
-dump_die (struct die_info *die, int max_level)
-{
-  dump_die_1 (gdb_stdlog, 0, max_level, die);
-}
-
 static void
 store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -22390,7 +22187,7 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
     die = follow_die_sig (src_die, attr, ref_cu);
   else
     {
-      dump_die_for_error (src_die);
+      src_die->error_dump ();
       error (_("Dwarf Error: Expected reference attribute [in module %s]"),
             objfile_name ((*ref_cu)->per_objfile->objfile));
     }
@@ -22889,7 +22686,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
   die = follow_die_sig_1 (src_die, sig_type, ref_cu);
   if (die == NULL)
     {
-      dump_die_for_error (src_die);
+      src_die->error_dump ();
       error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
               " from DIE at %s [in module %s]"),
             hex_string (signature), sect_offset_str (src_die->sect_off),
@@ -23032,8 +22829,8 @@ read_signatured_type (signatured_type *sig_type,
       gdb_assert (cu->die_hash == NULL);
       cu->die_hash =
        htab_create_alloc_ex (cu->header.get_length_without_initial () / 12,
-                             die_hash,
-                             die_eq,
+                             die_info::hash,
+                             die_info::eq,
                              NULL,
                              &cu->comp_unit_obstack,
                              hashtab_obstack_allocate,
@@ -23349,20 +23146,6 @@ dwarf_alloc_block (struct dwarf2_cu *cu)
   return XOBNEW (&cu->comp_unit_obstack, struct dwarf_block);
 }
 
-static struct die_info *
-dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
-{
-  struct die_info *die;
-  size_t size = sizeof (struct die_info);
-
-  if (num_attrs > 1)
-    size += (num_attrs - 1) * sizeof (struct attribute);
-
-  die = (struct die_info *) obstack_alloc (&cu->comp_unit_obstack, size);
-  memset (die, 0, sizeof (struct die_info));
-  return (die);
-}
-
 \f
 
 /* Macro support.  */
index b9fd457d069d044fdfe3136a7a1367c577979bd2..d5d533a0a2e070103f2fb38221fe1ddfbb47dd03 100644 (file)
@@ -23,10 +23,10 @@ set prompt (top-gdb)
 
 define pdie
   if $argc == 1
-    call dump_die ($arg0, 1)
+    call $arg0->dump (1)
   else
     if $argc == 2
-      call dump_die ($arg0, $arg1)
+      call $arg0->dump ($arg1)
     else
       printf "Syntax: pdie die [depth]\n"
     end