From 2ec9a5e0e2bbfb25896dbc4fe3c6230ef62c9b6f Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 18 Jul 2012 20:01:27 +0000 Subject: [PATCH] * dwarf2read.c (struct dwz_file) : New field. (locate_dwz_sections): Recognize .gdb_index. (create_cus_from_index_list): New function. (create_cus_from_index): Use it. Handle .dwz data. (read_index_from_section): New function, extracted from dwarf2_read_index. (dwarf2_read_index): Use it. Read .gdb_index from dwz file, if needed. --- gdb/ChangeLog | 11 ++++ gdb/dwarf2read.c | 173 +++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 142 insertions(+), 42 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a182ac2..b593f20 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2012-07-18 Tom Tromey + * dwarf2read.c (struct dwz_file) : New field. + (locate_dwz_sections): Recognize .gdb_index. + (create_cus_from_index_list): New function. + (create_cus_from_index): Use it. Handle .dwz data. + (read_index_from_section): New function, extracted from + dwarf2_read_index. + (dwarf2_read_index): Use it. Read .gdb_index from dwz file, + if needed. + +2012-07-18 Tom Tromey + * dwarf2read.c (struct dwarf2_per_objfile) : New field. (struct dwarf2_per_cu_data) : No longer bitfield. : New field. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index ee25219..3aa5eef 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -716,6 +716,7 @@ struct dwz_file struct dwarf2_section_info str; struct dwarf2_section_info line; struct dwarf2_section_info macro; + struct dwarf2_section_info gdb_index; /* The dwz's BFD. */ bfd *dwz_bfd; @@ -1953,6 +1954,11 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg) dwz_file->macro.asection = sectp; dwz_file->macro.size = bfd_get_section_size (sectp); } + else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index)) + { + dwz_file->gdb_index.asection = sectp; + dwz_file->gdb_index.size = bfd_get_section_size (sectp); + } } /* Open the separate '.dwz' debug file, if needed. Error if the file @@ -2289,23 +2295,19 @@ extract_cu_value (const char *bytes, ULONGEST *result) return 1; } -/* Read the CU list from the mapped index, and use it to create all - the CU objects for this objfile. Return 0 if something went wrong, - 1 if everything went ok. */ +/* A helper for create_cus_from_index that handles a given list of + CUs. */ static int -create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list, - offset_type cu_list_elements) +create_cus_from_index_list (struct objfile *objfile, + const gdb_byte *cu_list, offset_type n_elements, + struct dwarf2_section_info *section, + int is_dwz, + int base_offset) { offset_type i; - dwarf2_per_objfile->n_comp_units = cu_list_elements / 2; - dwarf2_per_objfile->all_comp_units - = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_comp_units - * sizeof (struct dwarf2_per_cu_data *)); - - for (i = 0; i < cu_list_elements; i += 2) + for (i = 0; i < n_elements; i += 2) { struct dwarf2_per_cu_data *the_cu; ULONGEST offset, length; @@ -2320,15 +2322,45 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list, the_cu->offset.sect_off = offset; the_cu->length = length; the_cu->objfile = objfile; - the_cu->info_or_types_section = &dwarf2_per_objfile->info; + the_cu->info_or_types_section = section; the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwarf2_per_cu_quick_data); - dwarf2_per_objfile->all_comp_units[i / 2] = the_cu; + the_cu->is_dwz = is_dwz; + dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu; } return 1; } +/* Read the CU list from the mapped index, and use it to create all + the CU objects for this objfile. Return 0 if something went wrong, + 1 if everything went ok. */ + +static int +create_cus_from_index (struct objfile *objfile, + const gdb_byte *cu_list, offset_type cu_list_elements, + const gdb_byte *dwz_list, offset_type dwz_elements) +{ + struct dwz_file *dwz; + + dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2; + dwarf2_per_objfile->all_comp_units + = obstack_alloc (&objfile->objfile_obstack, + dwarf2_per_objfile->n_comp_units + * sizeof (struct dwarf2_per_cu_data *)); + + if (!create_cus_from_index_list (objfile, cu_list, cu_list_elements, + &dwarf2_per_objfile->info, 0, 0)) + return 0; + + if (dwz_elements == 0) + return 1; + + dwz = dwarf2_get_dwz_file (); + return create_cus_from_index_list (objfile, dwz_list, dwz_elements, + &dwz->info, 1, cu_list_elements / 2); +} + /* Create the signatured type hash table from the index. */ static int @@ -2518,33 +2550,44 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } } -/* Read the index file. If everything went ok, initialize the "quick" - elements of all the CUs and return 1. Otherwise, return 0. */ +/* A helper function that reads the .gdb_index from SECTION and fills + in MAP. FILENAME is the name of the file containing the section; + it is used for error reporting. DEPRECATED_OK is nonzero if it is + ok to use deprecated sections. + + CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are + out parameters that are filled in with information about the CU and + TU lists in the section. + + Returns 1 if all went well, 0 otherwise. */ static int -dwarf2_read_index (struct objfile *objfile) +read_index_from_section (struct objfile *objfile, + const char *filename, + int deprecated_ok, + struct dwarf2_section_info *section, + struct mapped_index *map, + const gdb_byte **cu_list, + offset_type *cu_list_elements, + const gdb_byte **types_list, + offset_type *types_list_elements) { char *addr; - struct mapped_index *map; + offset_type version; offset_type *metadata; - const gdb_byte *cu_list; - const gdb_byte *types_list = NULL; - offset_type version, cu_list_elements; - offset_type types_list_elements = 0; int i; - if (dwarf2_section_empty_p (&dwarf2_per_objfile->gdb_index)) + if (dwarf2_section_empty_p (section)) return 0; /* Older elfutils strip versions could keep the section in the main executable while splitting it for the separate debug info file. */ - if ((bfd_get_file_flags (dwarf2_per_objfile->gdb_index.asection) - & SEC_HAS_CONTENTS) == 0) + if ((bfd_get_file_flags (section->asection) & SEC_HAS_CONTENTS) == 0) return 0; - dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index); + dwarf2_read_section (objfile, section); - addr = dwarf2_per_objfile->gdb_index.buffer; + addr = section->buffer; /* Version check. */ version = MAYBE_SWAP (*(offset_type *) addr); /* Versions earlier than 3 emitted every copy of a psymbol. This @@ -2557,7 +2600,7 @@ dwarf2_read_index (struct objfile *objfile) if (!warning_printed) { warning (_("Skipping obsolete .gdb_index section in %s."), - objfile->name); + filename); warning_printed = 1; } return 0; @@ -2570,14 +2613,14 @@ dwarf2_read_index (struct objfile *objfile) set breakpoints on inlined functions by name, so we ignore these indices unless the --use-deprecated-index-sections command line option was supplied. */ - if (version < 6 && !use_deprecated_index_sections) + if (version < 6 && !deprecated_ok) { static int warning_printed = 0; if (!warning_printed) { warning (_("Skipping deprecated .gdb_index section in %s, pass " "--use-deprecated-index-sections to use them anyway"), - objfile->name); + filename); warning_printed = 1; } return 0; @@ -2587,22 +2630,21 @@ dwarf2_read_index (struct objfile *objfile) if (version > 7) return 0; - map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index); map->version = version; - map->total_size = dwarf2_per_objfile->gdb_index.size; + map->total_size = section->size; metadata = (offset_type *) (addr + sizeof (offset_type)); i = 0; - cu_list = addr + MAYBE_SWAP (metadata[i]); - cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i])) - / 8); + *cu_list = addr + MAYBE_SWAP (metadata[i]); + *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i])) + / 8); ++i; - types_list = addr + MAYBE_SWAP (metadata[i]); - types_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - - MAYBE_SWAP (metadata[i])) - / 8); + *types_list = addr + MAYBE_SWAP (metadata[i]); + *types_list_elements = ((MAYBE_SWAP (metadata[i + 1]) + - MAYBE_SWAP (metadata[i])) + / 8); ++i; map->address_table = addr + MAYBE_SWAP (metadata[i]); @@ -2618,11 +2660,55 @@ dwarf2_read_index (struct objfile *objfile) map->constant_pool = addr + MAYBE_SWAP (metadata[i]); + return 1; +} + + +/* Read the index file. If everything went ok, initialize the "quick" + elements of all the CUs and return 1. Otherwise, return 0. */ + +static int +dwarf2_read_index (struct objfile *objfile) +{ + struct mapped_index local_map, *map; + const gdb_byte *cu_list, *types_list, *dwz_list = NULL; + offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0; + + if (!read_index_from_section (objfile, objfile->name, + use_deprecated_index_sections, + &dwarf2_per_objfile->gdb_index, &local_map, + &cu_list, &cu_list_elements, + &types_list, &types_list_elements)) + return 0; + /* Don't use the index if it's empty. */ - if (map->symbol_table_slots == 0) + if (local_map.symbol_table_slots == 0) return 0; - if (!create_cus_from_index (objfile, cu_list, cu_list_elements)) + /* If there is a .dwz file, read it so we can get its CU list as + well. */ + if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL) + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + struct mapped_index dwz_map; + const gdb_byte *dwz_types_ignore; + offset_type dwz_types_elements_ignore; + + if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd), + 1, + &dwz->gdb_index, &dwz_map, + &dwz_list, &dwz_list_elements, + &dwz_types_ignore, + &dwz_types_elements_ignore)) + { + warning (_("could not read '.gdb_index' section from %s; skipping"), + bfd_get_filename (dwz->dwz_bfd)); + return 0; + } + } + + if (!create_cus_from_index (objfile, cu_list, cu_list_elements, + dwz_list, dwz_list_elements)) return 0; if (types_list_elements) @@ -2643,7 +2729,10 @@ dwarf2_read_index (struct objfile *objfile) return 0; } - create_addrmap_from_index (objfile, map); + create_addrmap_from_index (objfile, &local_map); + + map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index)); + *map = local_map; dwarf2_per_objfile->index_table = map; dwarf2_per_objfile->using_index = 1; -- 2.7.4