]>
Commit | Line | Data |
---|---|---|
be932484 SM |
1 | /* Reading code for .gdb_index |
2 | ||
1d506c26 | 3 | Copyright (C) 2023-2024 Free Software Foundation, Inc. |
be932484 SM |
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 | ||
be932484 SM |
20 | #include "read-gdb-index.h" |
21 | ||
22 | #include "cli/cli-cmds.h" | |
23 | #include "complaints.h" | |
24 | #include "dwz.h" | |
e5dc0d5d | 25 | #include "event-top.h" |
be932484 SM |
26 | #include "gdb/gdb-index.h" |
27 | #include "gdbsupport/gdb-checked-static-cast.h" | |
28 | #include "mapped-index.h" | |
29 | #include "read.h" | |
30 | ||
31 | /* When true, do not reject deprecated .gdb_index sections. */ | |
32 | static bool use_deprecated_index_sections = false; | |
33 | ||
34 | /* This is a view into the index that converts from bytes to an | |
35 | offset_type, and allows indexing. Unaligned bytes are specifically | |
36 | allowed here, and handled via unpacking. */ | |
37 | ||
38 | class offset_view | |
39 | { | |
40 | public: | |
41 | offset_view () = default; | |
42 | ||
43 | explicit offset_view (gdb::array_view<const gdb_byte> bytes) | |
44 | : m_bytes (bytes) | |
45 | { | |
46 | } | |
47 | ||
48 | /* Extract the INDEXth offset_type from the array. */ | |
49 | offset_type operator[] (size_t index) const | |
50 | { | |
51 | const gdb_byte *bytes = &m_bytes[index * sizeof (offset_type)]; | |
52 | return (offset_type) extract_unsigned_integer (bytes, | |
53 | sizeof (offset_type), | |
54 | BFD_ENDIAN_LITTLE); | |
55 | } | |
56 | ||
57 | /* Return the number of offset_types in this array. */ | |
58 | size_t size () const | |
59 | { | |
60 | return m_bytes.size () / sizeof (offset_type); | |
61 | } | |
62 | ||
63 | /* Return true if this view is empty. */ | |
64 | bool empty () const | |
65 | { | |
66 | return m_bytes.empty (); | |
67 | } | |
68 | ||
69 | private: | |
70 | /* The underlying bytes. */ | |
71 | gdb::array_view<const gdb_byte> m_bytes; | |
72 | }; | |
73 | ||
74 | /* A description of .gdb_index index. The file format is described in | |
75 | a comment by the code that writes the index. */ | |
76 | ||
77 | struct mapped_gdb_index final : public mapped_index_base | |
78 | { | |
79 | /* Index data format version. */ | |
80 | int version = 0; | |
81 | ||
82 | /* The address table data. */ | |
83 | gdb::array_view<const gdb_byte> address_table; | |
84 | ||
85 | /* The symbol table, implemented as a hash table. */ | |
86 | offset_view symbol_table; | |
87 | ||
88 | /* A pointer to the constant pool. */ | |
89 | gdb::array_view<const gdb_byte> constant_pool; | |
90 | ||
93845901 | 91 | /* The shortcut table data. */ |
8b9c08ed MBB |
92 | gdb::array_view<const gdb_byte> shortcut_table; |
93 | ||
be932484 SM |
94 | /* Return the index into the constant pool of the name of the IDXth |
95 | symbol in the symbol table. */ | |
96 | offset_type symbol_name_index (offset_type idx) const | |
97 | { | |
98 | return symbol_table[2 * idx]; | |
99 | } | |
100 | ||
101 | /* Return the index into the constant pool of the CU vector of the | |
102 | IDXth symbol in the symbol table. */ | |
103 | offset_type symbol_vec_index (offset_type idx) const | |
104 | { | |
105 | return symbol_table[2 * idx + 1]; | |
106 | } | |
107 | ||
108 | bool symbol_name_slot_invalid (offset_type idx) const override | |
109 | { | |
110 | return (symbol_name_index (idx) == 0 | |
111 | && symbol_vec_index (idx) == 0); | |
112 | } | |
113 | ||
114 | /* Convenience method to get at the name of the symbol at IDX in the | |
115 | symbol table. */ | |
116 | const char *symbol_name_at | |
117 | (offset_type idx, dwarf2_per_objfile *per_objfile) const override | |
118 | { | |
119 | return (const char *) (this->constant_pool.data () | |
120 | + symbol_name_index (idx)); | |
121 | } | |
122 | ||
123 | size_t symbol_name_count () const override | |
124 | { return this->symbol_table.size () / 2; } | |
125 | ||
126 | quick_symbol_functions_up make_quick_functions () const override; | |
127 | ||
128 | bool version_check () const override | |
129 | { | |
130 | return version >= 8; | |
131 | } | |
132 | }; | |
133 | ||
134 | struct dwarf2_gdb_index : public dwarf2_base_index_functions | |
135 | { | |
136 | /* This dumps minimal information about the index. | |
137 | It is called via "mt print objfiles". | |
138 | One use is to verify .gdb_index has been loaded by the | |
139 | gdb.dwarf2/gdb-index.exp testcase. */ | |
140 | void dump (struct objfile *objfile) override; | |
141 | ||
be932484 SM |
142 | bool expand_symtabs_matching |
143 | (struct objfile *objfile, | |
144 | gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, | |
145 | const lookup_name_info *lookup_name, | |
146 | gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher, | |
147 | gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, | |
148 | block_search_flags search_flags, | |
6c015214 | 149 | domain_search_flags domain) override; |
be932484 SM |
150 | }; |
151 | ||
152 | /* This dumps minimal information about the index. | |
153 | It is called via "mt print objfiles". | |
154 | One use is to verify .gdb_index has been loaded by the | |
155 | gdb.dwarf2/gdb-index.exp testcase. */ | |
156 | ||
157 | void | |
158 | dwarf2_gdb_index::dump (struct objfile *objfile) | |
159 | { | |
160 | dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); | |
161 | ||
162 | mapped_gdb_index *index = (gdb::checked_static_cast<mapped_gdb_index *> | |
163 | (per_objfile->per_bfd->index_table.get ())); | |
164 | gdb_printf (".gdb_index: version %d\n", index->version); | |
165 | gdb_printf ("\n"); | |
166 | } | |
167 | ||
be932484 SM |
168 | /* Helper for dw2_expand_matching symtabs. Called on each symbol |
169 | matched, to expand corresponding CUs that were marked. IDX is the | |
170 | index of the symbol name that matched. */ | |
171 | ||
172 | static bool | |
173 | dw2_expand_marked_cus | |
174 | (dwarf2_per_objfile *per_objfile, offset_type idx, | |
175 | gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, | |
176 | gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, | |
177 | block_search_flags search_flags, | |
c92d4de1 | 178 | domain_search_flags kind) |
be932484 SM |
179 | { |
180 | offset_type vec_len, vec_idx; | |
181 | bool global_seen = false; | |
182 | mapped_gdb_index &index | |
183 | = *(gdb::checked_static_cast<mapped_gdb_index *> | |
184 | (per_objfile->per_bfd->index_table.get ())); | |
185 | ||
186 | offset_view vec (index.constant_pool.slice (index.symbol_vec_index (idx))); | |
187 | vec_len = vec[0]; | |
188 | for (vec_idx = 0; vec_idx < vec_len; ++vec_idx) | |
189 | { | |
190 | offset_type cu_index_and_attrs = vec[vec_idx + 1]; | |
191 | /* This value is only valid for index versions >= 7. */ | |
192 | int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs); | |
193 | gdb_index_symbol_kind symbol_kind = | |
194 | GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs); | |
195 | int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs); | |
196 | /* Only check the symbol attributes if they're present. | |
197 | Indices prior to version 7 don't record them, | |
198 | and indices >= 7 may elide them for certain symbols | |
199 | (gold does this). */ | |
200 | int attrs_valid = | |
201 | (index.version >= 7 | |
202 | && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE); | |
203 | ||
204 | /* Work around gold/15646. */ | |
205 | if (attrs_valid | |
206 | && !is_static | |
207 | && symbol_kind == GDB_INDEX_SYMBOL_KIND_TYPE) | |
208 | { | |
209 | if (global_seen) | |
210 | continue; | |
211 | ||
212 | global_seen = true; | |
213 | } | |
214 | ||
215 | /* Only check the symbol's kind if it has one. */ | |
216 | if (attrs_valid) | |
217 | { | |
218 | if (is_static) | |
219 | { | |
220 | if ((search_flags & SEARCH_STATIC_BLOCK) == 0) | |
221 | continue; | |
222 | } | |
223 | else | |
224 | { | |
225 | if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0) | |
226 | continue; | |
227 | } | |
228 | ||
c92d4de1 TT |
229 | domain_search_flags mask = 0; |
230 | switch (symbol_kind) | |
be932484 | 231 | { |
c92d4de1 TT |
232 | case GDB_INDEX_SYMBOL_KIND_VARIABLE: |
233 | mask = SEARCH_VAR_DOMAIN; | |
be932484 | 234 | break; |
c92d4de1 TT |
235 | case GDB_INDEX_SYMBOL_KIND_FUNCTION: |
236 | mask = SEARCH_FUNCTION_DOMAIN; | |
be932484 | 237 | break; |
c92d4de1 | 238 | case GDB_INDEX_SYMBOL_KIND_TYPE: |
974b36c2 | 239 | mask = SEARCH_TYPE_DOMAIN | SEARCH_STRUCT_DOMAIN; |
be932484 | 240 | break; |
c92d4de1 TT |
241 | case GDB_INDEX_SYMBOL_KIND_OTHER: |
242 | mask = SEARCH_MODULE_DOMAIN; | |
be932484 SM |
243 | break; |
244 | } | |
c92d4de1 TT |
245 | if ((kind & mask) == 0) |
246 | continue; | |
be932484 SM |
247 | } |
248 | ||
249 | /* Don't crash on bad data. */ | |
250 | if (cu_index >= per_objfile->per_bfd->all_units.size ()) | |
251 | { | |
252 | complaint (_(".gdb_index entry has bad CU index" | |
253 | " [in module %s]"), objfile_name (per_objfile->objfile)); | |
254 | continue; | |
255 | } | |
256 | ||
257 | dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (cu_index); | |
258 | if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher, | |
259 | expansion_notify)) | |
260 | return false; | |
261 | } | |
262 | ||
263 | return true; | |
264 | } | |
265 | ||
266 | bool | |
267 | dwarf2_gdb_index::expand_symtabs_matching | |
268 | (struct objfile *objfile, | |
269 | gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, | |
270 | const lookup_name_info *lookup_name, | |
271 | gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher, | |
272 | gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, | |
273 | block_search_flags search_flags, | |
6c015214 | 274 | domain_search_flags domain) |
be932484 SM |
275 | { |
276 | dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); | |
277 | ||
278 | dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher); | |
279 | ||
280 | /* This invariant is documented in quick-functions.h. */ | |
281 | gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr); | |
282 | if (lookup_name == nullptr) | |
283 | { | |
284 | for (dwarf2_per_cu_data *per_cu | |
285 | : all_units_range (per_objfile->per_bfd)) | |
286 | { | |
287 | QUIT; | |
288 | ||
289 | if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, | |
290 | file_matcher, | |
291 | expansion_notify)) | |
292 | return false; | |
293 | } | |
294 | return true; | |
295 | } | |
296 | ||
297 | mapped_gdb_index &index | |
298 | = *(gdb::checked_static_cast<mapped_gdb_index *> | |
299 | (per_objfile->per_bfd->index_table.get ())); | |
300 | ||
301 | bool result | |
302 | = dw2_expand_symtabs_matching_symbol (index, *lookup_name, | |
303 | symbol_matcher, | |
304 | [&] (offset_type idx) | |
305 | { | |
306 | if (!dw2_expand_marked_cus (per_objfile, idx, file_matcher, | |
6c015214 | 307 | expansion_notify, search_flags, domain)) |
be932484 SM |
308 | return false; |
309 | return true; | |
310 | }, per_objfile); | |
311 | ||
312 | return result; | |
313 | } | |
314 | ||
315 | quick_symbol_functions_up | |
316 | mapped_gdb_index::make_quick_functions () const | |
317 | { | |
318 | return quick_symbol_functions_up (new dwarf2_gdb_index); | |
319 | } | |
320 | ||
321 | /* A helper function that reads the .gdb_index from BUFFER and fills | |
322 | in MAP. FILENAME is the name of the file containing the data; | |
323 | it is used for error reporting. DEPRECATED_OK is true if it is | |
324 | ok to use deprecated sections. | |
325 | ||
326 | CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are | |
327 | out parameters that are filled in with information about the CU and | |
328 | TU lists in the section. | |
329 | ||
330 | Returns true if all went well, false otherwise. */ | |
331 | ||
332 | static bool | |
333 | read_gdb_index_from_buffer (const char *filename, | |
334 | bool deprecated_ok, | |
335 | gdb::array_view<const gdb_byte> buffer, | |
336 | mapped_gdb_index *map, | |
337 | const gdb_byte **cu_list, | |
338 | offset_type *cu_list_elements, | |
339 | const gdb_byte **types_list, | |
340 | offset_type *types_list_elements) | |
341 | { | |
342 | const gdb_byte *addr = &buffer[0]; | |
343 | offset_view metadata (buffer); | |
344 | ||
345 | /* Version check. */ | |
346 | offset_type version = metadata[0]; | |
347 | /* Versions earlier than 3 emitted every copy of a psymbol. This | |
348 | causes the index to behave very poorly for certain requests. Version 3 | |
349 | contained incomplete addrmap. So, it seems better to just ignore such | |
350 | indices. */ | |
351 | if (version < 4) | |
352 | { | |
353 | static int warning_printed = 0; | |
354 | if (!warning_printed) | |
355 | { | |
356 | warning (_("Skipping obsolete .gdb_index section in %s."), | |
357 | filename); | |
358 | warning_printed = 1; | |
359 | } | |
360 | return 0; | |
361 | } | |
362 | /* Index version 4 uses a different hash function than index version | |
363 | 5 and later. | |
364 | ||
365 | Versions earlier than 6 did not emit psymbols for inlined | |
366 | functions. Using these files will cause GDB not to be able to | |
367 | set breakpoints on inlined functions by name, so we ignore these | |
368 | indices unless the user has done | |
369 | "set use-deprecated-index-sections on". */ | |
370 | if (version < 6 && !deprecated_ok) | |
371 | { | |
372 | static int warning_printed = 0; | |
373 | if (!warning_printed) | |
374 | { | |
375 | warning (_("\ | |
376 | Skipping deprecated .gdb_index section in %s.\n\ | |
377 | Do \"set use-deprecated-index-sections on\" before the file is read\n\ | |
378 | to use the section anyway."), | |
379 | filename); | |
380 | warning_printed = 1; | |
381 | } | |
382 | return 0; | |
383 | } | |
384 | /* Version 7 indices generated by gold refer to the CU for a symbol instead | |
385 | of the TU (for symbols coming from TUs), | |
386 | http://sourceware.org/bugzilla/show_bug.cgi?id=15021. | |
387 | Plus gold-generated indices can have duplicate entries for global symbols, | |
388 | http://sourceware.org/bugzilla/show_bug.cgi?id=15646. | |
389 | These are just performance bugs, and we can't distinguish gdb-generated | |
390 | indices from gold-generated ones, so issue no warning here. */ | |
391 | ||
392 | /* Indexes with higher version than the one supported by GDB may be no | |
393 | longer backward compatible. */ | |
8b9c08ed | 394 | if (version > 9) |
be932484 SM |
395 | return 0; |
396 | ||
397 | map->version = version; | |
398 | ||
399 | int i = 1; | |
400 | *cu_list = addr + metadata[i]; | |
401 | *cu_list_elements = (metadata[i + 1] - metadata[i]) / 8; | |
402 | ++i; | |
403 | ||
404 | *types_list = addr + metadata[i]; | |
405 | *types_list_elements = (metadata[i + 1] - metadata[i]) / 8; | |
406 | ++i; | |
407 | ||
408 | const gdb_byte *address_table = addr + metadata[i]; | |
409 | const gdb_byte *address_table_end = addr + metadata[i + 1]; | |
410 | map->address_table | |
411 | = gdb::array_view<const gdb_byte> (address_table, address_table_end); | |
412 | ++i; | |
413 | ||
414 | const gdb_byte *symbol_table = addr + metadata[i]; | |
415 | const gdb_byte *symbol_table_end = addr + metadata[i + 1]; | |
416 | map->symbol_table | |
417 | = offset_view (gdb::array_view<const gdb_byte> (symbol_table, | |
418 | symbol_table_end)); | |
419 | ||
420 | ++i; | |
8b9c08ed MBB |
421 | |
422 | if (version >= 9) | |
423 | { | |
424 | const gdb_byte *shortcut_table = addr + metadata[i]; | |
425 | const gdb_byte *shortcut_table_end = addr + metadata[i + 1]; | |
426 | map->shortcut_table | |
427 | = gdb::array_view<const gdb_byte> (shortcut_table, shortcut_table_end); | |
428 | ++i; | |
429 | } | |
430 | ||
be932484 SM |
431 | map->constant_pool = buffer.slice (metadata[i]); |
432 | ||
433 | if (map->constant_pool.empty () && !map->symbol_table.empty ()) | |
434 | { | |
435 | /* An empty constant pool implies that all symbol table entries are | |
436 | empty. Make map->symbol_table.empty () == true. */ | |
437 | map->symbol_table | |
438 | = offset_view (gdb::array_view<const gdb_byte> (symbol_table, | |
439 | symbol_table)); | |
440 | } | |
441 | ||
442 | return 1; | |
443 | } | |
444 | ||
445 | /* A helper for create_cus_from_gdb_index that handles a given list of | |
446 | CUs. */ | |
447 | ||
448 | static void | |
449 | create_cus_from_gdb_index_list (dwarf2_per_bfd *per_bfd, | |
450 | const gdb_byte *cu_list, offset_type n_elements, | |
451 | struct dwarf2_section_info *section, | |
452 | int is_dwz) | |
453 | { | |
454 | for (offset_type i = 0; i < n_elements; i += 2) | |
455 | { | |
69f6730d | 456 | static_assert (sizeof (ULONGEST) >= 8); |
be932484 SM |
457 | |
458 | sect_offset sect_off | |
459 | = (sect_offset) extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE); | |
460 | ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE); | |
461 | cu_list += 2 * 8; | |
462 | ||
463 | dwarf2_per_cu_data_up per_cu | |
464 | = create_cu_from_index_list (per_bfd, section, is_dwz, sect_off, | |
465 | length); | |
466 | per_bfd->all_units.push_back (std::move (per_cu)); | |
467 | } | |
468 | } | |
469 | ||
470 | /* Read the CU list from the mapped index, and use it to create all | |
471 | the CU objects for PER_BFD. */ | |
472 | ||
473 | static void | |
474 | create_cus_from_gdb_index (dwarf2_per_bfd *per_bfd, | |
475 | const gdb_byte *cu_list, offset_type cu_list_elements, | |
476 | const gdb_byte *dwz_list, offset_type dwz_elements) | |
477 | { | |
478 | gdb_assert (per_bfd->all_units.empty ()); | |
479 | per_bfd->all_units.reserve ((cu_list_elements + dwz_elements) / 2); | |
480 | ||
481 | create_cus_from_gdb_index_list (per_bfd, cu_list, cu_list_elements, | |
482 | &per_bfd->info, 0); | |
483 | ||
484 | if (dwz_elements == 0) | |
485 | return; | |
486 | ||
487 | dwz_file *dwz = dwarf2_get_dwz_file (per_bfd); | |
488 | create_cus_from_gdb_index_list (per_bfd, dwz_list, dwz_elements, | |
489 | &dwz->info, 1); | |
490 | } | |
491 | ||
492 | /* Create the signatured type hash table from the index. */ | |
493 | ||
494 | static void | |
495 | create_signatured_type_table_from_gdb_index | |
496 | (dwarf2_per_bfd *per_bfd, struct dwarf2_section_info *section, | |
497 | const gdb_byte *bytes, offset_type elements) | |
498 | { | |
499 | htab_up sig_types_hash = allocate_signatured_type_table (); | |
500 | ||
501 | for (offset_type i = 0; i < elements; i += 3) | |
502 | { | |
503 | signatured_type_up sig_type; | |
504 | ULONGEST signature; | |
505 | void **slot; | |
506 | cu_offset type_offset_in_tu; | |
507 | ||
69f6730d | 508 | static_assert (sizeof (ULONGEST) >= 8); |
be932484 SM |
509 | sect_offset sect_off |
510 | = (sect_offset) extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); | |
511 | type_offset_in_tu | |
512 | = (cu_offset) extract_unsigned_integer (bytes + 8, 8, | |
513 | BFD_ENDIAN_LITTLE); | |
514 | signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE); | |
515 | bytes += 3 * 8; | |
516 | ||
517 | sig_type = per_bfd->allocate_signatured_type (signature); | |
518 | sig_type->type_offset_in_tu = type_offset_in_tu; | |
519 | sig_type->section = section; | |
520 | sig_type->sect_off = sect_off; | |
521 | ||
522 | slot = htab_find_slot (sig_types_hash.get (), sig_type.get (), INSERT); | |
523 | *slot = sig_type.get (); | |
524 | ||
525 | per_bfd->all_units.emplace_back (sig_type.release ()); | |
526 | } | |
527 | ||
528 | per_bfd->signatured_types = std::move (sig_types_hash); | |
529 | } | |
530 | ||
531 | /* Read the address map data from the mapped GDB index, and use it to | |
532 | populate the index_addrmap. */ | |
533 | ||
534 | static void | |
535 | create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile, | |
536 | mapped_gdb_index *index) | |
537 | { | |
be932484 | 538 | dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; |
be932484 | 539 | const gdb_byte *iter, *end; |
be932484 SM |
540 | |
541 | addrmap_mutable mutable_map; | |
542 | ||
543 | iter = index->address_table.data (); | |
544 | end = iter + index->address_table.size (); | |
545 | ||
be932484 SM |
546 | while (iter < end) |
547 | { | |
548 | ULONGEST hi, lo, cu_index; | |
549 | lo = extract_unsigned_integer (iter, 8, BFD_ENDIAN_LITTLE); | |
550 | iter += 8; | |
551 | hi = extract_unsigned_integer (iter, 8, BFD_ENDIAN_LITTLE); | |
552 | iter += 8; | |
553 | cu_index = extract_unsigned_integer (iter, 4, BFD_ENDIAN_LITTLE); | |
554 | iter += 4; | |
555 | ||
556 | if (lo > hi) | |
557 | { | |
558 | complaint (_(".gdb_index address table has invalid range (%s - %s)"), | |
559 | hex_string (lo), hex_string (hi)); | |
560 | continue; | |
561 | } | |
562 | ||
563 | if (cu_index >= per_bfd->all_units.size ()) | |
564 | { | |
565 | complaint (_(".gdb_index address table has invalid CU number %u"), | |
566 | (unsigned) cu_index); | |
567 | continue; | |
568 | } | |
569 | ||
1e73d09f TT |
570 | lo = (ULONGEST) per_objfile->adjust ((unrelocated_addr) lo); |
571 | hi = (ULONGEST) per_objfile->adjust ((unrelocated_addr) hi); | |
be932484 SM |
572 | mutable_map.set_empty (lo, hi - 1, per_bfd->get_cu (cu_index)); |
573 | } | |
574 | ||
575 | per_bfd->index_addrmap | |
576 | = new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack, &mutable_map); | |
577 | } | |
578 | ||
93845901 | 579 | /* Sets the name and language of the main function from the shortcut table. */ |
8b9c08ed MBB |
580 | |
581 | static void | |
582 | set_main_name_from_gdb_index (dwarf2_per_objfile *per_objfile, | |
583 | mapped_gdb_index *index) | |
584 | { | |
729d0667 | 585 | const auto expected_size = 2 * sizeof (offset_type); |
8b9c08ed MBB |
586 | if (index->shortcut_table.size () < expected_size) |
587 | /* The data in the section is not present, is corrupted or is in a version | |
93845901 | 588 | we don't know about. Regardless, we can't make use of it. */ |
8b9c08ed MBB |
589 | return; |
590 | ||
591 | auto ptr = index->shortcut_table.data (); | |
592 | const auto dw_lang = extract_unsigned_integer (ptr, 4, BFD_ENDIAN_LITTLE); | |
593 | if (dw_lang >= DW_LANG_hi_user) | |
594 | { | |
595 | complaint (_(".gdb_index shortcut table has invalid main language %u"), | |
596 | (unsigned) dw_lang); | |
597 | return; | |
598 | } | |
599 | if (dw_lang == 0) | |
600 | { | |
601 | /* Don't bother if the language for the main symbol was not known or if | |
93845901 | 602 | there was no main symbol at all when the index was built. */ |
8b9c08ed MBB |
603 | return; |
604 | } | |
605 | ptr += 4; | |
606 | ||
607 | const auto lang = dwarf_lang_to_enum_language (dw_lang); | |
608 | const auto name_offset = extract_unsigned_integer (ptr, | |
609 | sizeof (offset_type), | |
610 | BFD_ENDIAN_LITTLE); | |
729d0667 | 611 | const auto name = (const char *) (index->constant_pool.data () + name_offset); |
8b9c08ed MBB |
612 | |
613 | set_objfile_main_name (per_objfile->objfile, name, (enum language) lang); | |
614 | } | |
615 | ||
be932484 SM |
616 | /* See read-gdb-index.h. */ |
617 | ||
618 | int | |
619 | dwarf2_read_gdb_index | |
620 | (dwarf2_per_objfile *per_objfile, | |
621 | get_gdb_index_contents_ftype get_gdb_index_contents, | |
622 | get_gdb_index_contents_dwz_ftype get_gdb_index_contents_dwz) | |
623 | { | |
624 | const gdb_byte *cu_list, *types_list, *dwz_list = NULL; | |
625 | offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0; | |
626 | struct dwz_file *dwz; | |
627 | struct objfile *objfile = per_objfile->objfile; | |
628 | dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; | |
629 | ||
630 | gdb::array_view<const gdb_byte> main_index_contents | |
631 | = get_gdb_index_contents (objfile, per_bfd); | |
632 | ||
633 | if (main_index_contents.empty ()) | |
634 | return 0; | |
635 | ||
6b62451a | 636 | auto map = std::make_unique<mapped_gdb_index> (); |
be932484 SM |
637 | if (!read_gdb_index_from_buffer (objfile_name (objfile), |
638 | use_deprecated_index_sections, | |
639 | main_index_contents, map.get (), &cu_list, | |
640 | &cu_list_elements, &types_list, | |
641 | &types_list_elements)) | |
642 | return 0; | |
643 | ||
644 | /* Don't use the index if it's empty. */ | |
645 | if (map->symbol_table.empty ()) | |
646 | return 0; | |
647 | ||
648 | /* If there is a .dwz file, read it so we can get its CU list as | |
649 | well. */ | |
650 | dwz = dwarf2_get_dwz_file (per_bfd); | |
651 | if (dwz != NULL) | |
652 | { | |
653 | mapped_gdb_index dwz_map; | |
654 | const gdb_byte *dwz_types_ignore; | |
655 | offset_type dwz_types_elements_ignore; | |
656 | ||
657 | gdb::array_view<const gdb_byte> dwz_index_content | |
658 | = get_gdb_index_contents_dwz (objfile, dwz); | |
659 | ||
660 | if (dwz_index_content.empty ()) | |
661 | return 0; | |
662 | ||
663 | if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()), | |
664 | 1, dwz_index_content, &dwz_map, | |
665 | &dwz_list, &dwz_list_elements, | |
666 | &dwz_types_ignore, | |
667 | &dwz_types_elements_ignore)) | |
668 | { | |
669 | warning (_("could not read '.gdb_index' section from %s; skipping"), | |
670 | bfd_get_filename (dwz->dwz_bfd.get ())); | |
671 | return 0; | |
672 | } | |
673 | } | |
674 | ||
675 | create_cus_from_gdb_index (per_bfd, cu_list, cu_list_elements, dwz_list, | |
676 | dwz_list_elements); | |
677 | ||
678 | if (types_list_elements) | |
679 | { | |
680 | /* We can only handle a single .debug_types when we have an | |
681 | index. */ | |
682 | if (per_bfd->types.size () > 1) | |
683 | { | |
684 | per_bfd->all_units.clear (); | |
685 | return 0; | |
686 | } | |
687 | ||
688 | dwarf2_section_info *section | |
689 | = (per_bfd->types.size () == 1 | |
690 | ? &per_bfd->types[0] | |
691 | : &per_bfd->info); | |
692 | ||
693 | create_signatured_type_table_from_gdb_index (per_bfd, section, types_list, | |
694 | types_list_elements); | |
695 | } | |
696 | ||
697 | finalize_all_units (per_bfd); | |
698 | ||
699 | create_addrmap_from_gdb_index (per_objfile, map.get ()); | |
700 | ||
8b9c08ed MBB |
701 | set_main_name_from_gdb_index (per_objfile, map.get ()); |
702 | ||
be932484 SM |
703 | per_bfd->index_table = std::move (map); |
704 | per_bfd->quick_file_names_table = | |
705 | create_quick_file_names_table (per_bfd->all_units.size ()); | |
706 | ||
707 | return 1; | |
708 | } | |
709 | ||
710 | void _initialize_read_gdb_index (); | |
711 | ||
712 | void | |
713 | _initialize_read_gdb_index () | |
714 | { | |
715 | add_setshow_boolean_cmd ("use-deprecated-index-sections", | |
716 | no_class, &use_deprecated_index_sections, _("\ | |
717 | Set whether to use deprecated gdb_index sections."), _("\ | |
718 | Show whether to use deprecated gdb_index sections."), _("\ | |
719 | When enabled, deprecated .gdb_index sections are used anyway.\n\ | |
720 | Normally they are ignored either because of a missing feature or\n\ | |
721 | performance issue.\n\ | |
722 | Warning: This option must be enabled before gdb reads the file."), | |
723 | NULL, | |
724 | NULL, | |
725 | &setlist, &showlist); | |
726 | } |