X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=071f97bea614fc1558671d79b0053187b6770527;hb=749bab0110ddc56835bfe70765675577e3dea05a;hp=486a1ccc6701ce9a03bfb53605fd0ff71ab45dba;hpb=32d0add0a654c1204ab71dc8a55d9374538c4b33;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 486a1ccc67..071f97bea6 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -199,6 +199,15 @@ struct mapped_index 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. */ @@ -250,14 +259,7 @@ struct dwarf2_per_objfile /* 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. */ @@ -308,6 +310,9 @@ struct dwarf2_per_objfile /* 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; @@ -1019,11 +1024,27 @@ typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader, 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; @@ -1051,15 +1072,7 @@ struct line_header 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. */ @@ -1276,20 +1289,40 @@ struct dwarf_block 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; @@ -1302,35 +1335,19 @@ struct field_info /* 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; }; @@ -1512,7 +1529,7 @@ static struct line_header *dwarf_decode_line_header (unsigned int offset, 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 *); @@ -1844,6 +1861,8 @@ static void free_dwo_file_cleanup (void *); static void process_cu_includes (void); static void check_producer (struct dwarf2_cu *cu); + +static void free_line_header_voidp (void *arg); /* Various complaints about symbol reading that don't abort the process. */ @@ -1910,6 +1929,37 @@ dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) _("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); +} + #if WORDS_BIGENDIAN @@ -3766,7 +3816,7 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile, 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 *), @@ -3783,6 +3833,7 @@ dw2_expand_symtabs_matching (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) { @@ -3954,7 +4005,20 @@ dw2_expand_symtabs_matching 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); + } + } } } } @@ -4452,7 +4516,7 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, 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); } @@ -7704,7 +7768,8 @@ compute_delayed_physnames (struct dwarf2_cu *cu) 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 : ""; } } @@ -8994,24 +9059,95 @@ static void 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. */ @@ -9152,7 +9288,6 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu) gdb_assert (tu_group->symtabs == NULL); restart_symtab (tu_group->compunit_symtab, "", 0); } - /* Note: The compunit symtab will get allocated at the end. */ return; } @@ -11148,7 +11283,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) { 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; @@ -11216,15 +11351,15 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) } } - 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; @@ -11274,9 +11409,9 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) } } - 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. */ @@ -11288,7 +11423,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) /* 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)) @@ -11310,8 +11445,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) 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. */ @@ -11327,7 +11462,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) { 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; @@ -11354,13 +11489,13 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) 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 @@ -11374,8 +11509,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) 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. */ @@ -12153,7 +12288,7 @@ static void check_producer (struct dwarf2_cu *cu) { const char *cs; - int major, minor, release; + int major, minor; if (cu->producer == NULL) { @@ -12166,22 +12301,10 @@ check_producer (struct dwarf2_cu *cu) 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; @@ -12600,7 +12723,7 @@ static int 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) @@ -12612,13 +12735,13 @@ dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu) 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. */ @@ -12882,7 +13005,7 @@ is_vtable_name (const char *name, struct dwarf2_cu *cu) 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) @@ -12909,9 +13032,9 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile) || 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); @@ -13140,7 +13263,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { struct type *t = die_containing_type (die, cu); - TYPE_VPTR_BASETYPE (type) = t; + set_type_vptr_basetype (type, t); if (type == t) { int i; @@ -13154,7 +13277,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) if (is_vtable_name (fieldname, cu)) { - TYPE_VPTR_FIELDNO (type) = i; + set_type_vptr_fieldno (type, i); break; } } @@ -13169,7 +13292,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) } else { - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t); + set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t)); } } else if (cu->producer @@ -13188,8 +13311,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { 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; } } @@ -13994,7 +14117,12 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu) 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; } @@ -14229,6 +14357,24 @@ read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu) 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 @@ -14343,6 +14489,12 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) 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. */ @@ -14613,34 +14765,59 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, 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)) @@ -16761,6 +16938,8 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu) 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: @@ -16909,6 +17088,16 @@ free_line_header (struct line_header *lh) 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 @@ -16994,6 +17183,8 @@ get_debug_line_section (struct dwarf2_cu *cu) /* 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, @@ -17039,6 +17230,9 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) 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. */ @@ -17055,6 +17249,14 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) 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); @@ -17666,17 +17868,22 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, 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) { @@ -18695,6 +18902,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu) 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'"), @@ -19056,7 +19266,8 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu, 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) @@ -19065,6 +19276,7 @@ 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 @@ -19083,6 +19295,11 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) 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 "", so return the class name when we see this special case. */ @@ -21773,6 +21990,9 @@ dwarf2_free_objfile (struct objfile *objfile) 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. */ } @@ -21855,6 +22075,9 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) 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);