#include "defs.h"
#include "dwarf2read.h"
+#include "dwarf-index-cache.h"
#include "dwarf-index-common.h"
#include "bfd.h"
#include "elf-bfd.h"
unsigned int producer_is_gxx_lt_4_6 : 1;
unsigned int producer_is_gcc_lt_4_3 : 1;
unsigned int producer_is_icc_lt_14 : 1;
+ bool producer_is_codewarrior : 1;
/* When set, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
/* 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_resource> index_cache_res;
};
/* Struct used to pass misc. parameters to read_die_and_children, et
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));
}
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);
}
}
}
}
-/* 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.
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<const gdb_byte> 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
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);
return 1;
}
+/* Callback types for dwarf2_read_gdb_index. */
+
+typedef gdb::function_view
+ <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_objfile *)>
+ get_gdb_index_contents_ftype;
+typedef gdb::function_view
+ <gdb::array_view<const gdb_byte>(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<const gdb_byte> main_index_contents
+ = get_gdb_index_contents (objfile, dwarf2_per_objfile);
+
+ if (main_index_contents.empty ())
+ return 0;
+
std::unique_ptr<struct mapped_index> 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. */
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<const gdb_byte> 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));
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)
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;
dw2_lookup_symbol,
dw2_print_stats,
dw2_dump,
- dw2_relocate,
dw2_expand_symtabs_for_function,
dw2_expand_all_symtabs,
dw2_expand_symtabs_with_fullname,
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)
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,
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 <typename T>
+static gdb::array_view<const gdb_byte>
+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<const gdb_byte>
+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<const gdb_byte>
+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
return true;
}
- if (dwarf2_read_gdb_index (dwarf2_per_objfile))
+ if (dwarf2_read_gdb_index (dwarf2_per_objfile,
+ get_gdb_index_contents_from_section<struct dwarf2_per_objfile>,
+ get_gdb_index_contents_from_section<dwz_file>))
{
*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;
}
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)
{
if (lh == NULL)
return; /* No linetable, so no includes. */
- /* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
+ /* 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->text_low (), 1);
+ pst->raw_text_low (), 1);
}
static hashval_t
{
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 ("<type_units_%d>",
- (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB));
+ name = string_printf ("<type_units_%d>",
+ (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB));
else
- name = xstrprintf ("<type_units_at_0x%x>", line_offset);
+ name = string_printf ("<type_units_at_0x%x>", 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;
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.
}
}
pst->set_text_low (gdbarch_adjust_dwarf2_addr (gdbarch,
- best_lowpc + baseaddr));
+ best_lowpc + baseaddr)
+ - baseaddr);
pst->set_text_high (gdbarch_adjust_dwarf2_addr (gdbarch,
- best_highpc + baseaddr));
+ best_highpc + baseaddr)
+ - baseaddr);
end_psymtab_common (objfile, pst);
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->text_low ()),
- paddress (gdbarch, pst->text_high ()),
- 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.
{
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
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);
}
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:
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
{
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;
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;
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;
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,
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,
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);
}
}
{
const gdb_byte *ids_ptr = htab->unit_table + sizeof (uint32_t) * nr_slots;
int *ids = htab->section_pool.v2.section_ids;
+ size_t sizeof_ids = sizeof (htab->section_pool.v2.section_ids);
/* Reverse map for error checking. */
int ids_seen[DW_SECT_MAX + 1];
int i;
" in section table [in module %s]"),
dwp_file->name);
}
- memset (ids, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
- memset (ids_seen, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
+ memset (ids, 255, sizeof_ids);
+ memset (ids_seen, 255, sizeof (ids_seen));
for (i = 0; i < nr_columns; ++i)
{
int id = read_4_bytes (dbfd, ids_ptr + i * sizeof (uint32_t));
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
}
}
- 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
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);
}
unsigned long offset = (DW_UNSND (attr)
+ (need_ranges_base ? cu->ranges_base : 0));
+ std::vector<blockrange> blockvec;
dwarf2_ranges_process (offset, cu,
[&] (CORE_ADDR start, CORE_ADDR end)
{
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);
}
}
}
else if (producer_is_icc (cu->producer, &major, &minor))
cu->producer_is_icc_lt_14 = major < 14;
+ else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
+ cu->producer_is_codewarrior = true;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
return cu->producer_is_gxx_lt_4_6;
}
+
+/* Codewarrior (at least as of version 5.0.40) generates dwarf line information
+ with incorrect is_stmt attributes. */
+
+static bool
+producer_is_codewarrior (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_codewarrior;
+}
+
/* Return the default accessibility type if it is not overriden by
DW_AT_accessibility. */
fp->type = get_die_type (die, cu);
fp->artificial = 1;
fp->name = "<<variant>>";
+
+ /* 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");
discriminant_info. */
bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
sect_offset discr_offset;
+ bool has_template_parameters = false;
if (is_variant_part)
{
/* 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)
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,
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,
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;
{
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);
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,
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;
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)
{
}
}
if ((shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= -(((LONGEST) 1) << shift);
+ result |= -(((ULONGEST) 1) << shift);
*bytes_read_ptr = num_read;
return result;
}
/* 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
else if (m_op_index == 0 || end_sequence)
{
fe->included_p = 1;
- if (m_record_lines_p && m_is_stmt)
+ if (m_record_lines_p && (producer_is_codewarrior (m_cu) || m_is_stmt))
{
if (m_last_subfile != m_cu->builder->get_current_subfile ()
|| end_sequence)
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 (_("<unknown type in %s, CU %s, DIE %s>"),
- objfile_name (objfile),
- sect_offset_str (cu->header.sect_off),
- sect_offset_str (die->sect_off));
+ std::string message
+ = string_printf (_("<unknown type in %s, CU %s, DIE %s>"),
+ 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);
}
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;
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.".
producer_is_gxx_lt_4_6 (0),
producer_is_gcc_lt_4_3 (0),
producer_is_icc_lt_14 (0),
+ producer_is_codewarrior (false),
processing_has_namespace_info (0)
{
per_cu->cu = this;