1 /* DIE indexing 2 3 Copyright (C) 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 #ifndef GDB_DWARF2_PARENT_MAP_H 21 #define GDB_DWARF2_PARENT_MAP_H 22 23 #include <algorithm> 24 25 class cooked_index_entry; 26 27 /* A class that handles mapping from a DIE range to a parent 28 entry. 29 30 The generated DWARF can sometimes have the declaration for a method 31 in a class (or perhaps namespace) scope, with the definition 32 appearing outside this scope... just one of the many bad things 33 about DWARF. In order to handle this situation, we defer certain 34 entries until the end of scanning, at which point we'll know the 35 containing context of all the DIEs that we might have scanned. */ 36 class parent_map 37 { 38 public: 39 40 parent_map () = default; 41 ~parent_map () = default; 42 43 /* Move only. */ 44 DISABLE_COPY_AND_ASSIGN (parent_map); 45 parent_map (parent_map &&) = default; 46 parent_map &operator= (parent_map &&) = default; 47 48 /* A reasonably opaque type that is used here to combine a section 49 offset and the 'dwz' flag into a single value. */ 50 enum addr_type : CORE_ADDR { }; 51 52 /* Turn a section offset into a value that can be used in a parent 53 map. */ 54 static addr_type form_addr (sect_offset offset, bool is_dwz) 55 { 56 CORE_ADDR value = to_underlying (offset); 57 if (is_dwz) 58 value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1); 59 return addr_type (value); 60 } 61 62 /* Add a new entry to this map. DIEs from START to END, inclusive, 63 are mapped to PARENT. */ 64 void add_entry (addr_type start, addr_type end, 65 const cooked_index_entry *parent) 66 { 67 gdb_assert (parent != nullptr); 68 m_map.set_empty (start, end, (void *) parent); 69 } 70 71 /* Look up an entry in this map. */ 72 const cooked_index_entry *find (addr_type search) const 73 { 74 return static_cast<const cooked_index_entry *> (m_map.find (search)); 75 } 76 77 /* Return a fixed addrmap that is equivalent to this map. */ 78 addrmap_fixed *to_fixed (struct obstack *obstack) const 79 { 80 return new (obstack) addrmap_fixed (obstack, &m_map); 81 } 82 83 private: 84 85 /* An addrmap that maps from section offsets to cooked_index_entry *. */ 86 addrmap_mutable m_map; 87 }; 88 89 /* Keep a collection of parent_map objects, and allow for lookups 90 across all of them. */ 91 class parent_map_map 92 { 93 public: 94 95 parent_map_map () = default; 96 ~parent_map_map () = default; 97 98 DISABLE_COPY_AND_ASSIGN (parent_map_map); 99 100 /* Add a parent_map to this map. */ 101 void add_map (const parent_map &map) 102 { 103 m_maps.push_back (map.to_fixed (&m_storage)); 104 } 105 106 /* Look up an entry in this map. */ 107 const cooked_index_entry *find (parent_map::addr_type search) const 108 { 109 for (const auto &iter : m_maps) 110 { 111 const cooked_index_entry *result 112 = static_cast<const cooked_index_entry *> (iter->find (search)); 113 if (result != nullptr) 114 return result; 115 } 116 return nullptr; 117 } 118 119 private: 120 121 /* Storage for the convert maps. */ 122 auto_obstack m_storage; 123 124 /* While conceptually this class is a combination of parent_maps, in 125 practice it is just a number of fixed maps. This is important 126 because we want to allow concurrent lookups, but a mutable 127 addrmap is based on a splay-tree, which is not thread-safe, even 128 for nominally read-only lookups. */ 129 std::vector<addrmap_fixed *> m_maps; 130 }; 131 132 #endif /* GDB_DWARF2_PARENT_MAP_H */ 133