1/* DWARF DIEs
2
3   Copyright (C) 1994-2024 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20#include "dwarf2/die.h"
21#include "dwarf2/stringify.h"
22
23/* See die.h.  */
24
25struct die_info *
26die_info::allocate (struct obstack *obstack, int num_attrs)
27{
28  size_t size = sizeof (struct die_info);
29
30  if (num_attrs > 1)
31    size += (num_attrs - 1) * sizeof (struct attribute);
32
33  struct die_info *die = (struct die_info *) obstack_alloc (obstack, size);
34  memset (die, 0, size);
35  return die;
36}
37
38/* See die.h.  */
39
40hashval_t
41die_info::hash (const void *item)
42{
43  const struct die_info *die = (const struct die_info *) item;
44
45  return to_underlying (die->sect_off);
46}
47
48/* See die.h.  */
49
50int
51die_info::eq (const void *item_lhs, const void *item_rhs)
52{
53  const struct die_info *die_lhs = (const struct die_info *) item_lhs;
54  const struct die_info *die_rhs = (const struct die_info *) item_rhs;
55
56  return die_lhs->sect_off == die_rhs->sect_off;
57}
58
59static void
60dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
61{
62  unsigned int i;
63
64  gdb_printf (f, "%*sDie: %s (abbrev %d, offset %s)\n",
65	      indent, "",
66	      dwarf_tag_name (die->tag), die->abbrev,
67	      sect_offset_str (die->sect_off));
68
69  if (die->parent != NULL)
70    gdb_printf (f, "%*s  parent at offset: %s\n",
71		indent, "",
72		sect_offset_str (die->parent->sect_off));
73
74  gdb_printf (f, "%*s  has children: %s\n",
75	      indent, "",
76	      dwarf_bool_name (die->child != NULL));
77
78  gdb_printf (f, "%*s  attributes:\n", indent, "");
79
80  for (i = 0; i < die->num_attrs; ++i)
81    {
82      gdb_printf (f, "%*s    %s (%s) ",
83		  indent, "",
84		  dwarf_attr_name (die->attrs[i].name),
85		  dwarf_form_name (die->attrs[i].form));
86
87      switch (die->attrs[i].form)
88	{
89	case DW_FORM_addr:
90	case DW_FORM_addrx:
91	case DW_FORM_GNU_addr_index:
92	  gdb_printf (f, "address: ");
93	  gdb_puts (hex_string ((CORE_ADDR) die->attrs[i].as_address ()), f);
94	  break;
95	case DW_FORM_block2:
96	case DW_FORM_block4:
97	case DW_FORM_block:
98	case DW_FORM_block1:
99	  gdb_printf (f, "block: size %s",
100		      pulongest (die->attrs[i].as_block ()->size));
101	  break;
102	case DW_FORM_exprloc:
103	  gdb_printf (f, "expression: size %s",
104		      pulongest (die->attrs[i].as_block ()->size));
105	  break;
106	case DW_FORM_data16:
107	  gdb_printf (f, "constant of 16 bytes");
108	  break;
109	case DW_FORM_ref_addr:
110	  gdb_printf (f, "ref address: ");
111	  gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
112	  break;
113	case DW_FORM_GNU_ref_alt:
114	  gdb_printf (f, "alt ref address: ");
115	  gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
116	  break;
117	case DW_FORM_ref1:
118	case DW_FORM_ref2:
119	case DW_FORM_ref4:
120	case DW_FORM_ref8:
121	case DW_FORM_ref_udata:
122	  gdb_printf (f, "constant ref: 0x%lx (adjusted)",
123		      (long) (die->attrs[i].as_unsigned ()));
124	  break;
125	case DW_FORM_data1:
126	case DW_FORM_data2:
127	case DW_FORM_data4:
128	case DW_FORM_data8:
129	case DW_FORM_udata:
130	  gdb_printf (f, "constant: %s",
131		      pulongest (die->attrs[i].as_unsigned ()));
132	  break;
133	case DW_FORM_sec_offset:
134	  gdb_printf (f, "section offset: %s",
135		      pulongest (die->attrs[i].as_unsigned ()));
136	  break;
137	case DW_FORM_ref_sig8:
138	  gdb_printf (f, "signature: %s",
139		      hex_string (die->attrs[i].as_signature ()));
140	  break;
141	case DW_FORM_string:
142	case DW_FORM_strp:
143	case DW_FORM_line_strp:
144	case DW_FORM_strx:
145	case DW_FORM_GNU_str_index:
146	case DW_FORM_GNU_strp_alt:
147	  gdb_printf (f, "string: \"%s\" (%s canonicalized)",
148		      die->attrs[i].as_string ()
149		      ? die->attrs[i].as_string () : "",
150		      die->attrs[i].canonical_string_p () ? "is" : "not");
151	  break;
152	case DW_FORM_flag:
153	  if (die->attrs[i].as_boolean ())
154	    gdb_printf (f, "flag: TRUE");
155	  else
156	    gdb_printf (f, "flag: FALSE");
157	  break;
158	case DW_FORM_flag_present:
159	  gdb_printf (f, "flag: TRUE");
160	  break;
161	case DW_FORM_indirect:
162	  /* The reader will have reduced the indirect form to
163	     the "base form" so this form should not occur.  */
164	  gdb_printf (f,
165		      "unexpected attribute form: DW_FORM_indirect");
166	  break;
167	case DW_FORM_sdata:
168	case DW_FORM_implicit_const:
169	  gdb_printf (f, "constant: %s",
170		      plongest (die->attrs[i].as_signed ()));
171	  break;
172	default:
173	  gdb_printf (f, "unsupported attribute form: %d.",
174		      die->attrs[i].form);
175	  break;
176	}
177      gdb_printf (f, "\n");
178    }
179}
180
181static void
182dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die)
183{
184  int indent = level * 4;
185
186  gdb_assert (die != NULL);
187
188  if (level >= max_level)
189    return;
190
191  dump_die_shallow (f, indent, die);
192
193  if (die->child != NULL)
194    {
195      gdb_printf (f, "%*s  Children:", indent, "");
196      if (level + 1 < max_level)
197	{
198	  gdb_printf (f, "\n");
199	  dump_die_1 (f, level + 1, max_level, die->child);
200	}
201      else
202	{
203	  gdb_printf (f,
204		      " [not printed, max nesting level reached]\n");
205	}
206    }
207
208  if (die->sibling != NULL && level > 0)
209    {
210      dump_die_1 (f, level, max_level, die->sibling);
211    }
212}
213
214/* See die.h.  */
215
216void
217die_info::dump (int max_level)
218{
219  dump_die_1 (gdb_stdlog, 0, max_level, this);
220}
221
222/* See die.h.  */
223
224void
225die_info::error_dump ()
226{
227  dump_die_shallow (gdb_stderr, 0, this);
228}
229