3 Copyright (C) 2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #ifndef GDB_DWARF2_PARENT_MAP_H
21 #define GDB_DWARF2_PARENT_MAP_H
24 #include "dwarf2/types.h"
25 #include "gdbsupport/gdb_obstack.h"
27 class cooked_index_entry
;
29 /* A class that handles mapping from a DIE range to a parent
32 The generated DWARF can sometimes have the declaration for a method
33 in a class (or perhaps namespace) scope, with the definition
34 appearing outside this scope... just one of the many bad things
37 For example, a program like this:
39 struct X { int method (); };
40 int X::method () { return 23; }
42 ... ends up with DWARF like:
44 <1><2e>: Abbrev Number: 2 (DW_TAG_structure_type)
47 <2><39>: Abbrev Number: 3 (DW_TAG_subprogram)
48 <3a> DW_AT_external : 1
49 <3a> DW_AT_name : (indirect string, offset: 0xf): method
51 <1><66>: Abbrev Number: 8 (DW_TAG_subprogram)
52 <67> DW_AT_specification: <0x39>
54 Here, the name of DIE 0x66 can't be determined without knowing the
57 In order to handle this situation, we defer certain entries until
58 the end of scanning, at which point we'll know the containing
59 context of all the DIEs that we might have scanned. */
64 parent_map () = default;
65 ~parent_map () = default;
68 DISABLE_COPY_AND_ASSIGN (parent_map
);
69 parent_map (parent_map
&&) = default;
70 parent_map
&operator= (parent_map
&&) = default;
72 /* A reasonably opaque type that is used as part of a DIE range. */
73 enum addr_type
: CORE_ADDR
{ };
75 /* Turn a section offset into a value that can be used in a parent
77 static addr_type
form_addr (const gdb_byte
*info_ptr
)
79 static_assert (sizeof (addr_type
) >= sizeof (uintptr_t));
80 return (addr_type
) (uintptr_t) info_ptr
;
83 /* Add a new entry to this map. DIEs from START to END, inclusive,
84 are mapped to PARENT. */
85 void add_entry (addr_type start
, addr_type end
,
86 const cooked_index_entry
*parent
)
88 gdb_assert (parent
!= nullptr);
89 m_map
.set_empty (start
, end
, (void *) parent
);
92 /* Look up an entry in this map. */
93 const cooked_index_entry
*find (addr_type search
) const
95 return static_cast<const cooked_index_entry
*> (m_map
.find (search
));
98 /* Return a fixed addrmap that is equivalent to this map. */
99 addrmap_fixed
*to_fixed (struct obstack
*obstack
) const
101 return new (obstack
) addrmap_fixed (obstack
, &m_map
);
104 /* Dump a human-readable form of this map. */
105 void dump (dwarf2_per_bfd
*per_bfd
) const;
109 /* An addrmap that maps from section offsets to cooked_index_entry *. */
110 addrmap_mutable m_map
;
113 /* Keep a collection of parent_map objects, and allow for lookups
114 across all of them. */
119 parent_map_map () = default;
120 ~parent_map_map () = default;
122 DISABLE_COPY_AND_ASSIGN (parent_map_map
);
124 /* Add a parent_map to this map. Note that a copy of MAP is made --
125 modifications to MAP after this call will have no effect. */
126 void add_map (const parent_map
&map
)
128 m_maps
.push_back (map
.to_fixed (&m_storage
));
131 /* Look up an entry in this map. */
132 const cooked_index_entry
*find (parent_map::addr_type search
) const
134 for (const auto &iter
: m_maps
)
136 const cooked_index_entry
*result
137 = static_cast<const cooked_index_entry
*> (iter
->find (search
));
138 if (result
!= nullptr)
144 /* Dump a human-readable form of this collection of parent_maps. */
145 void dump (dwarf2_per_bfd
*per_bfd
) const;
149 /* Storage for the convert maps. */
150 auto_obstack m_storage
;
152 /* While conceptually this class is a combination of parent_maps, in
153 practice it is just a number of fixed maps. This is important
154 because we want to allow concurrent lookups, but a mutable
155 addrmap is based on a splay-tree, which is not thread-safe, even
156 for nominally read-only lookups. */
157 std::vector
<addrmap_fixed
*> m_maps
;
160 #endif /* GDB_DWARF2_PARENT_MAP_H */