1 /* DWARF 2 abbreviations 2 3 Copyright (C) 1994-2023 Free Software Foundation, Inc. 4 5 Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, 6 Inc. with support from Florida State University (under contract 7 with the Ada Joint Program Office), and Silicon Graphics, Inc. 8 Initial contribution by Brent Benson, Harris Computer Systems, Inc., 9 based on Fred Fish's (Cygnus Support) implementation of DWARF 1 10 support. 11 12 This file is part of GDB. 13 14 This program is free software; you can redistribute it and/or modify 15 it under the terms of the GNU General Public License as published by 16 the Free Software Foundation; either version 3 of the License, or 17 (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 GNU General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 26 27 #include "defs.h" 28 #include "dwarf2/read.h" 29 #include "dwarf2/abbrev.h" 30 #include "dwarf2/leb.h" 31 #include "bfd.h" 32 33 /* Hash function for an abbrev. */ 34 35 static hashval_t 36 hash_abbrev (const void *item) 37 { 38 const struct abbrev_info *info = (const struct abbrev_info *) item; 39 /* Warning: if you change this next line, you must also update the 40 other code in this class using the _with_hash functions. */ 41 return info->number; 42 } 43 44 /* Comparison function for abbrevs. */ 45 46 static int 47 eq_abbrev (const void *lhs, const void *rhs) 48 { 49 const struct abbrev_info *l_info = (const struct abbrev_info *) lhs; 50 const struct abbrev_info *r_info = (const struct abbrev_info *) rhs; 51 return l_info->number == r_info->number; 52 } 53 54 /* Abbreviation tables. 55 56 In DWARF version 2, the description of the debugging information is 57 stored in a separate .debug_abbrev section. Before we read any 58 dies from a section we read in all abbreviations and install them 59 in a hash table. */ 60 61 abbrev_table::abbrev_table (sect_offset off, struct dwarf2_section_info *sect) 62 : sect_off (off), 63 section (sect), 64 m_abbrevs (htab_create_alloc (20, hash_abbrev, eq_abbrev, 65 nullptr, xcalloc, xfree)) 66 { 67 } 68 69 /* Add an abbreviation to the table. */ 70 71 void 72 abbrev_table::add_abbrev (struct abbrev_info *abbrev) 73 { 74 void **slot = htab_find_slot_with_hash (m_abbrevs.get (), abbrev, 75 abbrev->number, INSERT); 76 *slot = abbrev; 77 } 78 79 /* Helper function that returns true if a DIE with the given tag might 80 plausibly be indexed. */ 81 82 static bool 83 tag_interesting_for_index (dwarf_tag tag) 84 { 85 switch (tag) 86 { 87 case DW_TAG_array_type: 88 case DW_TAG_base_type: 89 case DW_TAG_class_type: 90 case DW_TAG_constant: 91 case DW_TAG_enumeration_type: 92 case DW_TAG_enumerator: 93 case DW_TAG_imported_declaration: 94 case DW_TAG_imported_unit: 95 case DW_TAG_inlined_subroutine: 96 case DW_TAG_interface_type: 97 case DW_TAG_module: 98 case DW_TAG_namespace: 99 case DW_TAG_ptr_to_member_type: 100 case DW_TAG_set_type: 101 case DW_TAG_string_type: 102 case DW_TAG_structure_type: 103 case DW_TAG_subprogram: 104 case DW_TAG_subrange_type: 105 case DW_TAG_generic_subrange: 106 case DW_TAG_subroutine_type: 107 case DW_TAG_typedef: 108 case DW_TAG_union_type: 109 case DW_TAG_unspecified_type: 110 case DW_TAG_variable: 111 return true; 112 } 113 114 return false; 115 } 116 117 /* Read in an abbrev table. */ 118 119 abbrev_table_up 120 abbrev_table::read (struct dwarf2_section_info *section, 121 sect_offset sect_off) 122 { 123 bfd *abfd = section->get_bfd_owner (); 124 const gdb_byte *abbrev_ptr; 125 struct abbrev_info *cur_abbrev; 126 127 abbrev_table_up abbrev_table (new struct abbrev_table (sect_off, section)); 128 struct obstack *obstack = &abbrev_table->m_abbrev_obstack; 129 130 /* Caller must ensure this. */ 131 gdb_assert (section->readin); 132 abbrev_ptr = section->buffer + to_underlying (sect_off); 133 134 while (true) 135 { 136 unsigned int bytes_read; 137 /* Loop until we reach an abbrev number of 0. */ 138 unsigned int abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, 139 &bytes_read); 140 if (abbrev_number == 0) 141 break; 142 abbrev_ptr += bytes_read; 143 144 /* Start without any attrs. */ 145 obstack_blank (obstack, offsetof (abbrev_info, attrs)); 146 cur_abbrev = (struct abbrev_info *) obstack_base (obstack); 147 148 /* Read in abbrev header. */ 149 cur_abbrev->number = abbrev_number; 150 cur_abbrev->tag 151 = (enum dwarf_tag) read_unsigned_leb128 (abfd, abbrev_ptr, 152 &bytes_read); 153 abbrev_ptr += bytes_read; 154 cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr); 155 abbrev_ptr += 1; 156 157 unsigned int size = 0; 158 unsigned int sibling_offset = -1; 159 bool is_csize = true; 160 161 bool has_hardcoded_declaration = false; 162 bool has_specification_or_origin = false; 163 bool has_name = false; 164 bool has_linkage_name = false; 165 bool has_location = false; 166 bool has_external = false; 167 168 /* Now read in declarations. */ 169 int num_attrs = 0; 170 for (;;) 171 { 172 struct attr_abbrev cur_attr; 173 174 cur_attr.name 175 = (enum dwarf_attribute) read_unsigned_leb128 (abfd, abbrev_ptr, 176 &bytes_read); 177 abbrev_ptr += bytes_read; 178 cur_attr.form 179 = (enum dwarf_form) read_unsigned_leb128 (abfd, abbrev_ptr, 180 &bytes_read); 181 abbrev_ptr += bytes_read; 182 if (cur_attr.form == DW_FORM_implicit_const) 183 { 184 cur_attr.implicit_const = read_signed_leb128 (abfd, abbrev_ptr, 185 &bytes_read); 186 abbrev_ptr += bytes_read; 187 } 188 else 189 cur_attr.implicit_const = -1; 190 191 if (cur_attr.name == 0) 192 break; 193 194 switch (cur_attr.name) 195 { 196 case DW_AT_declaration: 197 if (cur_attr.form == DW_FORM_flag_present) 198 has_hardcoded_declaration = true; 199 break; 200 201 case DW_AT_external: 202 has_external = true; 203 break; 204 205 case DW_AT_specification: 206 case DW_AT_abstract_origin: 207 case DW_AT_extension: 208 has_specification_or_origin = true; 209 break; 210 211 case DW_AT_name: 212 has_name = true; 213 break; 214 215 case DW_AT_MIPS_linkage_name: 216 case DW_AT_linkage_name: 217 has_linkage_name = true; 218 break; 219 220 case DW_AT_const_value: 221 case DW_AT_location: 222 has_location = true; 223 break; 224 225 case DW_AT_sibling: 226 if (is_csize && cur_attr.form == DW_FORM_ref4) 227 sibling_offset = size; 228 break; 229 } 230 231 switch (cur_attr.form) 232 { 233 case DW_FORM_data1: 234 case DW_FORM_ref1: 235 case DW_FORM_flag: 236 case DW_FORM_strx1: 237 size += 1; 238 break; 239 case DW_FORM_flag_present: 240 case DW_FORM_implicit_const: 241 break; 242 case DW_FORM_data2: 243 case DW_FORM_ref2: 244 case DW_FORM_strx2: 245 size += 2; 246 break; 247 case DW_FORM_strx3: 248 size += 3; 249 break; 250 case DW_FORM_data4: 251 case DW_FORM_ref4: 252 case DW_FORM_strx4: 253 size += 4; 254 break; 255 case DW_FORM_data8: 256 case DW_FORM_ref8: 257 case DW_FORM_ref_sig8: 258 size += 8; 259 break; 260 case DW_FORM_data16: 261 size += 16; 262 break; 263 264 default: 265 is_csize = false; 266 break; 267 } 268 269 ++num_attrs; 270 obstack_grow (obstack, &cur_attr, sizeof (cur_attr)); 271 } 272 273 cur_abbrev = (struct abbrev_info *) obstack_finish (obstack); 274 cur_abbrev->num_attrs = num_attrs; 275 276 if (!has_name && !has_linkage_name && !has_specification_or_origin) 277 { 278 /* Some anonymous DIEs are worth examining. */ 279 cur_abbrev->interesting 280 = (cur_abbrev->tag == DW_TAG_namespace 281 || cur_abbrev->tag == DW_TAG_enumeration_type); 282 } 283 else if ((cur_abbrev->tag == DW_TAG_structure_type 284 || cur_abbrev->tag == DW_TAG_class_type 285 || cur_abbrev->tag == DW_TAG_union_type) 286 && cur_abbrev->has_children) 287 { 288 /* We have to record this as interesting, regardless of how 289 DW_AT_declaration is set, so that any subsequent 290 DW_AT_specification pointing at a child of this will get 291 the correct scope. */ 292 cur_abbrev->interesting = true; 293 } 294 else if (has_hardcoded_declaration 295 && (cur_abbrev->tag != DW_TAG_variable || !has_external)) 296 cur_abbrev->interesting = false; 297 else if (!tag_interesting_for_index (cur_abbrev->tag)) 298 cur_abbrev->interesting = false; 299 else if (!has_location && !has_specification_or_origin && !has_external 300 && cur_abbrev->tag == DW_TAG_variable) 301 cur_abbrev->interesting = false; 302 else 303 cur_abbrev->interesting = true; 304 305 /* If there are no children, and the abbrev has a constant size, 306 then we don't care about the sibling offset, because it's 307 simple to just skip the entire DIE without reading a sibling 308 offset. */ 309 if ((!cur_abbrev->has_children && is_csize) 310 /* Overflow. */ 311 || sibling_offset != (unsigned short) sibling_offset) 312 sibling_offset = -1; 313 cur_abbrev->size_if_constant = is_csize ? size : 0; 314 cur_abbrev->sibling_offset = sibling_offset; 315 316 abbrev_table->add_abbrev (cur_abbrev); 317 } 318 319 return abbrev_table; 320 } 321