typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
DEF_VEC_P (dwarf2_per_cu_ptr);
+struct tu_stats
+{
+ int nr_uniq_abbrev_tables;
+ int nr_symtabs;
+ int nr_symtab_sharers;
+ int nr_stmt_less_type_units;
+ int nr_all_type_units_reallocs;
+};
+
/* Collection of data recorded per objfile.
This hangs off of dwarf2_objfile_data_key. */
/* Type unit statistics, to see how well the scaling improvements
are doing. */
- struct tu_stats
- {
- int nr_uniq_abbrev_tables;
- int nr_symtabs;
- int nr_symtab_sharers;
- int nr_stmt_less_type_units;
- int nr_all_type_units_reallocs;
- } tu_stats;
+ struct tu_stats tu_stats;
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
/* The CUs we recently read. */
VEC (dwarf2_per_cu_ptr) *just_read_cus;
+
+ /* Table containing line_header indexed by offset and offset_in_dwz. */
+ htab_t line_header_hash;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
int has_children,
void *data);
+struct file_entry
+{
+ const char *name;
+ unsigned int dir_index;
+ unsigned int mod_time;
+ unsigned int length;
+ int included_p; /* Non-zero if referenced by the Line Number Program. */
+ struct symtab *symtab; /* The associated symbol table, if any. */
+};
+
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
struct line_header
{
+ /* Offset of line number information in .debug_line section. */
+ sect_offset offset;
+
+ /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile. */
+ unsigned offset_in_dwz : 1;
+
unsigned int total_length;
unsigned short version;
unsigned int header_length;
with xmalloc; instead, they are pointers into debug_line_buffer.
Don't try to free them directly. */
unsigned int num_file_names, file_names_size;
- struct file_entry
- {
- const char *name;
- unsigned int dir_index;
- unsigned int mod_time;
- unsigned int length;
- int included_p; /* Non-zero if referenced by the Line Number Program. */
- struct symtab *symtab; /* The associated symbol table, if any. */
- } *file_names;
+ struct file_entry *file_names;
/* The start and end of the statement program following this
header. These point into dwarf2_per_objfile->line_buffer. */
and friends. */
static int bits_per_byte = 8;
+struct nextfield
+{
+ struct nextfield *next;
+ int accessibility;
+ int virtuality;
+ struct field field;
+};
+
+struct nextfnfield
+{
+ struct nextfnfield *next;
+ struct fn_field fnfield;
+};
+
+struct fnfieldlist
+{
+ const char *name;
+ int length;
+ struct nextfnfield *head;
+};
+
+struct typedef_field_list
+{
+ struct typedef_field field;
+ struct typedef_field_list *next;
+};
+
/* The routines that read and process dies for a C struct or C++ class
pass lists of data member fields and lists of member function fields
in an instance of a field_info structure, as defined below. */
struct field_info
{
/* List of data member and baseclasses fields. */
- struct nextfield
- {
- struct nextfield *next;
- int accessibility;
- int virtuality;
- struct field field;
- }
- *fields, *baseclasses;
+ struct nextfield *fields, *baseclasses;
/* Number of fields (including baseclasses). */
int nfields;
/* Member function fields array, entries are allocated in the order they
are encountered in the object file. */
- struct nextfnfield
- {
- struct nextfnfield *next;
- struct fn_field fnfield;
- }
- *fnfields;
+ struct nextfnfield *fnfields;
/* Member function fieldlist array, contains name of possibly overloaded
member function, number of overloaded member functions and a pointer
to the head of the member function field chain. */
- struct fnfieldlist
- {
- const char *name;
- int length;
- struct nextfnfield *head;
- }
- *fnfieldlists;
+ struct fnfieldlist *fnfieldlists;
/* Number of entries in the fnfieldlists array. */
int nfnfields;
/* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head of
a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */
- struct typedef_field_list
- {
- struct typedef_field field;
- struct typedef_field_list *next;
- }
- *typedef_field_list;
+ struct typedef_field_list *typedef_field_list;
unsigned typedef_field_list_count;
};
static void dwarf_decode_lines (struct line_header *, const char *,
struct dwarf2_cu *, struct partial_symtab *,
- CORE_ADDR);
+ CORE_ADDR, int decode_mapping);
static void dwarf2_start_subfile (const char *, const char *);
static void process_cu_includes (void);
static void check_producer (struct dwarf2_cu *cu);
+
+static void free_line_header_voidp (void *arg);
\f
/* Various complaints about symbol reading that don't abort the process. */
_("invalid attribute class or form for '%s' in '%s'"),
arg1, arg2);
}
+
+/* Hash function for line_header_hash. */
+
+static hashval_t
+line_header_hash (const struct line_header *ofs)
+{
+ return ofs->offset.sect_off ^ ofs->offset_in_dwz;
+}
+
+/* Hash function for htab_create_alloc_ex for line_header_hash. */
+
+static hashval_t
+line_header_hash_voidp (const void *item)
+{
+ const struct line_header *ofs = item;
+
+ return line_header_hash (ofs);
+}
+
+/* Equality function for line_header_hash. */
+
+static int
+line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
+{
+ const struct line_header *ofs_lhs = item_lhs;
+ const struct line_header *ofs_rhs = item_rhs;
+
+ return (ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off
+ && ofs_lhs->offset_in_dwz == ofs_rhs->offset_in_dwz);
+}
+
\f
#if WORDS_BIGENDIAN
static void
dw2_map_matching_symbols (struct objfile *objfile,
- const char * name, domain_enum namespace,
+ const char * name, domain_enum domain,
int global,
int (*callback) (struct block *,
struct symbol *, void *),
(struct objfile *objfile,
expand_symtabs_file_matcher_ftype *file_matcher,
expand_symtabs_symbol_matcher_ftype *symbol_matcher,
+ expand_symtabs_exp_notify_ftype *expansion_notify,
enum search_domain kind,
void *data)
{
per_cu = dw2_get_cutu (cu_index);
if (file_matcher == NULL || per_cu->v.quick->mark)
- dw2_instantiate_symtab (per_cu);
+ {
+ int symtab_was_null =
+ (per_cu->v.quick->compunit_symtab == NULL);
+
+ dw2_instantiate_symtab (per_cu);
+
+ if (expansion_notify != NULL
+ && symtab_was_null
+ && per_cu->v.quick->compunit_symtab != NULL)
+ {
+ expansion_notify (per_cu->v.quick->compunit_symtab,
+ data);
+ }
+ }
}
}
}
return; /* No linetable, so no includes. */
/* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
- dwarf_decode_lines (lh, pst->dirname, cu, pst, pst->textlow);
+ dwarf_decode_lines (lh, pst->dirname, cu, pst, pst->textlow, 1);
free_line_header (lh);
}
struct fn_fieldlist *fn_flp
= &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
physname = dwarf2_physname (mi->name, mi->die, cu);
- fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+ TYPE_FN_FIELD_PHYSNAME (fn_flp->fn_fields, mi->index)
+ = physname ? physname : "";
}
}
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
struct attribute *attr;
+ unsigned int line_offset;
+ struct line_header line_header_local;
+ hashval_t line_header_local_hash;
+ unsigned u;
+ void **slot;
+ int decode_mapping;
gdb_assert (! cu->per_cu->is_debug_types);
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
- if (attr)
+ if (attr == NULL)
+ return;
+
+ line_offset = DW_UNSND (attr);
+
+ /* The line header hash table is only created if needed (it exists to
+ prevent redundant reading of the line table for partial_units).
+ If we're given a partial_unit, we'll need it. If we're given a
+ compile_unit, then use the line header hash table if it's already
+ created, but don't create one just yet. */
+
+ if (dwarf2_per_objfile->line_header_hash == NULL
+ && die->tag == DW_TAG_partial_unit)
{
- unsigned int line_offset = DW_UNSND (attr);
- struct line_header *line_header
- = dwarf_decode_line_header (line_offset, cu);
+ dwarf2_per_objfile->line_header_hash
+ = htab_create_alloc_ex (127, line_header_hash_voidp,
+ line_header_eq_voidp,
+ free_line_header_voidp,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+ }
+
+ line_header_local.offset.sect_off = line_offset;
+ line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
+ line_header_local_hash = line_header_hash (&line_header_local);
+ if (dwarf2_per_objfile->line_header_hash != NULL)
+ {
+ slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash,
+ &line_header_local,
+ line_header_local_hash, NO_INSERT);
- if (line_header)
+ /* For DW_TAG_compile_unit we need info like symtab::linetable which
+ is not present in *SLOT (since if there is something in *SLOT then
+ it will be for a partial_unit). */
+ if (die->tag == DW_TAG_partial_unit && slot != NULL)
{
- cu->line_header = line_header;
- make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, cu, NULL, lowpc);
+ gdb_assert (*slot != NULL);
+ cu->line_header = *slot;
+ return;
}
}
+
+ /* dwarf_decode_line_header does not yet provide sufficient information.
+ We always have to call also dwarf_decode_lines for it. */
+ cu->line_header = dwarf_decode_line_header (line_offset, cu);
+ if (cu->line_header == NULL)
+ return;
+
+ if (dwarf2_per_objfile->line_header_hash == NULL)
+ slot = NULL;
+ else
+ {
+ slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash,
+ &line_header_local,
+ line_header_local_hash, INSERT);
+ gdb_assert (slot != NULL);
+ }
+ if (slot != NULL && *slot == NULL)
+ {
+ /* This newly decoded line number information unit will be owned
+ by line_header_hash hash table. */
+ *slot = cu->line_header;
+ }
+ else
+ {
+ /* We cannot free any current entry in (*slot) as that struct line_header
+ may be already used by multiple CUs. Create only temporary decoded
+ line_header for this CU - it may happen at most once for each line
+ number information unit. And if we're not using line_header_hash
+ then this is what we want as well. */
+ gdb_assert (die->tag != DW_TAG_partial_unit);
+ make_cleanup (free_cu_line_header, cu);
+ }
+ decode_mapping = (die->tag != DW_TAG_partial_unit);
+ dwarf_decode_lines (cu->line_header, comp_dir, cu, NULL, lowpc,
+ decode_mapping);
}
/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */
gdb_assert (tu_group->symtabs == NULL);
restart_symtab (tu_group->compunit_symtab, "", 0);
}
- /* Note: The compunit symtab will get allocated at the end. */
return;
}
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct context_stack *new;
+ struct context_stack *newobj;
CORE_ADDR lowpc;
CORE_ADDR highpc;
struct die_info *child_die;
}
}
- new = push_context (0, lowpc);
- new->name = new_symbol_full (die, read_type_die (die, cu), cu,
+ newobj = push_context (0, lowpc);
+ newobj->name = new_symbol_full (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
/* If there is a location expression for DW_AT_frame_base, record
it. */
attr = dwarf2_attr (die, DW_AT_frame_base, cu);
if (attr)
- dwarf2_symbol_mark_computed (attr, new->name, cu, 1);
+ dwarf2_symbol_mark_computed (attr, newobj->name, cu, 1);
cu->list_in_scope = &local_symbols;
}
}
- new = pop_context ();
+ newobj = pop_context ();
/* Make a block for the local symbols within. */
- block = finish_block (new->name, &local_symbols, new->old_blocks,
+ block = finish_block (newobj->name, &local_symbols, newobj->old_blocks,
lowpc, highpc);
/* For C++, set the block's scope. */
/* If we have address ranges, record them. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
- gdbarch_make_symbol_special (gdbarch, new->name, objfile);
+ gdbarch_make_symbol_special (gdbarch, newobj->name, objfile);
/* Attach template arguments to function. */
if (! VEC_empty (symbolp, template_args))
a function declares a class that has methods). This means that
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
- local_symbols = new->locals;
- using_directives = new->using_directives;
+ local_symbols = newobj->locals;
+ using_directives = newobj->using_directives;
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct context_stack *new;
+ struct context_stack *newobj;
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
CORE_ADDR baseaddr;
child_die = sibling_die (child_die);
}
}
- new = pop_context ();
+ newobj = pop_context ();
if (local_symbols != NULL || using_directives != NULL)
{
struct block *block
- = finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
- highpc);
+ = finish_block (0, &local_symbols, newobj->old_blocks,
+ newobj->start_addr, highpc);
/* Note that recording ranges after traversing children, as we
do here, means that recording a parent's ranges entails
to do. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
- local_symbols = new->locals;
- using_directives = new->using_directives;
+ local_symbols = newobj->locals;
+ using_directives = newobj->using_directives;
}
/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */
check_producer (struct dwarf2_cu *cu)
{
const char *cs;
- int major, minor, release;
+ int major, minor;
if (cu->producer == NULL)
{
combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility
interpreted incorrectly by GDB now - GCC PR debug/48229. */
}
- else if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) == 0)
+ else if (producer_is_gcc (cu->producer, &major, &minor))
{
- /* Skip any identifier after "GNU " - such as "C++" or "Java". */
-
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
- {
- /* Not recognized as GCC. */
- }
- else
- {
- cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
- cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
- }
+ cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
+ cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
}
else if (strncmp (cu->producer, "Intel(R) C", strlen ("Intel(R) C")) == 0)
cu->producer_is_icc = 1;
dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
{
const char *fieldname;
- const char *typename;
+ const char *type_name;
int len;
if (die->parent == NULL)
return 0;
fieldname = dwarf2_name (die, cu);
- typename = dwarf2_name (die->parent, cu);
- if (fieldname == NULL || typename == NULL)
+ type_name = dwarf2_name (die->parent, cu);
+ if (fieldname == NULL || type_name == NULL)
return 0;
len = strlen (fieldname);
- return (strncmp (fieldname, typename, len) == 0
- && (typename[len] == '\0' || typename[len] == '<'));
+ return (strncmp (fieldname, type_name, len) == 0
+ && (type_name[len] == '\0' || type_name[len] == '<'));
}
/* Add a member function to the proper fieldlist. */
static void
quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
{
- struct type *pfn_type, *domain_type, *new_type;
+ struct type *pfn_type, *self_type, *new_type;
/* Check for a structure with no name and two children. */
if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
|| TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
return;
- domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
+ self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
new_type = alloc_type (objfile);
- smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+ smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
TYPE_VARARGS (pfn_type));
smash_to_methodptr_type (type, new_type);
{
struct type *t = die_containing_type (die, cu);
- TYPE_VPTR_BASETYPE (type) = t;
+ set_type_vptr_basetype (type, t);
if (type == t)
{
int i;
if (is_vtable_name (fieldname, cu))
{
- TYPE_VPTR_FIELDNO (type) = i;
+ set_type_vptr_fieldno (type, i);
break;
}
}
}
else
{
- TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+ set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
}
}
else if (cu->producer
{
if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
{
- TYPE_VPTR_FIELDNO (type) = i;
- TYPE_VPTR_BASETYPE (type) = type;
+ set_type_vptr_fieldno (type, i);
+ set_type_vptr_basetype (type, type);
break;
}
}
current_die != NULL;
current_die = dwarf2_extension (die, &cu))
{
- name = dwarf2_name (current_die, cu);
+ /* We don't use dwarf2_name here so that we can detect the absence
+ of a name -> anonymous namespace. */
+ struct attribute *attr = dwarf2_attr (die, DW_AT_name, cu);
+
+ if (attr != NULL)
+ name = DW_STRING (attr);
if (name != NULL)
break;
}
return set_die_type (die, cv_type, cu);
}
+/* Handle DW_TAG_atomic_type. */
+
+static struct type *
+read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type, *cv_type;
+
+ base_type = die_type (die, cu);
+
+ /* The die_type call above may have already set the type for this DIE. */
+ cv_type = get_die_type (die, cu);
+ if (cv_type)
+ return cv_type;
+
+ cv_type = make_atomic_type (base_type);
+ return set_die_type (die, cv_type, cu);
+}
+
/* Extract all information from a DW_TAG_string_type DIE and add to
the user defined type vector. It isn't really a user defined type,
but it behaves like one, with other DIE's using an AT_user_def_type
else
TYPE_CALLING_CONVENTION (ftype) = DW_CC_normal;
+ /* Record whether the function returns normally to its caller or not
+ if the DWARF producer set that information. */
+ attr = dwarf2_attr (die, DW_AT_noreturn, cu);
+ if (attr && (DW_UNSND (attr) != 0))
+ TYPE_NO_RETURN (ftype) = 1;
+
/* We need to add the subroutine type to the die immediately so
we don't infinitely recurse when dealing with parameters
declared as the same subroutine type. */
target_die = follow_die_ref (die, attr, &target_cu);
target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
+ if (target_attr == NULL)
+ target_attr = dwarf2_attr (target_die, DW_AT_data_member_location,
+ target_cu);
if (target_attr == NULL)
return 0;
- if (attr_form_is_section_offset (target_attr))
+ switch (target_attr->name)
{
- baton = obstack_alloc (obstack, sizeof (*baton));
- baton->referenced_type = die_type (target_die, target_cu);
- fill_in_loclist_baton (cu, &baton->loclist, target_attr);
- prop->data.baton = baton;
- prop->kind = PROP_LOCLIST;
- gdb_assert (prop->data.baton != NULL);
- }
- else if (attr_form_is_block (target_attr))
- {
- baton = obstack_alloc (obstack, sizeof (*baton));
- baton->referenced_type = die_type (target_die, target_cu);
- baton->locexpr.per_cu = cu->per_cu;
- baton->locexpr.size = DW_BLOCK (target_attr)->size;
- baton->locexpr.data = DW_BLOCK (target_attr)->data;
- prop->data.baton = baton;
- prop->kind = PROP_LOCEXPR;
- gdb_assert (prop->data.baton != NULL);
- }
- else
- {
- dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
- "dynamic property");
- return 0;
+ case DW_AT_location:
+ if (attr_form_is_section_offset (target_attr))
+ {
+ baton = obstack_alloc (obstack, sizeof (*baton));
+ baton->referenced_type = die_type (target_die, target_cu);
+ fill_in_loclist_baton (cu, &baton->loclist, target_attr);
+ prop->data.baton = baton;
+ prop->kind = PROP_LOCLIST;
+ gdb_assert (prop->data.baton != NULL);
+ }
+ else if (attr_form_is_block (target_attr))
+ {
+ baton = obstack_alloc (obstack, sizeof (*baton));
+ baton->referenced_type = die_type (target_die, target_cu);
+ baton->locexpr.per_cu = cu->per_cu;
+ baton->locexpr.size = DW_BLOCK (target_attr)->size;
+ baton->locexpr.data = DW_BLOCK (target_attr)->data;
+ prop->data.baton = baton;
+ prop->kind = PROP_LOCEXPR;
+ gdb_assert (prop->data.baton != NULL);
+ }
+ else
+ {
+ dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
+ "dynamic property");
+ return 0;
+ }
+ break;
+ case DW_AT_data_member_location:
+ {
+ LONGEST offset;
+
+ if (!handle_data_member_location (target_die, target_cu,
+ &offset))
+ return 0;
+
+ baton = obstack_alloc (obstack, sizeof (*baton));
+ baton->referenced_type = get_die_type (target_die->parent,
+ target_cu);
+ baton->offset_info.offset = offset;
+ baton->offset_info.type = die_type (target_die, target_cu);
+ prop->data.baton = baton;
+ prop->kind = PROP_ADDR_OFFSET;
+ break;
+ }
}
}
else if (attr_form_is_constant (attr))
case DW_LANG_Fortran77:
case DW_LANG_Fortran90:
case DW_LANG_Fortran95:
+ case DW_LANG_Fortran03:
+ case DW_LANG_Fortran08:
cu->language = language_fortran;
break;
case DW_LANG_Go:
xfree (lh);
}
+/* Stub for free_line_header to match void * callback types. */
+
+static void
+free_line_header_voidp (void *arg)
+{
+ struct line_header *lh = arg;
+
+ free_line_header (lh);
+}
+
/* Add an entry to LH's include directory table. */
static void
/* Read the statement program header starting at OFFSET in
.debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
+ Returns NULL if there is a problem reading the header, e.g., if it
+ has a version we don't understand.
NOTE: the strings in the include directory and file name tables of
the returned object point into the dwarf line section buffer,
back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
(void *) lh);
+ lh->offset.sect_off = offset;
+ lh->offset_in_dwz = cu->per_cu->is_dwz;
+
line_ptr = section->buffer + offset;
/* Read in the header. */
lh->statement_program_end = line_ptr + lh->total_length;
lh->version = read_2_bytes (abfd, line_ptr);
line_ptr += 2;
+ if (lh->version > 4)
+ {
+ /* This is a version we don't understand. The format could have
+ changed in ways we don't handle properly so just punt. */
+ complaint (&symfile_complaints,
+ _("unsupported version in .debug_line section"));
+ return NULL;
+ }
lh->header_length = read_offset_1 (abfd, line_ptr, offset_size);
line_ptr += offset_size;
lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
E.g. expand_line_sal requires this when finding psymtabs to expand.
A good testcase for this is mb-inline.exp.
- LOWPC is the lowest address in CU (or 0 if not known). */
+ LOWPC is the lowest address in CU (or 0 if not known).
+
+ Boolean DECODE_MAPPING specifies we need to fully decode .debug_line
+ for its PC<->lines mapping information. Otherwise only the filename
+ table is read in. */
static void
dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
struct dwarf2_cu *cu, struct partial_symtab *pst,
- CORE_ADDR lowpc)
+ CORE_ADDR lowpc, int decode_mapping)
{
struct objfile *objfile = cu->objfile;
const int decode_for_pst_p = (pst != NULL);
- dwarf_decode_lines_1 (lh, cu, decode_for_pst_p, lowpc);
+ if (decode_mapping)
+ dwarf_decode_lines_1 (lh, cu, decode_for_pst_p, lowpc);
if (decode_for_pst_p)
{
case DW_TAG_module:
this_type = read_module_type (die, cu);
break;
+ case DW_TAG_atomic_type:
+ this_type = read_tag_atomic_type (die, cu);
+ break;
default:
complaint (&symfile_complaints,
_("unexpected tag in read_type_die: '%s'"),
return name;
}
-/* Get name of a die, return NULL if not found. */
+/* Get name of a die, return NULL if not found.
+ Anonymous namespaces are converted to their magic string. */
static const char *
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_name, cu);
if ((!attr || !DW_STRING (attr))
+ && die->tag != DW_TAG_namespace
&& die->tag != DW_TAG_class_type
&& die->tag != DW_TAG_interface_type
&& die->tag != DW_TAG_structure_type
to canonicalize them. */
return DW_STRING (attr);
+ case DW_TAG_namespace:
+ if (attr != NULL && DW_STRING (attr) != NULL)
+ return DW_STRING (attr);
+ return CP_ANONYMOUS_NAMESPACE_STR;
+
case DW_TAG_subprogram:
/* Java constructors will all be named "<init>", so return
the class name when we see this special case. */
if (dwarf2_per_objfile->quick_file_names_table)
htab_delete (dwarf2_per_objfile->quick_file_names_table);
+ if (dwarf2_per_objfile->line_header_hash)
+ htab_delete (dwarf2_per_objfile->line_header_hash);
+
/* Everything else should be on the objfile obstack. */
}
if (need_gnat_info (cu)
&& TYPE_CODE (type) != TYPE_CODE_FUNC
&& TYPE_CODE (type) != TYPE_CODE_FLT
+ && TYPE_CODE (type) != TYPE_CODE_METHODPTR
+ && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
+ && TYPE_CODE (type) != TYPE_CODE_METHOD
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);