X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=e0fd56529ca29949662c58bf209e1c2912ca5260;hb=b926417afaea99ed17663e06d6654d0048536017;hp=d16700fb9241ce0e083e01206658314b30361193;hpb=3c3bb0580be0027a1c7187b78c747af74dcfa884;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d16700fb92..e0fd56529c 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -30,6 +30,7 @@ #include "defs.h" #include "dwarf2read.h" +#include "dwarf-index-cache.h" #include "dwarf-index-common.h" #include "bfd.h" #include "elf-bfd.h" @@ -868,6 +869,10 @@ struct dwz_file /* The dwz's BFD. */ gdb_bfd_ref_ptr dwz_bfd; + + /* If we loaded the index from an external file, this contains the + resources associated to the open file, memory mapping, etc. */ + std::unique_ptr index_cache_res; }; /* Struct used to pass misc. parameters to read_die_and_children, et @@ -3177,8 +3182,8 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile, continue; } - lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr); - hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr); + lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr; + hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr; addrmap_set_empty (mutable_map, lo, hi - 1, dwarf2_per_objfile->get_cu (cu_index)); } @@ -3336,8 +3341,10 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, continue; } ULONGEST end = start + length; - start = gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr); - end = gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr); + start = (gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr) + - baseaddr); + end = (gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr) + - baseaddr); addrmap_set_empty (mutable_map, start, end - 1, per_cu); } } @@ -3408,8 +3415,8 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } } -/* A helper function that reads the .gdb_index from SECTION and fills - in MAP. FILENAME is the name of the file containing the section; +/* A helper function that reads the .gdb_index from BUFFER and fills + in MAP. FILENAME is the name of the file containing the data; it is used for error reporting. DEPRECATED_OK is true if it is ok to use deprecated sections. @@ -3417,37 +3424,23 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, 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. */ + Returns true if all went well, false otherwise. */ static bool -read_gdb_index_from_section (struct objfile *objfile, - const char *filename, - bool 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) -{ - const gdb_byte *addr; - offset_type version; - offset_type *metadata; - int i; - - 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 ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0) - return 0; - - dwarf2_read_section (objfile, section); +read_gdb_index_from_buffer (struct objfile *objfile, + const char *filename, + bool deprecated_ok, + gdb::array_view buffer, + struct mapped_index *map, + const gdb_byte **cu_list, + offset_type *cu_list_elements, + const gdb_byte **types_list, + offset_type *types_list_elements) +{ + const gdb_byte *addr = &buffer[0]; - addr = section->buffer; /* Version check. */ - version = MAYBE_SWAP (*(offset_type *) addr); + offset_type version = MAYBE_SWAP (*(offset_type *) addr); /* Versions earlier than 3 emitted every copy of a psymbol. This causes the index to behave very poorly for certain requests. Version 3 contained incomplete addrmap. So, it seems better to just ignore such @@ -3500,9 +3493,9 @@ to use the section anyway."), map->version = version; - metadata = (offset_type *) (addr + sizeof (offset_type)); + offset_type *metadata = (offset_type *) (addr + sizeof (offset_type)); - i = 0; + int i = 0; *cu_list = addr + MAYBE_SWAP (metadata[i]); *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i])) / 8); @@ -3533,23 +3526,41 @@ to use the section anyway."), return 1; } +/* Callback types for dwarf2_read_gdb_index. */ + +typedef gdb::function_view + (objfile *, dwarf2_per_objfile *)> + get_gdb_index_contents_ftype; +typedef gdb::function_view + (objfile *, dwz_file *)> + get_gdb_index_contents_dwz_ftype; + /* Read .gdb_index. If everything went ok, initialize the "quick" elements of all the CUs and return 1. Otherwise, return 0. */ static int -dwarf2_read_gdb_index (struct dwarf2_per_objfile *dwarf2_per_objfile) +dwarf2_read_gdb_index + (struct dwarf2_per_objfile *dwarf2_per_objfile, + get_gdb_index_contents_ftype get_gdb_index_contents, + get_gdb_index_contents_dwz_ftype get_gdb_index_contents_dwz) { const gdb_byte *cu_list, *types_list, *dwz_list = NULL; offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0; struct dwz_file *dwz; struct objfile *objfile = dwarf2_per_objfile->objfile; + gdb::array_view main_index_contents + = get_gdb_index_contents (objfile, dwarf2_per_objfile); + + if (main_index_contents.empty ()) + return 0; + std::unique_ptr map (new struct mapped_index); - if (!read_gdb_index_from_section (objfile, objfile_name (objfile), - use_deprecated_index_sections, - &dwarf2_per_objfile->gdb_index, map.get (), - &cu_list, &cu_list_elements, - &types_list, &types_list_elements)) + if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile), + use_deprecated_index_sections, + main_index_contents, map.get (), &cu_list, + &cu_list_elements, &types_list, + &types_list_elements)) return 0; /* Don't use the index if it's empty. */ @@ -3565,12 +3576,18 @@ dwarf2_read_gdb_index (struct dwarf2_per_objfile *dwarf2_per_objfile) const gdb_byte *dwz_types_ignore; offset_type dwz_types_elements_ignore; - if (!read_gdb_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)) + gdb::array_view dwz_index_content + = get_gdb_index_contents_dwz (objfile, dwz); + + if (dwz_index_content.empty ()) + return 0; + + if (!read_gdb_index_from_buffer (objfile, + bfd_get_filename (dwz->dwz_bfd), 1, + dwz_index_content, &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)); @@ -4098,14 +4115,6 @@ dw2_dump (struct objfile *objfile) printf_filtered ("\n"); } -static void -dw2_relocate (struct objfile *objfile, - const struct section_offsets *new_offsets, - const struct section_offsets *delta) -{ - /* There's nothing to relocate here. */ -} - static void dw2_expand_symtabs_for_function (struct objfile *objfile, const char *func_name) @@ -5237,8 +5246,10 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile, if (!objfile->psymtabs_addrmap) return NULL; + CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap, - pc); + pc - baseaddr); if (!data) return NULL; @@ -5336,7 +5347,6 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions = dw2_lookup_symbol, dw2_print_stats, dw2_dump, - dw2_relocate, dw2_expand_symtabs_for_function, dw2_expand_all_symtabs, dw2_expand_symtabs_with_fullname, @@ -5487,7 +5497,6 @@ read_debug_names_from_section (struct objfile *objfile, const gdb_byte *abbrev_table_start = addr; for (;;) { - unsigned int bytes_read; const ULONGEST index_num = read_unsigned_leb128 (abfd, addr, &bytes_read); addr += bytes_read; if (index_num == 0) @@ -6149,7 +6158,6 @@ const struct quick_symbol_functions dwarf2_debug_names_functions = dw2_debug_names_lookup_symbol, dw2_print_stats, dw2_debug_names_dump, - dw2_relocate, dw2_debug_names_expand_symtabs_for_function, dw2_expand_all_symtabs, dw2_expand_symtabs_with_fullname, @@ -6160,6 +6168,54 @@ const struct quick_symbol_functions dwarf2_debug_names_functions = dw2_map_symbol_filenames }; +/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point + to either a dwarf2_per_objfile or dwz_file object. */ + +template +static gdb::array_view +get_gdb_index_contents_from_section (objfile *obj, T *section_owner) +{ + dwarf2_section_info *section = §ion_owner->gdb_index; + + if (dwarf2_section_empty_p (section)) + return {}; + + /* Older elfutils strip versions could keep the section in the main + executable while splitting it for the separate debug info file. */ + if ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0) + return {}; + + dwarf2_read_section (obj, section); + + return {section->buffer, section->size}; +} + +/* Lookup the index cache for the contents of the index associated to + DWARF2_OBJ. */ + +static gdb::array_view +get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj) +{ + const bfd_build_id *build_id = build_id_bfd_get (obj->obfd); + if (build_id == nullptr) + return {}; + + return global_index_cache.lookup_gdb_index (build_id, + &dwarf2_obj->index_cache_res); +} + +/* Same as the above, but for DWZ. */ + +static gdb::array_view +get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz) +{ + const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); + if (build_id == nullptr) + return {}; + + return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res); +} + /* See symfile.h. */ bool @@ -6203,12 +6259,25 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind) return true; } - if (dwarf2_read_gdb_index (dwarf2_per_objfile)) + if (dwarf2_read_gdb_index (dwarf2_per_objfile, + get_gdb_index_contents_from_section, + get_gdb_index_contents_from_section)) + { + *index_kind = dw_index_kind::GDB_INDEX; + return true; + } + + /* ... otherwise, try to find the index in the index cache. */ + if (dwarf2_read_gdb_index (dwarf2_per_objfile, + get_gdb_index_contents_from_cache, + get_gdb_index_contents_from_cache_dwz)) { + global_index_cache.hit (); *index_kind = dw_index_kind::GDB_INDEX; return true; } + global_index_cache.miss (); return false; } @@ -6234,6 +6303,9 @@ dwarf2_build_psymtabs (struct objfile *objfile) psymtab_discarder psymtabs (objfile); dwarf2_build_psymtabs_hard (dwarf2_per_objfile); psymtabs.keep (); + + /* (maybe) store an index in the cache. */ + global_index_cache.store (dwarf2_per_objfile); } CATCH (except, RETURN_MASK_ERROR) { @@ -6507,9 +6579,6 @@ dwarf2_create_include_psymtab (const char *name, struct partial_symtab *pst, subpst->dirname = pst->dirname; } - subpst->textlow = 0; - subpst->texthigh = 0; - subpst->dependencies = XOBNEW (&objfile->objfile_obstack, struct partial_symtab *); subpst->dependencies[0] = pst; @@ -6547,8 +6616,12 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, if (lh == NULL) return; /* No linetable, so no includes. */ - /* NOTE: pst->dirname is DW_AT_comp_dir (if present). */ - dwarf_decode_lines (lh.get (), pst->dirname, cu, pst, pst->textlow, 1); + /* NOTE: pst->dirname is DW_AT_comp_dir (if present). Also note + that we pass in the raw text_low here; that is ok because we're + only decoding the line table to make include partial symtabs, and + so the addresses aren't really used. */ + dwarf_decode_lines (lh.get (), pst->dirname, cu, pst, + pst->raw_text_low (), 1); } static hashval_t @@ -7762,19 +7835,17 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct) { unsigned int line_offset = to_underlying (line_offset_struct); struct partial_symtab *pst; - char *name; + std::string name; /* Give the symtab a useful name for debug purposes. */ if ((line_offset & NO_STMT_LIST_TYPE_UNIT_PSYMTAB) != 0) - name = xstrprintf ("", - (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB)); + name = string_printf ("", + (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB)); else - name = xstrprintf ("", line_offset); + name = string_printf ("", line_offset); - pst = create_partial_symtab (per_cu, name); + pst = create_partial_symtab (per_cu, name.c_str ()); pst->anonymous = 1; - - xfree (name); } tu_group->hash.dwo_unit = cu->dwo_unit; @@ -7932,14 +8003,17 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, cu_bounds_kind = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, &best_highpc, cu, pst); if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc) - /* Store the contiguous range if it is not empty; it can be empty for - CUs with no code. */ - addrmap_set_empty (objfile->psymtabs_addrmap, - gdbarch_adjust_dwarf2_addr (gdbarch, - best_lowpc + baseaddr), - gdbarch_adjust_dwarf2_addr (gdbarch, - best_highpc + baseaddr) - 1, - pst); + { + CORE_ADDR low + = (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr) + - baseaddr); + CORE_ADDR high + = (gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr) + - baseaddr - 1); + /* Store the contiguous range if it is not empty; it can be + empty for CUs with no code. */ + addrmap_set_empty (objfile->psymtabs_addrmap, low, high, pst); + } /* Check if comp unit has_children. If so, read the rest of the partial symbols from this comp unit. @@ -7970,8 +8044,12 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, best_highpc = highpc; } } - pst->textlow = gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr); - pst->texthigh = gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr); + pst->set_text_low (gdbarch_adjust_dwarf2_addr (gdbarch, + best_lowpc + baseaddr) + - baseaddr); + pst->set_text_high (gdbarch_adjust_dwarf2_addr (gdbarch, + best_highpc + baseaddr) + - baseaddr); end_psymtab_common (objfile, pst); @@ -8000,18 +8078,14 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, dwarf2_build_include_psymtabs (cu, comp_unit_die, pst); if (dwarf_read_debug) - { - struct gdbarch *gdbarch = get_objfile_arch (objfile); - - fprintf_unfiltered (gdb_stdlog, - "Psymtab for %s unit @%s: %s - %s" - ", %d global, %d static syms\n", - per_cu->is_debug_types ? "type" : "comp", - sect_offset_str (per_cu->sect_off), - paddress (gdbarch, pst->textlow), - paddress (gdbarch, pst->texthigh), - pst->n_global_syms, pst->n_static_syms); - } + fprintf_unfiltered (gdb_stdlog, + "Psymtab for %s unit @%s: %s - %s" + ", %d global, %d static syms\n", + per_cu->is_debug_types ? "type" : "comp", + sect_offset_str (per_cu->sect_off), + paddress (gdbarch, pst->text_low (objfile)), + paddress (gdbarch, pst->text_high (objfile)), + pst->n_global_syms, pst->n_static_syms); } /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. @@ -8802,7 +8876,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) { case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: - addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr); + addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr) + - baseaddr); if (pdi->is_external || cu->language == language_ada) { /* brobecker/2007-12-26: Normally, only "external" DIEs are part @@ -8812,14 +8887,17 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, VAR_DOMAIN, LOC_BLOCK, + SECT_OFF_TEXT (objfile), &objfile->global_psymbols, - addr, cu->language, objfile); + addr, + cu->language, objfile); } else { add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, VAR_DOMAIN, LOC_BLOCK, + SECT_OFF_TEXT (objfile), &objfile->static_psymbols, addr, cu->language, objfile); } @@ -8837,7 +8915,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) list = &objfile->static_psymbols; add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, - list, 0, cu->language, objfile); + -1, list, 0, cu->language, objfile); } break; case DW_TAG_variable: @@ -8872,9 +8950,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, + SECT_OFF_TEXT (objfile), &objfile->global_psymbols, - addr + baseaddr, - cu->language, objfile); + addr, cu->language, objfile); } else { @@ -8891,8 +8969,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, + SECT_OFF_TEXT (objfile), &objfile->static_psymbols, - has_loc ? addr + baseaddr : (CORE_ADDR) 0, + has_loc ? addr : 0, cu->language, objfile); } break; @@ -8901,7 +8980,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) case DW_TAG_subrange_type: add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, - VAR_DOMAIN, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, -1, &objfile->static_psymbols, 0, cu->language, objfile); break; @@ -8909,14 +8988,14 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) case DW_TAG_namespace: add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, - VAR_DOMAIN, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, -1, &objfile->global_psymbols, 0, cu->language, objfile); break; case DW_TAG_module: add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, - MODULE_DOMAIN, LOC_TYPEDEF, + MODULE_DOMAIN, LOC_TYPEDEF, -1, &objfile->global_psymbols, 0, cu->language, objfile); break; @@ -8940,7 +9019,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) static vs. global. */ add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, - STRUCT_DOMAIN, LOC_TYPEDEF, + STRUCT_DOMAIN, LOC_TYPEDEF, -1, cu->language == language_cplus ? &objfile->global_psymbols : &objfile->static_psymbols, @@ -8950,7 +9029,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) case DW_TAG_enumerator: add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name != NULL, - VAR_DOMAIN, LOC_CONST, + VAR_DOMAIN, LOC_CONST, -1, cu->language == language_cplus ? &objfile->global_psymbols : &objfile->static_psymbols, @@ -9028,16 +9107,21 @@ add_partial_subprogram (struct partial_die_info *pdi, struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; struct gdbarch *gdbarch = get_objfile_arch (objfile); CORE_ADDR baseaddr; - CORE_ADDR highpc; - CORE_ADDR lowpc; + CORE_ADDR this_highpc; + CORE_ADDR this_lowpc; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, - pdi->lowpc + baseaddr); - highpc = gdbarch_adjust_dwarf2_addr (gdbarch, - pdi->highpc + baseaddr); - addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1, + this_lowpc + = (gdbarch_adjust_dwarf2_addr (gdbarch, + pdi->lowpc + baseaddr) + - baseaddr); + this_highpc + = (gdbarch_adjust_dwarf2_addr (gdbarch, + pdi->highpc + baseaddr) + - baseaddr); + addrmap_set_empty (objfile->psymtabs_addrmap, + this_lowpc, this_highpc - 1, cu->per_cu->v.psymtab); } } @@ -13744,6 +13828,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) memcpy (templ_func->template_arguments, template_args.data (), (templ_func->n_template_arguments * sizeof (struct symbol *))); + + /* Make sure that the symtab is set on the new symbols. Even + though they don't appear in this symtab directly, other parts + of gdb assume that symbols do, and this is reasonably + true. */ + for (symbol *sym : template_args) + symbol_set_symtab (sym, symbol_symtab (templ_func)); } /* In C++, we can have functions nested inside functions (e.g., when @@ -14190,7 +14281,22 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu) } } - new_symbol (die, NULL, cu, storage); + struct symbol *res = new_symbol (die, NULL, cu, storage); + struct attribute *abstract_origin + = dwarf2_attr (die, DW_AT_abstract_origin, cu); + struct attribute *loc = dwarf2_attr (die, DW_AT_location, cu); + if (res == NULL && loc && abstract_origin) + { + /* We have a variable without a name, but with a location and an abstract + origin. This may be a concrete instance of an abstract variable + referenced from an DW_OP_GNU_variable_value, so save it to find it back + later. */ + struct dwarf2_cu *origin_cu = cu; + struct die_info *origin_die + = follow_die_ref (die, abstract_origin, &origin_cu); + dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile; + dpo->abstract_to_concrete[origin_die].push_back (die); + } } /* Call CALLBACK from DW_AT_ranges attribute value OFFSET @@ -14489,10 +14595,12 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, CORE_ADDR lowpc; CORE_ADDR highpc; - lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, - range_beginning + baseaddr); - highpc = gdbarch_adjust_dwarf2_addr (gdbarch, - range_end + baseaddr); + lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch, + range_beginning + baseaddr) + - baseaddr); + highpc = (gdbarch_adjust_dwarf2_addr (gdbarch, + range_end + baseaddr) + - baseaddr); addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1, ranges_pst); } @@ -14751,6 +14859,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, unsigned long offset = (DW_UNSND (attr) + (need_ranges_base ? cu->ranges_base : 0)); + std::vector blockvec; dwarf2_ranges_process (offset, cu, [&] (CORE_ADDR start, CORE_ADDR end) { @@ -14759,7 +14868,10 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, start = gdbarch_adjust_dwarf2_addr (gdbarch, start); end = gdbarch_adjust_dwarf2_addr (gdbarch, end); cu->builder->record_block_range (block, start, end - 1); + blockvec.emplace_back (start, end); }); + + BLOCK_RANGES(block) = make_blockranges (objfile, blockvec); } } @@ -15070,6 +15182,18 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, fp->type = get_die_type (die, cu); fp->artificial = 1; fp->name = "<>"; + + /* Normally a DW_TAG_variant_part won't have a size, but our + representation requires one, so set it to the maximum of the + child sizes. */ + if (TYPE_LENGTH (fp->type) == 0) + { + unsigned max = 0; + for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i) + if (TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)) > max) + max = TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)); + TYPE_LENGTH (fp->type) = max; + } } else gdb_assert_not_reached ("missing case in dwarf2_add_field"); @@ -15862,6 +15986,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) discriminant_info. */ bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type); sect_offset discr_offset; + bool has_template_parameters = false; if (is_variant_part) { @@ -15909,6 +16034,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) /* Attach template arguments to type. */ if (!template_args.empty ()) { + has_template_parameters = true; ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_N_TEMPLATE_ARGUMENTS (type) = template_args.size (); TYPE_TEMPLATE_ARGUMENTS (type) @@ -16058,7 +16184,20 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) attribute, and a declaration attribute. */ if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL || !die_is_declaration (die, cu)) - new_symbol (die, type, cu); + { + struct symbol *sym = new_symbol (die, type, cu); + + if (has_template_parameters) + { + /* Make sure that the symtab is set on the new symbols. + Even though they don't appear in this symtab directly, + other parts of gdb assume that symbols do, and this is + reasonably true. */ + for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i) + symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i), + symbol_symtab (sym)); + } + } } /* Assuming DIE is an enumeration type, and TYPE is its associated type, @@ -17568,7 +17707,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) int low_default_is_valid; int high_bound_is_count = 0; const char *name; - LONGEST negative_mask; + ULONGEST negative_mask; orig_base_type = die_type (die, cu); /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED, @@ -17701,7 +17840,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) the bounds as signed, and thus sign-extend their values, when the base type is signed. */ negative_mask = - -((LONGEST) 1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1)); + -((ULONGEST) 1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1)); if (low.kind == PROP_CONST && !TYPE_UNSIGNED (base_type) && (low.data.const_val & negative_mask)) low.data.const_val |= negative_mask; @@ -18253,7 +18392,7 @@ load_partial_dies (const struct die_reader_specs *reader, { if (building_psymtab && pdi.name != NULL) add_psymbol_to_list (pdi.name, strlen (pdi.name), 0, - VAR_DOMAIN, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, -1, &objfile->static_psymbols, 0, cu->language, objfile); info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr); @@ -18287,7 +18426,7 @@ load_partial_dies (const struct die_reader_specs *reader, complaint (_("malformed enumerator DIE ignored")); else if (building_psymtab) add_psymbol_to_list (pdi.name, strlen (pdi.name), 0, - VAR_DOMAIN, LOC_CONST, + VAR_DOMAIN, LOC_CONST, -1, cu->language == language_cplus ? &objfile->global_psymbols : &objfile->static_psymbols, @@ -19486,7 +19625,7 @@ static LONGEST read_signed_leb128 (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read_ptr) { - LONGEST result; + ULONGEST result; int shift, num_read; unsigned char byte; @@ -19498,7 +19637,7 @@ read_signed_leb128 (bfd *abfd, const gdb_byte *buf, byte = bfd_get_8 (abfd, buf); buf++; num_read++; - result |= ((LONGEST) (byte & 127) << shift); + result |= ((ULONGEST) (byte & 127) << shift); shift += 7; if ((byte & 128) == 0) { @@ -19506,7 +19645,7 @@ read_signed_leb128 (bfd *abfd, const gdb_byte *buf, } } if ((shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -(((LONGEST) 1) << shift); + result |= -(((ULONGEST) 1) << shift); *bytes_read_ptr = num_read; return result; } @@ -20198,21 +20337,21 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) /* Read directory table. */ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (), &cu->header, - [] (struct line_header *lh, const char *name, + [] (struct line_header *header, const char *name, dir_index d_index, unsigned int mod_time, unsigned int length) { - lh->add_include_dir (name); + header->add_include_dir (name); }); /* Read file name table. */ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (), &cu->header, - [] (struct line_header *lh, const char *name, + [] (struct line_header *header, const char *name, dir_index d_index, unsigned int mod_time, unsigned int length) { - lh->add_file_name (name, d_index, mod_time, length); + header->add_file_name (name, d_index, mod_time, length); }); } else @@ -21811,15 +21950,15 @@ build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die) struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_cu->dwarf2_per_objfile; struct objfile *objfile = dwarf2_per_objfile->objfile; - char *message, *saved; + char *saved; - message = xstrprintf (_(""), - objfile_name (objfile), - sect_offset_str (cu->header.sect_off), - sect_offset_str (die->sect_off)); + std::string message + = string_printf (_(""), + objfile_name (objfile), + sect_offset_str (cu->header.sect_off), + sect_offset_str (die->sect_off)); saved = (char *) obstack_copy0 (&objfile->objfile_obstack, - message, strlen (message)); - xfree (message); + message.c_str (), message.length ()); return init_type (objfile, TYPE_CODE_ERROR, 0, saved); } @@ -22884,7 +23023,7 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, struct dwarf2_per_cu_data *per_cu, CORE_ADDR (*get_frame_pc) (void *baton), - void *baton) + void *baton, bool resolve_abstract_p) { struct dwarf2_cu *cu; struct die_info *die; @@ -22910,6 +23049,30 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, sect_offset_str (sect_off), objfile_name (objfile)); attr = dwarf2_attr (die, DW_AT_location, cu); + if (!attr && resolve_abstract_p + && (dwarf2_per_objfile->abstract_to_concrete.find (die) + != dwarf2_per_objfile->abstract_to_concrete.end ())) + { + CORE_ADDR pc = (*get_frame_pc) (baton); + + for (const auto &cand : dwarf2_per_objfile->abstract_to_concrete[die]) + { + if (!cand->parent + || cand->parent->tag != DW_TAG_subprogram) + continue; + + CORE_ADDR pc_low, pc_high; + get_scope_pc_bounds (cand->parent, &pc_low, &pc_high, cu); + if (pc_low == ((CORE_ADDR) -1) + || !(pc_low <= pc && pc < pc_high)) + continue; + + die = cand; + attr = dwarf2_attr (die, DW_AT_location, cu); + break; + } + } + if (!attr) { /* DWARF: "If there is no such attribute, then there is no effect.".