aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2023-01-26 21:13:20 -0700
committerTom Tromey <tom@tromey.com>2023-02-12 13:03:58 -0700
commitfdc82b33c455b049d4739ef0959f458263197a33 (patch)
tree8a3d71e0afeeb7d88cb3a858eb4f925d07224e84
parent8282ad74c302a8e0db7a588e500ae117a1df68c5 (diff)
downloadgdb-fdc82b33c455b049d4739ef0959f458263197a33.zip
gdb-fdc82b33c455b049d4739ef0959f458263197a33.tar.gz
gdb-fdc82b33c455b049d4739ef0959f458263197a33.tar.bz2
Move some code from dwarf2/read.c to die.c
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.
-rw-r--r--gdb/Makefile.in1
-rw-r--r--gdb/dwarf2/die.c229
-rw-r--r--gdb/dwarf2/die.h21
-rw-r--r--gdb/dwarf2/read.c239
-rw-r--r--gdb/gdb-gdb.gdb.in4
5 files changed, 264 insertions, 230 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 049a14f..dac5a66 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -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
index 0000000..d409d24
--- /dev/null
+++ b/gdb/dwarf2/die.c
@@ -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);
+}
diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
index ae46514..cdee469 100644
--- a/gdb/dwarf2/die.h
+++ b/gdb/dwarf2/die.h
@@ -21,10 +21,31 @@
#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)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index fb5aa7b..ce6c01a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -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;
@@ -22193,176 +22160,6 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **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)
{
void **slot;
@@ -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);
-}
-
/* Macro support. */
diff --git a/gdb/gdb-gdb.gdb.in b/gdb/gdb-gdb.gdb.in
index b9fd457..d5d533a 100644
--- a/gdb/gdb-gdb.gdb.in
+++ b/gdb/gdb-gdb.gdb.in
@@ -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