X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=16a1c4225d6ed4ae160c7383867539a762edd9de;hb=8b2dbe47f314187de7089f4ffeb26c100b7d4c3e;hp=17d81f9c236b5a66b5643feb4bfc42a503be34e1;hpb=f5ef7c67f8899c3d822c64e9317c62b55c9d2623;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 17d81f9c23..16a1c4225d 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,5 +1,5 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -37,6 +37,7 @@ #include "demangle.h" #include "expression.h" #include "filenames.h" /* for DOSish file names */ +#include "macrotab.h" #include "language.h" #include "complaints.h" @@ -161,6 +162,11 @@ unsigned int dwarf_eh_frame_size; /* local data types */ +/* We hold several abbreviation tables in memory at the same time. */ +#ifndef ABBREV_HASH_SIZE +#define ABBREV_HASH_SIZE 121 +#endif + /* The data in a compilation unit header, after target2host translation, looks like this. */ struct comp_unit_head @@ -173,21 +179,74 @@ struct comp_unit_head unsigned int offset_size; /* size of file offsets; either 4 or 8 */ unsigned int initial_length_size; /* size of the length field; either 4 or 12 */ + + /* Offset to the first byte of this compilation unit header in the + * .debug_info section, for resolving relative reference dies. */ + + unsigned int offset; + + /* Pointer to this compilation unit header in the .debug_info + * section */ + + char *cu_head_ptr; + + /* Pointer to the first die of this compilatio unit. This will + * be the first byte following the compilation unit header. */ + + char *first_die_ptr; + + /* Pointer to the next compilation unit header in the program. */ + + struct comp_unit_head *next; + + /* DWARF abbreviation table associated with this compilation unit */ + + struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; }; -/* The data in the .debug_line statement prologue looks like this. */ -struct line_head +/* 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 +{ + unsigned int total_length; + unsigned short version; + unsigned int header_length; + unsigned char minimum_instruction_length; + unsigned char default_is_stmt; + int line_base; + unsigned char line_range; + unsigned char opcode_base; + + /* standard_opcode_lengths[i] is the number of operands for the + standard opcode whose value is i. This means that + standard_opcode_lengths[0] is unused, and the last meaningful + element is standard_opcode_lengths[opcode_base - 1]. */ + unsigned char *standard_opcode_lengths; + + /* The include_directories table. NOTE! These strings are not + allocated with xmalloc; instead, they are pointers into + debug_line_buffer. If you try to free them, `free' will get + indigestion. */ + unsigned int num_include_dirs, include_dirs_size; + char **include_dirs; + + /* The file_names table. NOTE! These strings are not allocated + 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 { - unsigned int total_length; - unsigned short version; - unsigned int prologue_length; - unsigned char minimum_instruction_length; - unsigned char default_is_stmt; - int line_base; - unsigned char line_range; - unsigned char opcode_base; - unsigned char *standard_opcode_lengths; - }; + char *name; + unsigned int dir_index; + unsigned int mod_time; + unsigned int length; + } *file_names; + + /* The start and end of the statement program following this + header. These point into dwarf_line_buffer. */ + char *statement_program_start, *statement_program_end; +}; /* When we construct a partial symbol table entry we only need this much information. */ @@ -256,6 +315,16 @@ struct attribute u; }; +struct function_range +{ + const char *name; + CORE_ADDR lowpc, highpc; + int seen_line; + struct function_range *next; +}; + +static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn; + /* Get at parts of an attribute structure */ #define DW_STRING(attr) ((attr)->u.str) @@ -271,17 +340,10 @@ struct dwarf_block char *data; }; -/* We only hold one compilation unit's abbrevs in - memory at any one time. */ -#ifndef ABBREV_HASH_SIZE -#define ABBREV_HASH_SIZE 121 -#endif #ifndef ATTR_ALLOC_CHUNK #define ATTR_ALLOC_CHUNK 4 #endif -static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; - /* A hash table of die offsets for following references. */ #ifndef REF_HASH_SIZE #define REF_HASH_SIZE 1021 @@ -310,6 +372,7 @@ static char *dwarf_info_buffer; static char *dwarf_abbrev_buffer; static char *dwarf_line_buffer; static char *dwarf_str_buffer; +static char *dwarf_macinfo_buffer; /* A zeroed version of a partial die for initialization purposes. */ static struct partial_die_info zeroed_partial_die; @@ -392,6 +455,10 @@ struct dwarf2_pinfo char *dwarf_line_buffer; + /* Size of dwarf_line_buffer, in bytes. */ + + unsigned int dwarf_line_size; + /* Pointer to start of dwarf string buffer for the objfile. */ char *dwarf_str_buffer; @@ -399,6 +466,15 @@ struct dwarf2_pinfo /* Size of dwarf string section for the objfile. */ unsigned int dwarf_str_size; + + /* Pointer to start of dwarf macro buffer for the objfile. */ + + char *dwarf_macinfo_buffer; + + /* Size of dwarf macinfo section for the objfile. */ + + unsigned int dwarf_macinfo_size; + }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) @@ -407,8 +483,11 @@ struct dwarf2_pinfo #define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer) #define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size) #define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer) +#define DWARF_LINE_SIZE(p) (PST_PRIVATE(p)->dwarf_line_size) #define DWARF_STR_BUFFER(p) (PST_PRIVATE(p)->dwarf_str_buffer) #define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size) +#define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer) +#define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size) /* Maintain an array of referenced fundamental types for the current compilation unit being read. For DWARF version 1, we have to construct @@ -474,17 +553,6 @@ struct field_info int nfnfields; }; -/* FIXME: Kludge to mark a varargs function type for C++ member function - argument processing. */ -#define TYPE_FLAG_VARARGS (1 << 10) - -/* Dwarf2 has no clean way to discern C++ static and non-static member - functions. G++ helps GDB by marking the first parameter for non-static - member functions (which is the this pointer) as artificial. - We pass this information between dwarf2_add_member_fn and - read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */ -#define TYPE_FIELD_ARTIFICIAL TYPE_FIELD_BITPOS - /* Various complaints about symbol reading that don't abort the process */ static struct complaint dwarf2_const_ignored = @@ -503,6 +571,10 @@ static struct complaint dwarf2_missing_line_number_section = { "missing .debug_line section", 0, 0 }; +static struct complaint dwarf2_statement_list_fits_in_line_number_section = +{ + "statement list doesn't fit in .debug_line section", 0, 0 +}; static struct complaint dwarf2_mangled_line_number_section = { "mangled .debug_line section", 0, 0 @@ -571,6 +643,50 @@ static struct complaint dwarf2_unsupported_const_value_attr = { "unsupported const value attribute form: '%s'", 0, 0 }; +static struct complaint dwarf2_misplaced_line_number = +{ + "misplaced first line number at 0x%lx for '%s'", 0, 0 +}; +static struct complaint dwarf2_line_header_too_long = +{ + "line number info header doesn't fit in `.debug_line' section", 0, 0 +}; +static struct complaint dwarf2_missing_macinfo_section = +{ + "missing .debug_macinfo section", 0, 0 +}; +static struct complaint dwarf2_macros_too_long = +{ + "macro info runs off end of `.debug_macinfo' section", 0, 0 +}; +static struct complaint dwarf2_macros_not_terminated = +{ + "no terminating 0-type entry for macros in `.debug_macinfo' section", 0, 0 +}; +static struct complaint dwarf2_macro_outside_file = +{ + "debug info gives macro %s outside of any file: %s", 0, 0 +}; +static struct complaint dwarf2_macro_unmatched_end_file = +{ + "macro debug info has an unmatched `close_file' directive", 0, 0 +}; +static struct complaint dwarf2_macro_malformed_definition = +{ + "macro debug info contains a malformed macro definition:\n`%s'", 0, 0 +}; +static struct complaint dwarf2_macro_spaces_in_definition = +{ + "macro definition contains spaces in formal argument list:\n`%s'", 0, 0 +}; +static struct complaint dwarf2_invalid_attrib_class = +{ + "invalid attribute class or form for '%s' in '%s'", 0, 0 +}; +static struct complaint dwarf2_invalid_pointer_size = +{ + "invalid pointer size %d", 0, 0 +}; /* local function prototypes */ @@ -595,11 +711,12 @@ static void psymtab_to_symtab_1 (struct partial_symtab *); char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); -static void dwarf2_read_abbrevs (bfd *, unsigned int); +static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header); static void dwarf2_empty_abbrev_table (PTR); -static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int); +static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, + const struct comp_unit_head *cu_header); static char *read_partial_die (struct partial_die_info *, bfd *, char *, @@ -650,7 +767,14 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int); static int die_is_declaration (struct die_info *); -static void dwarf_decode_lines (unsigned int, char *, bfd *, +static void free_line_header (struct line_header *lh); + +static struct line_header *(dwarf_decode_line_header + (unsigned int offset, + bfd *abfd, + const struct comp_unit_head *cu_header)); + +static void dwarf_decode_lines (struct line_header *, char *, bfd *, const struct comp_unit_head *); static void dwarf2_start_subfile (char *, char *); @@ -805,15 +929,29 @@ static struct abbrev_info *dwarf_alloc_abbrev (void); static struct die_info *dwarf_alloc_die (void); +static void initialize_cu_func_list (void); + +static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR); + +static void dwarf_decode_macros (struct line_header *, unsigned int, + char *, bfd *, const struct comp_unit_head *, + struct objfile *); + +static int attr_form_is_block (struct attribute *); + /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. */ int dwarf2_has_info (bfd *abfd) { - dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0; + dwarf_info_offset = 0; + dwarf_abbrev_offset = 0; + dwarf_line_offset = 0; dwarf_str_offset = 0; - dwarf_frame_offset = dwarf_eh_frame_offset = 0; + dwarf_macinfo_offset = 0; + dwarf_frame_offset = 0; + dwarf_eh_frame_offset = 0; bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); if (dwarf_info_offset && dwarf_abbrev_offset) { @@ -898,9 +1036,13 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) dwarf_abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_offset, dwarf_abbrev_size); - dwarf_line_buffer = dwarf2_read_section (objfile, - dwarf_line_offset, - dwarf_line_size); + + if (dwarf_line_offset) + dwarf_line_buffer = dwarf2_read_section (objfile, + dwarf_line_offset, + dwarf_line_size); + else + dwarf_line_buffer = NULL; if (dwarf_str_offset) dwarf_str_buffer = dwarf2_read_section (objfile, @@ -909,6 +1051,13 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) else dwarf_str_buffer = NULL; + if (dwarf_macinfo_offset) + dwarf_macinfo_buffer = dwarf2_read_section (objfile, + dwarf_macinfo_offset, + dwarf_macinfo_size); + else + dwarf_macinfo_buffer = NULL; + if (mainline || (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)) @@ -1088,9 +1237,14 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) (long) (beg_of_comp_unit - dwarf_info_buffer)); return; } + /* Complete the cu_header */ + cu_header.offset = beg_of_comp_unit - dwarf_info_buffer; + cu_header.first_die_ptr = info_ptr; + cu_header.cu_head_ptr = beg_of_comp_unit; + /* Read the abbrevs for this compilation unit into a table */ - dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); - make_cleanup (dwarf2_empty_abbrev_table, NULL); + dwarf2_read_abbrevs (abfd, &cu_header); + make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs); /* Read the compilation unit die */ info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr, @@ -1114,8 +1268,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer; DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size; DWARF_LINE_BUFFER (pst) = dwarf_line_buffer; + DWARF_LINE_SIZE (pst) = dwarf_line_size; DWARF_STR_BUFFER (pst) = dwarf_str_buffer; DWARF_STR_SIZE (pst) = dwarf_str_size; + DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer; + DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table */ @@ -1415,8 +1572,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst); dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst); dwarf_line_buffer = DWARF_LINE_BUFFER (pst); + dwarf_line_size = DWARF_LINE_SIZE (pst); dwarf_str_buffer = DWARF_STR_BUFFER (pst); dwarf_str_size = DWARF_STR_SIZE (pst); + dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst); + dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst); baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); cu_header_offset = offset; info_ptr = dwarf_info_buffer + offset; @@ -1431,8 +1591,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); /* Read the abbrevs for this compilation unit */ - dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); - make_cleanup (dwarf2_empty_abbrev_table, NULL); + dwarf2_read_abbrevs (abfd, &cu_header); + make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs); dies = read_comp_unit (info_ptr, abfd, &cu_header); @@ -1552,11 +1712,17 @@ process_die (struct die_info *die, struct objfile *objfile, } } +static void +initialize_cu_func_list (void) +{ + cu_first_fn = cu_last_fn = cu_cached_fn = NULL; +} + static void read_file_scope (struct die_info *die, struct objfile *objfile, const struct comp_unit_head *cu_header) { - unsigned int line_offset = 0; + struct cleanup *back_to = make_cleanup (null_cleanup, 0); CORE_ADDR lowpc = ((CORE_ADDR) -1); CORE_ADDR highpc = ((CORE_ADDR) 0); struct attribute *attr; @@ -1564,6 +1730,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile, char *comp_dir = NULL; struct die_info *child_die; bfd *abfd = objfile->obfd; + struct line_header *line_header = 0; if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile)) { @@ -1644,13 +1811,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile, start_symtab (name, comp_dir, lowpc); record_debugformat ("DWARF 2"); - /* Decode line number information if present. */ - attr = dwarf_attr (die, DW_AT_stmt_list); - if (attr) - { - line_offset = DW_UNSND (attr); - dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header); - } + initialize_cu_func_list (); /* Process all dies in compilation unit. */ if (die->has_children) @@ -1662,6 +1823,55 @@ read_file_scope (struct die_info *die, struct objfile *objfile, child_die = sibling_die (child_die); } } + + /* Decode line number information if present. */ + attr = dwarf_attr (die, DW_AT_stmt_list); + if (attr) + { + unsigned int line_offset = DW_UNSND (attr); + line_header = dwarf_decode_line_header (line_offset, + abfd, cu_header); + if (line_header) + { + make_cleanup ((make_cleanup_ftype *) free_line_header, + (void *) line_header); + dwarf_decode_lines (line_header, comp_dir, abfd, cu_header); + } + } + + /* Decode macro information, if present. Dwarf 2 macro information + refers to information in the line number info statement program + header, so we can only read it if we've read the header + successfully. */ + attr = dwarf_attr (die, DW_AT_macro_info); + if (attr && line_header) + { + unsigned int macro_offset = DW_UNSND (attr); + dwarf_decode_macros (line_header, macro_offset, + comp_dir, abfd, cu_header, objfile); + } + do_cleanups (back_to); +} + +static void +add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc) +{ + struct function_range *thisfn; + + thisfn = (struct function_range *) + obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range)); + thisfn->name = name; + thisfn->lowpc = lowpc; + thisfn->highpc = highpc; + thisfn->seen_line = 0; + thisfn->next = NULL; + + if (cu_last_fn == NULL) + cu_first_fn = thisfn; + else + cu_last_fn->next = thisfn; + + cu_last_fn = thisfn; } static void @@ -1685,6 +1895,9 @@ read_func_scope (struct die_info *die, struct objfile *objfile, lowpc += baseaddr; highpc += baseaddr; + /* Record the function range for dwarf_decode_lines. */ + add_to_cu_func_list (name, lowpc, highpc); + if (objfile->ei.entry_point >= lowpc && objfile->ei.entry_point < highpc) { @@ -1699,7 +1912,24 @@ read_func_scope (struct die_info *die, struct objfile *objfile, attr = dwarf_attr (die, DW_AT_frame_base); if (attr) { - CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + CORE_ADDR addr; + + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + } + else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + addr = 0; + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_frame_base", name); + addr = 0; + } + if (isderef) complain (&dwarf2_unsupported_at_frame_base, name); else if (isreg) @@ -2127,23 +2357,15 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC) { struct type *return_type = TYPE_TARGET_TYPE (die->type); - struct type **arg_types; int nparams = TYPE_NFIELDS (die->type); - int iparams; - /* Copy argument types from the subroutine type. */ - arg_types = (struct type **) - TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *)); - for (iparams = 0; iparams < nparams; iparams++) - arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams); - - /* Set last entry in argument type vector. */ - if (TYPE_FLAGS (die->type) & TYPE_FLAG_VARARGS) - arg_types[nparams] = NULL; - else - arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID); - - smash_to_method_type (fnp->type, type, return_type, arg_types); + /* TYPE is the domain of this method, and DIE->TYPE is the type + of the method itself (TYPE_CODE_METHOD). */ + smash_to_method_type (fnp->type, type, + TYPE_TARGET_TYPE (die->type), + TYPE_FIELDS (die->type), + TYPE_NFIELDS (die->type), + TYPE_VARARGS (die->type)); /* Handle static member functions. Dwarf2 has no clean way to discern C++ static and non-static @@ -2179,10 +2401,30 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, } } + /* Check for artificial methods. */ + attr = dwarf_attr (die, DW_AT_artificial); + if (attr && DW_UNSND (attr) != 0) + fnp->is_artificial = 1; + /* Get index in virtual function table if it is a virtual member function. */ attr = dwarf_attr (die, DW_AT_vtable_elem_location); if (attr) - fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2; + { + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2; + } + else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_vtable_elem_location", + fieldname); + } + } } /* Create the vector of member function fields, and attach it to the type. */ @@ -2380,8 +2622,6 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, /* No children, must be stub. */ TYPE_FLAGS (type) |= TYPE_FLAG_STUB; } - - finish_cv_type (die->type); } /* Given a pointer to a die which begins an enumeration, process all @@ -2544,7 +2784,8 @@ read_array_type (struct die_info *die, struct objfile *objfile, else if (attr->form == DW_FORM_udata || attr->form == DW_FORM_data1 || attr->form == DW_FORM_data2 - || attr->form == DW_FORM_data4) + || attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) { low = DW_UNSND (attr); } @@ -2570,7 +2811,8 @@ read_array_type (struct die_info *die, struct objfile *objfile, else if (attr->form == DW_FORM_udata || attr->form == DW_FORM_data1 || attr->form == DW_FORM_data2 - || attr->form == DW_FORM_data4) + || attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) { high = DW_UNSND (attr); } @@ -2616,6 +2858,16 @@ read_array_type (struct die_info *die, struct objfile *objfile, while (ndim-- > 0) type = create_array_type (NULL, type, range_types[ndim]); + /* Understand Dwarf2 support for vector types (like they occur on + the PowerPC w/ AltiVec). Gcc just adds another attribute to the + array type. This is not part of the Dwarf2/3 standard yet, but a + custom vendor extension. The main difference between a regular + array and the vector variant is that vectors are passed by value + to functions. */ + attr = dwarf_attr (die, DW_AT_GNU_vector); + if (attr) + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + do_cleanups (back_to); /* Install the type in the die. */ @@ -2636,7 +2888,20 @@ read_common_block (struct die_info *die, struct objfile *objfile, attr = dwarf_attr (die, DW_AT_location); if (attr) { - base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + } + else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_location", + "common block member"); + } } if (die->has_children) { @@ -2664,7 +2929,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile, const struct comp_unit_head *cu_header) { struct type *type; - struct attribute *attr; + struct attribute *attr_byte_size; + struct attribute *attr_address_class; + int byte_size, addr_class; if (die->type) { @@ -2672,15 +2939,42 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile, } type = lookup_pointer_type (die_type (die, objfile, cu_header)); - attr = dwarf_attr (die, DW_AT_byte_size); - if (attr) - { - TYPE_LENGTH (type) = DW_UNSND (attr); - } + + attr_byte_size = dwarf_attr (die, DW_AT_byte_size); + if (attr_byte_size) + byte_size = DW_UNSND (attr_byte_size); else + byte_size = cu_header->addr_size; + + attr_address_class = dwarf_attr (die, DW_AT_address_class); + if (attr_address_class) + addr_class = DW_UNSND (attr_address_class); + else + addr_class = DW_ADDR_none; + + /* If the pointer size or address class is different than the + default, create a type variant marked as such and set the + length accordingly. */ + if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none) { - TYPE_LENGTH (type) = cu_header->addr_size; + if (ADDRESS_CLASS_TYPE_FLAGS_P ()) + { + int type_flags; + + type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class); + gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); + type = make_type_with_address_space (type, type_flags); + } + else if (TYPE_LENGTH (type) != byte_size) + { + complain (&dwarf2_invalid_pointer_size, byte_size); + } + else { + /* Should we also complain about unhandled address classes? */ + } } + + TYPE_LENGTH (type) = byte_size; die->type = type; } @@ -2790,12 +3084,30 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) } else { - length = 1; + /* check for the DW_AT_byte_size attribute */ + attr = dwarf_attr (die, DW_AT_byte_size); + if (attr) + { + length = DW_UNSND (attr); + } + else + { + length = 1; + } } index_type = dwarf2_fundamental_type (objfile, FT_INTEGER); range_type = create_range_type (NULL, index_type, 1, length); - char_type = dwarf2_fundamental_type (objfile, FT_CHAR); - type = create_string_type (char_type, range_type); + if (cu_language == language_fortran) + { + /* Need to create a unique string type for bounds + information */ + type = create_string_type (0, range_type); + } + else + { + char_type = dwarf2_fundamental_type (objfile, FT_CHAR); + type = create_string_type (char_type, range_type); + } die->type = type; } @@ -2886,26 +3198,18 @@ static void read_typedef (struct die_info *die, struct objfile *objfile, const struct comp_unit_head *cu_header) { - struct type *type; + struct attribute *attr; + char *name = NULL; if (!die->type) { - struct attribute *attr; - struct type *xtype; - - xtype = die_type (die, objfile, cu_header); - - type = alloc_type (objfile); - TYPE_CODE (type) = TYPE_CODE_TYPEDEF; - TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB; - TYPE_TARGET_TYPE (type) = xtype; attr = dwarf_attr (die, DW_AT_name); if (attr && DW_STRING (attr)) - TYPE_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); - - die->type = type; + { + name = DW_STRING (attr); + } + die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile); + TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header); } } @@ -2973,6 +3277,18 @@ read_base_type (struct die_info *die, struct objfile *objfile) type = init_type (code, size, type_flags, DW_STRING (attr), objfile); if (encoding == DW_ATE_address) TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID); + else if (encoding == DW_ATE_complex_float) + { + if (size == 32) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT); + else if (size == 16) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT); + else if (size == 8) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_FLOAT); + } } else { @@ -3089,17 +3405,18 @@ dwarf2_read_section (struct objfile *objfile, file_ptr offset, in a hash table. */ static void -dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) +dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header) { char *abbrev_ptr; struct abbrev_info *cur_abbrev; unsigned int abbrev_number, bytes_read, abbrev_name; unsigned int abbrev_form, hash_number; - /* empty the table */ - dwarf2_empty_abbrev_table (NULL); + /* Initialize dwarf2 abbrevs */ + memset (cu_header->dwarf2_abbrevs, 0, + ABBREV_HASH_SIZE*sizeof (struct abbrev_info *)); - abbrev_ptr = dwarf_abbrev_buffer + offset; + abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -3138,8 +3455,8 @@ dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) } hash_number = abbrev_number % ABBREV_HASH_SIZE; - cur_abbrev->next = dwarf2_abbrevs[hash_number]; - dwarf2_abbrevs[hash_number] = cur_abbrev; + cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number]; + cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev; /* Get next abbreviation. Under Irix6 the abbreviations for a compilation unit are not @@ -3153,7 +3470,7 @@ dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; - if (dwarf2_lookup_abbrev (abbrev_number) != NULL) + if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL) break; } } @@ -3162,15 +3479,18 @@ dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) /* ARGSUSED */ static void -dwarf2_empty_abbrev_table (PTR ignore) +dwarf2_empty_abbrev_table (PTR ptr_to_abbrevs_table) { int i; struct abbrev_info *abbrev, *next; + struct abbrev_info **abbrevs; + + abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table; for (i = 0; i < ABBREV_HASH_SIZE; ++i) { next = NULL; - abbrev = dwarf2_abbrevs[i]; + abbrev = abbrevs[i]; while (abbrev) { next = abbrev->next; @@ -3178,20 +3498,20 @@ dwarf2_empty_abbrev_table (PTR ignore) xfree (abbrev); abbrev = next; } - dwarf2_abbrevs[i] = NULL; + abbrevs[i] = NULL; } } /* Lookup an abbrev_info structure in the abbrev hash table. */ static struct abbrev_info * -dwarf2_lookup_abbrev (unsigned int number) +dwarf2_lookup_abbrev (unsigned int number, const struct comp_unit_head *cu_header) { unsigned int hash_number; struct abbrev_info *abbrev; hash_number = number % ABBREV_HASH_SIZE; - abbrev = dwarf2_abbrevs[hash_number]; + abbrev = cu_header->dwarf2_abbrevs[hash_number]; while (abbrev) { @@ -3223,7 +3543,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, if (!abbrev_number) return info_ptr; - abbrev = dwarf2_lookup_abbrev (abbrev_number); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header); if (!abbrev) { error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number); @@ -3260,7 +3580,20 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, part_die->highpc = DW_ADDR (&attr); break; case DW_AT_location: - part_die->locdesc = DW_BLOCK (&attr); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (&attr)) + { + part_die->locdesc = DW_BLOCK (&attr); + } + else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_location", + "partial symbol information"); + } break; case DW_AT_language: part_die->language = DW_UNSND (&attr); @@ -3354,7 +3687,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, return info_ptr; } - abbrev = dwarf2_lookup_abbrev (abbrev_number); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header); if (!abbrev) { error ("Dwarf Error: could not find abbrev number %d.", abbrev_number); @@ -3601,12 +3934,25 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, return retval; } -/* Reads the initial length from a section. The (draft) DWARF 2.1 +/* Read the initial length from a section. The (draft) DWARF 3 specification allows the initial length to take up either 4 bytes or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8 bytes describe the length and all offsets will be 8 bytes in length instead of 4. + An older, non-standard 64-bit format is also handled by this + function. The older format in question stores the initial length + as an 8-byte quantity without an escape value. Lengths greater + than 2^32 aren't very common which means that the initial 4 bytes + is almost always zero. Since a length value of zero doesn't make + sense for the 32-bit format, this initial zero can be considered to + be an escape value which indicates the presence of the older 64-bit + format. As written, the code can't detect (old format) lengths + greater than 4GB. If it becomes necessary to handle lengths somewhat + larger than 4GB, we could allow other small values (such as the + non-sensical values of 1, 2, and 3) to also be used as escape values + indicating the presence of the old format. + The value returned via bytes_read should be used to increment the relevant pointer after calling read_initial_length(). @@ -3617,14 +3963,18 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, [ Note: read_initial_length() and read_offset() are based on the document entitled "DWARF Debugging Information Format", revision - 2.1, draft 4, dated July 20, 2000. This document was obtained + 3, draft 8, dated November 19, 2001. This document was obtained from: - http://reality.sgi.com/dehnert_engr/dwarf/dwarf2p1-draft4-000720.pdf + http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf This document is only a draft and is subject to change. (So beware.) - - Kevin, Aug 4, 2000 + Details regarding the older, non-standard 64-bit format were + determined empirically by examining 64-bit ELF files produced + by the SGI toolchain on an IRIX 6.5 machine. + + - Kevin, July 16, 2002 ] */ static LONGEST @@ -3645,6 +3995,18 @@ read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header, cu_header->offset_size = 8; } } + else if (retval == 0) + { + /* Handle (non-standard) 64-bit DWARF2 formats such as that used + by IRIX. */ + retval = bfd_get_64 (abfd, (bfd_byte *) buf); + *bytes_read = 8; + if (cu_header != NULL) + { + cu_header->initial_length_size = 8; + cu_header->offset_size = 8; + } + } else { *bytes_read = 4; @@ -3809,6 +4171,7 @@ set_cu_language (unsigned int lang) break; case DW_LANG_Fortran77: case DW_LANG_Fortran90: + case DW_LANG_Fortran95: cu_language = language_fortran; break; case DW_LANG_Mips_Assembler: @@ -3818,6 +4181,7 @@ set_cu_language (unsigned int lang) cu_language = language_java; break; case DW_LANG_Ada83: + case DW_LANG_Ada95: case DW_LANG_Cobol74: case DW_LANG_Cobol85: case DW_LANG_Pascal83: @@ -3866,87 +4230,153 @@ die_is_declaration (struct die_info *die) && ! dwarf_attr (die, DW_AT_specification)); } -/* Decode the line number information for the compilation unit whose - line number info is at OFFSET in the .debug_line section. - The compilation directory of the file is passed in COMP_DIR. */ -struct filenames +/* Free the line_header structure *LH, and any arrays and strings it + refers to. */ +static void +free_line_header (struct line_header *lh) +{ + if (lh->standard_opcode_lengths) + xfree (lh->standard_opcode_lengths); + + /* Remember that all the lh->file_names[i].name pointers are + pointers into debug_line_buffer, and don't need to be freed. */ + if (lh->file_names) + xfree (lh->file_names); + + /* Similarly for the include directory names. */ + if (lh->include_dirs) + xfree (lh->include_dirs); + + xfree (lh); +} + + +/* Add an entry to LH's include directory table. */ +static void +add_include_dir (struct line_header *lh, char *include_dir) { - unsigned int num_files; - struct fileinfo + /* Grow the array if necessary. */ + if (lh->include_dirs_size == 0) { - char *name; - unsigned int dir; - unsigned int time; - unsigned int size; + lh->include_dirs_size = 1; /* for testing */ + lh->include_dirs = xmalloc (lh->include_dirs_size + * sizeof (*lh->include_dirs)); + } + else if (lh->num_include_dirs >= lh->include_dirs_size) + { + lh->include_dirs_size *= 2; + lh->include_dirs = xrealloc (lh->include_dirs, + (lh->include_dirs_size + * sizeof (*lh->include_dirs))); } - *files; -}; -struct directories - { - unsigned int num_dirs; - char **dirs; - }; + lh->include_dirs[lh->num_include_dirs++] = include_dir; +} + +/* Add an entry to LH's file name table. */ static void -dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, - const struct comp_unit_head *cu_header) +add_file_name (struct line_header *lh, + char *name, + unsigned int dir_index, + unsigned int mod_time, + unsigned int length) { - char *line_ptr; - char *line_end; - struct line_head lh; - struct cleanup *back_to; - unsigned int i, bytes_read; - char *cur_file, *cur_dir; - unsigned char op_code, extended_op, adj_opcode; + struct file_entry *fe; -#define FILE_ALLOC_CHUNK 5 -#define DIR_ALLOC_CHUNK 5 + /* Grow the array if necessary. */ + if (lh->file_names_size == 0) + { + lh->file_names_size = 1; /* for testing */ + lh->file_names = xmalloc (lh->file_names_size + * sizeof (*lh->file_names)); + } + else if (lh->num_file_names >= lh->file_names_size) + { + lh->file_names_size *= 2; + lh->file_names = xrealloc (lh->file_names, + (lh->file_names_size + * sizeof (*lh->file_names))); + } - struct filenames files; - struct directories dirs; + fe = &lh->file_names[lh->num_file_names++]; + fe->name = name; + fe->dir_index = dir_index; + fe->mod_time = mod_time; + fe->length = length; +} + + +/* Read the statement program header starting at OFFSET in + dwarf_line_buffer, according to the endianness of ABFD. Return a + pointer to a struct line_header, allocated using xmalloc. + + NOTE: the strings in the include directory and file name tables of + the returned object point into debug_line_buffer, and must not be + freed. */ +static struct line_header * +dwarf_decode_line_header (unsigned int offset, bfd *abfd, + const struct comp_unit_head *cu_header) +{ + struct cleanup *back_to; + struct line_header *lh; + char *line_ptr; + int bytes_read; + int i; + char *cur_dir, *cur_file; if (dwarf_line_buffer == NULL) { complain (&dwarf2_missing_line_number_section); - return; + return 0; } - files.num_files = 0; - files.files = NULL; + /* Make sure that at least there's room for the total_length field. That + could be 12 bytes long, but we're just going to fudge that. */ + if (offset + 4 >= dwarf_line_size) + { + complain (&dwarf2_statement_list_fits_in_line_number_section); + return 0; + } - dirs.num_dirs = 0; - dirs.dirs = NULL; + lh = xmalloc (sizeof (*lh)); + memset (lh, 0, sizeof (*lh)); + back_to = make_cleanup ((make_cleanup_ftype *) free_line_header, + (void *) lh); line_ptr = dwarf_line_buffer + offset; - /* read in the prologue */ - lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read); + /* read in the header */ + lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read); line_ptr += bytes_read; - line_end = line_ptr + lh.total_length; - lh.version = read_2_bytes (abfd, line_ptr); + if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size) + { + complain (&dwarf2_statement_list_fits_in_line_number_section); + return 0; + } + lh->statement_program_end = line_ptr + lh->total_length; + lh->version = read_2_bytes (abfd, line_ptr); line_ptr += 2; - lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read); + lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read); line_ptr += bytes_read; - lh.minimum_instruction_length = read_1_byte (abfd, line_ptr); + lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; - lh.default_is_stmt = read_1_byte (abfd, line_ptr); + lh->default_is_stmt = read_1_byte (abfd, line_ptr); line_ptr += 1; - lh.line_base = read_1_signed_byte (abfd, line_ptr); + lh->line_base = read_1_signed_byte (abfd, line_ptr); line_ptr += 1; - lh.line_range = read_1_byte (abfd, line_ptr); + lh->line_range = read_1_byte (abfd, line_ptr); line_ptr += 1; - lh.opcode_base = read_1_byte (abfd, line_ptr); + lh->opcode_base = read_1_byte (abfd, line_ptr); line_ptr += 1; - lh.standard_opcode_lengths = (unsigned char *) - xmalloc (lh.opcode_base * sizeof (unsigned char)); - back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths); + lh->standard_opcode_lengths + = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char)); - lh.standard_opcode_lengths[0] = 1; - for (i = 1; i < lh.opcode_base; ++i) + lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */ + for (i = 1; i < lh->opcode_base; ++i) { - lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr); + lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr); line_ptr += 1; } @@ -3954,44 +4384,96 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL) { line_ptr += bytes_read; - if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0) - { - dirs.dirs = (char **) - xrealloc (dirs.dirs, - (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *)); - if (dirs.num_dirs == 0) - make_cleanup (free_current_contents, &dirs.dirs); - } - dirs.dirs[dirs.num_dirs++] = cur_dir; + add_include_dir (lh, cur_dir); } line_ptr += bytes_read; /* Read file name table */ while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL) { + unsigned int dir_index, mod_time, length; + line_ptr += bytes_read; - if ((files.num_files % FILE_ALLOC_CHUNK) == 0) - { - files.files = (struct fileinfo *) - xrealloc (files.files, - (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); - if (files.num_files == 0) - make_cleanup (free_current_contents, &files.files); - } - files.files[files.num_files].name = cur_file; - files.files[files.num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.files[files.num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.files[files.num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.num_files++; + + add_file_name (lh, cur_file, dir_index, mod_time, length); } line_ptr += bytes_read; + lh->statement_program_start = line_ptr; + + if (line_ptr > dwarf_line_buffer + dwarf_line_size) + complain (&dwarf2_line_header_too_long); + + discard_cleanups (back_to); + return lh; +} + +/* This function exists to work around a bug in certain compilers + (particularly GCC 2.95), in which the first line number marker of a + function does not show up until after the prologue, right before + the second line number marker. This function shifts ADDRESS down + to the beginning of the function if necessary, and is called on + addresses passed to record_line. */ + +static CORE_ADDR +check_cu_functions (CORE_ADDR address) +{ + struct function_range *fn; + + /* Find the function_range containing address. */ + if (!cu_first_fn) + return address; + + if (!cu_cached_fn) + cu_cached_fn = cu_first_fn; + + fn = cu_cached_fn; + while (fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + fn = cu_first_fn; + while (fn && fn != cu_cached_fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + return address; + + found: + if (fn->seen_line) + return address; + if (address != fn->lowpc) + complain (&dwarf2_misplaced_line_number, + (unsigned long) address, fn->name); + fn->seen_line = 1; + return fn->lowpc; +} + +/* Decode the line number information for the compilation unit whose + line number info is at OFFSET in the .debug_line section. + The compilation directory of the file is passed in COMP_DIR. */ + +static void +dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, + const struct comp_unit_head *cu_header) +{ + char *line_ptr; + char *line_end; + unsigned int i, bytes_read; + char *cur_dir; + unsigned char op_code, extended_op, adj_opcode; + + line_ptr = lh->statement_program_start; + line_end = lh->statement_program_end; /* Read the statement sequences until there's nothing left. */ while (line_ptr < line_end) @@ -4001,19 +4483,23 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, unsigned int file = 1; unsigned int line = 1; unsigned int column = 0; - int is_stmt = lh.default_is_stmt; + int is_stmt = lh->default_is_stmt; int basic_block = 0; int end_sequence = 0; /* Start a subfile for the current file of the state machine. */ - if (files.num_files >= file) + if (lh->num_file_names >= file) { - /* The file and directory tables are 0 based, the references - are 1 based. */ - dwarf2_start_subfile (files.files[file - 1].name, - (files.files[file - 1].dir - ? dirs.dirs[files.files[file - 1].dir - 1] - : comp_dir)); + /* lh->include_dirs and lh->file_names are 0-based, but the + directory and file name numbers in the statement program + are 1-based. */ + struct file_entry *fe = &lh->file_names[file - 1]; + char *dir; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + dwarf2_start_subfile (fe->name, dir); } /* Decode the table. */ @@ -4022,13 +4508,14 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, op_code = read_1_byte (abfd, line_ptr); line_ptr += 1; - if (op_code >= lh.opcode_base) + if (op_code >= lh->opcode_base) { /* Special operand. */ - adj_opcode = op_code - lh.opcode_base; - address += (adj_opcode / lh.line_range) - * lh.minimum_instruction_length; - line += lh.line_base + (adj_opcode % lh.line_range); + adj_opcode = op_code - lh->opcode_base; + address += (adj_opcode / lh->line_range) + * lh->minimum_instruction_length; + line += lh->line_base + (adj_opcode % lh->line_range); /* append row to matrix using current values */ + address = check_cu_functions (address); record_line (current_subfile, line, address); basic_block = 1; } @@ -4042,12 +4529,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, { case DW_LNE_end_sequence: end_sequence = 1; - /* Don't call record_line here. The end_sequence - instruction provides the address of the first byte - *after* the last line in the sequence; it's not the - address of any real source line. However, the GDB - linetable structure only records the starts of lines, - not the ends. This is a weakness of GDB. */ + record_line (current_subfile, 0, address); break; case DW_LNE_set_address: address = read_address (abfd, line_ptr, cu_header, &bytes_read); @@ -4055,40 +4537,36 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, address += baseaddr; break; case DW_LNE_define_file: - cur_file = read_string (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - if ((files.num_files % FILE_ALLOC_CHUNK) == 0) - { - files.files = (struct fileinfo *) - xrealloc (files.files, - (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); - if (files.num_files == 0) - make_cleanup (free_current_contents, &files.files); - } - files.files[files.num_files].name = cur_file; - files.files[files.num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.files[files.num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.files[files.num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.num_files++; + { + char *cur_file; + unsigned int dir_index, mod_time, length; + + cur_file = read_string (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + dir_index = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + mod_time = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + length = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + add_file_name (lh, cur_file, dir_index, mod_time, length); + } break; default: complain (&dwarf2_mangled_line_number_section); - goto done; + return; } break; case DW_LNS_copy: + address = check_cu_functions (address); record_line (current_subfile, line, address); basic_block = 0; break; case DW_LNS_advance_pc: - address += lh.minimum_instruction_length + address += lh->minimum_instruction_length * read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; break; @@ -4097,15 +4575,21 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, line_ptr += bytes_read; break; case DW_LNS_set_file: - /* The file and directory tables are 0 based, the references - are 1 based. */ - file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - dwarf2_start_subfile - (files.files[file - 1].name, - (files.files[file - 1].dir - ? dirs.dirs[files.files[file - 1].dir - 1] - : comp_dir)); + { + /* lh->include_dirs and lh->file_names are 0-based, + but the directory and file name numbers in the + statement program are 1-based. */ + struct file_entry *fe; + char *dir; + file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + fe = &lh->file_names[file - 1]; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + dwarf2_start_subfile (fe->name, dir); + } break; case DW_LNS_set_column: column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); @@ -4123,8 +4607,8 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, length since special opcode 255 would have scaled the the increment. */ case DW_LNS_const_add_pc: - address += (lh.minimum_instruction_length - * ((255 - lh.opcode_base) / lh.line_range)); + address += (lh->minimum_instruction_length + * ((255 - lh->opcode_base) / lh->line_range)); break; case DW_LNS_fixed_advance_pc: address += read_2_bytes (abfd, line_ptr); @@ -4133,7 +4617,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, default: { /* Unknown standard opcode, ignore it. */ int i; - for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) + for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++) { (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; @@ -4142,8 +4626,6 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, } } } -done: - do_cleanups (back_to); } /* Start a subfile for DWARF. FILENAME is the name of the file and @@ -4205,7 +4687,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, char *name; struct attribute *attr = NULL; struct attribute *attr2 = NULL; - CORE_ADDR addr; + CORE_ADDR addr = 0; name = dwarf2_linkage_name (die); if (name) @@ -4289,8 +4771,22 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, attr2 = dwarf_attr (die, DW_AT_external); if (attr2 && (DW_UNSND (attr2) != 0)) { - SYMBOL_VALUE_ADDRESS (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + SYMBOL_VALUE_ADDRESS (sym) = + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + } + else if (attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_location", + "external variable"); + } add_symbol_to_list (sym, &global_symbols); /* In shared libraries the address of the variable @@ -4313,8 +4809,23 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, } else { - SYMBOL_VALUE (sym) = addr = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + SYMBOL_VALUE (sym) = addr = + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + } + else if (attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) + { + complain (&dwarf2_complex_location_expr); + } + else + { + complain (&dwarf2_invalid_attrib_class, "DW_AT_location", + "external variable"); + addr = 0; + } add_symbol_to_list (sym, list_in_scope); if (optimized_out) { @@ -5156,6 +5667,8 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; + case DW_AT_GNU_vector: + return "DW_AT_GNU_vector"; default: return "DW_AT_"; } @@ -5512,6 +6025,18 @@ dwarf_stack_op_name (register unsigned op) return "DW_OP_xderef_size"; case DW_OP_nop: return "DW_OP_nop"; + /* DWARF 3 extensions. */ + case DW_OP_push_object_address: + return "DW_OP_push_object_address"; + case DW_OP_call2: + return "DW_OP_call2"; + case DW_OP_call4: + return "DW_OP_call4"; + case DW_OP_call_ref: + return "DW_OP_call_ref"; + /* GNU extensions. */ + case DW_OP_GNU_push_tls_address: + return "DW_OP_GNU_push_tls_address"; default: return "OP_"; } @@ -5598,9 +6123,31 @@ dwarf_cfi_name (register unsigned cfi_opc) return "DW_CFA_def_cfa_register"; case DW_CFA_def_cfa_offset: return "DW_CFA_def_cfa_offset"; + + /* DWARF 3 */ + case DW_CFA_def_cfa_expression: + return "DW_CFA_def_cfa_expression"; + case DW_CFA_expression: + return "DW_CFA_expression"; + case DW_CFA_offset_extended_sf: + return "DW_CFA_offset_extended_sf"; + case DW_CFA_def_cfa_sf: + return "DW_CFA_def_cfa_sf"; + case DW_CFA_def_cfa_offset_sf: + return "DW_CFA_def_cfa_offset_sf"; + /* SGI/MIPS specific */ case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8"; + + /* GNU extensions */ + case DW_CFA_GNU_window_save: + return "DW_CFA_GNU_window_save"; + case DW_CFA_GNU_args_size: + return "DW_CFA_GNU_args_size"; + case DW_CFA_GNU_negative_offset_extended: + return "DW_CFA_GNU_negative_offset_extended"; + default: return "DW_CFA_"; } @@ -5612,29 +6159,29 @@ dump_die (struct die_info *die) { unsigned int i; - fprintf (stderr, "Die: %s (abbrev = %d, offset = %d)\n", + fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n", dwarf_tag_name (die->tag), die->abbrev, die->offset); - fprintf (stderr, "\thas children: %s\n", + fprintf_unfiltered (gdb_stderr, "\thas children: %s\n", dwarf_bool_name (die->has_children)); - fprintf (stderr, "\tattributes:\n"); + fprintf_unfiltered (gdb_stderr, "\tattributes:\n"); for (i = 0; i < die->num_attrs; ++i) { - fprintf (stderr, "\t\t%s (%s) ", + fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ", dwarf_attr_name (die->attrs[i].name), dwarf_form_name (die->attrs[i].form)); switch (die->attrs[i].form) { case DW_FORM_ref_addr: case DW_FORM_addr: - fprintf (stderr, "address: "); + fprintf_unfiltered (gdb_stderr, "address: "); print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr); break; case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_block: case DW_FORM_block1: - fprintf (stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size); + fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size); break; case DW_FORM_data1: case DW_FORM_data2: @@ -5645,30 +6192,30 @@ dump_die (struct die_info *die) case DW_FORM_ref4: case DW_FORM_udata: case DW_FORM_sdata: - fprintf (stderr, "constant: %ld", DW_UNSND (&die->attrs[i])); + fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i])); break; case DW_FORM_string: case DW_FORM_strp: - fprintf (stderr, "string: \"%s\"", + fprintf_unfiltered (gdb_stderr, "string: \"%s\"", DW_STRING (&die->attrs[i]) ? DW_STRING (&die->attrs[i]) : ""); break; case DW_FORM_flag: if (DW_UNSND (&die->attrs[i])) - fprintf (stderr, "flag: TRUE"); + fprintf_unfiltered (gdb_stderr, "flag: TRUE"); else - fprintf (stderr, "flag: FALSE"); + fprintf_unfiltered (gdb_stderr, "flag: FALSE"); break; case DW_FORM_indirect: /* the reader will have reduced the indirect form to the "base form" so this form should not occur */ - fprintf (stderr, "unexpected attribute form: DW_FORM_indirect"); + fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect"); break; default: - fprintf (stderr, "unsupported attribute form: %d.", + fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.", die->attrs[i].form); } - fprintf (stderr, "\n"); + fprintf_unfiltered (gdb_stderr, "\n"); } } @@ -5819,6 +6366,41 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, op = data[i++]; switch (op) { + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + stack[++stacki] = op - DW_OP_lit0; + break; + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: @@ -5859,12 +6441,6 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, isreg = 1; unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read); i += bytes_read; -#if defined(HARRIS_TARGET) && defined(_M88K) - /* The Harris 88110 gdb ports have long kept their special reg - numbers between their gp-regs and their x-regs. This is - not how our dwarf is generated. Punt. */ - unsnd += 6; -#endif stack[++stacki] = unsnd; break; @@ -5977,6 +6553,11 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, i += bytes_read; break; + case DW_OP_dup: + stack[stacki + 1] = stack[stacki]; + stacki++; + break; + case DW_OP_plus: stack[stacki - 1] += stack[stacki]; stacki--; @@ -5988,7 +6569,7 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, break; case DW_OP_minus: - stack[stacki - 1] = stack[stacki] - stack[stacki - 1]; + stack[stacki - 1] -= stack[stacki]; stacki--; break; @@ -6046,3 +6627,388 @@ dwarf_alloc_die (void) memset (die, 0, sizeof (struct die_info)); return (die); } + + +/* Macro support. */ + + +/* Return the full name of file number I in *LH's file name table. + Use COMP_DIR as the name of the current directory of the + compilation. The result is allocated using xmalloc; the caller is + responsible for freeing it. */ +static char * +file_full_name (int file, struct line_header *lh, const char *comp_dir) +{ + struct file_entry *fe = &lh->file_names[file - 1]; + + if (IS_ABSOLUTE_PATH (fe->name)) + return xstrdup (fe->name); + else + { + const char *dir; + int dir_len; + char *full_name; + + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + + if (dir) + { + dir_len = strlen (dir); + full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1); + strcpy (full_name, dir); + full_name[dir_len] = '/'; + strcpy (full_name + dir_len + 1, fe->name); + return full_name; + } + else + return xstrdup (fe->name); + } +} + + +static struct macro_source_file * +macro_start_file (int file, int line, + struct macro_source_file *current_file, + const char *comp_dir, + struct line_header *lh, struct objfile *objfile) +{ + /* The full name of this source file. */ + char *full_name = file_full_name (file, lh, comp_dir); + + /* We don't create a macro table for this compilation unit + at all until we actually get a filename. */ + if (! pending_macros) + pending_macros = new_macro_table (&objfile->symbol_obstack, + objfile->macro_cache); + + if (! current_file) + /* If we have no current file, then this must be the start_file + directive for the compilation unit's main source file. */ + current_file = macro_set_main (pending_macros, full_name); + else + current_file = macro_include (current_file, line, full_name); + + xfree (full_name); + + return current_file; +} + + +/* Copy the LEN characters at BUF to a xmalloc'ed block of memory, + followed by a null byte. */ +static char * +copy_string (const char *buf, int len) +{ + char *s = xmalloc (len + 1); + memcpy (s, buf, len); + s[len] = '\0'; + + return s; +} + + +static const char * +consume_improper_spaces (const char *p, const char *body) +{ + if (*p == ' ') + { + complain (&dwarf2_macro_spaces_in_definition, body); + + while (*p == ' ') + p++; + } + + return p; +} + + +static void +parse_macro_definition (struct macro_source_file *file, int line, + const char *body) +{ + const char *p; + + /* The body string takes one of two forms. For object-like macro + definitions, it should be: + + " " + + For function-like macro definitions, it should be: + + "() " + or + "(" ( "," ) * ") " + + Spaces may appear only where explicitly indicated, and in the + . + + The Dwarf 2 spec says that an object-like macro's name is always + followed by a space, but versions of GCC around March 2002 omit + the space when the macro's definition is the empty string. + + The Dwarf 2 spec says that there should be no spaces between the + formal arguments in a function-like macro's formal argument list, + but versions of GCC around March 2002 include spaces after the + commas. */ + + + /* Find the extent of the macro name. The macro name is terminated + by either a space or null character (for an object-like macro) or + an opening paren (for a function-like macro). */ + for (p = body; *p; p++) + if (*p == ' ' || *p == '(') + break; + + if (*p == ' ' || *p == '\0') + { + /* It's an object-like macro. */ + int name_len = p - body; + char *name = copy_string (body, name_len); + const char *replacement; + + if (*p == ' ') + replacement = body + name_len + 1; + else + { + complain (&dwarf2_macro_malformed_definition, body); + replacement = body + name_len; + } + + macro_define_object (file, line, name, replacement); + + xfree (name); + } + else if (*p == '(') + { + /* It's a function-like macro. */ + char *name = copy_string (body, p - body); + int argc = 0; + int argv_size = 1; + char **argv = xmalloc (argv_size * sizeof (*argv)); + + p++; + + p = consume_improper_spaces (p, body); + + /* Parse the formal argument list. */ + while (*p && *p != ')') + { + /* Find the extent of the current argument name. */ + const char *arg_start = p; + + while (*p && *p != ',' && *p != ')' && *p != ' ') + p++; + + if (! *p || p == arg_start) + complain (&dwarf2_macro_malformed_definition, + body); + else + { + /* Make sure argv has room for the new argument. */ + if (argc >= argv_size) + { + argv_size *= 2; + argv = xrealloc (argv, argv_size * sizeof (*argv)); + } + + argv[argc++] = copy_string (arg_start, p - arg_start); + } + + p = consume_improper_spaces (p, body); + + /* Consume the comma, if present. */ + if (*p == ',') + { + p++; + + p = consume_improper_spaces (p, body); + } + } + + if (*p == ')') + { + p++; + + if (*p == ' ') + /* Perfectly formed definition, no complaints. */ + macro_define_function (file, line, name, + argc, (const char **) argv, + p + 1); + else if (*p == '\0') + { + /* Complain, but do define it. */ + complain (&dwarf2_macro_malformed_definition, body); + macro_define_function (file, line, name, + argc, (const char **) argv, + p); + } + else + /* Just complain. */ + complain (&dwarf2_macro_malformed_definition, body); + } + else + /* Just complain. */ + complain (&dwarf2_macro_malformed_definition, body); + + xfree (name); + { + int i; + + for (i = 0; i < argc; i++) + xfree (argv[i]); + } + xfree (argv); + } + else + complain (&dwarf2_macro_malformed_definition, body); +} + + +static void +dwarf_decode_macros (struct line_header *lh, unsigned int offset, + char *comp_dir, bfd *abfd, + const struct comp_unit_head *cu_header, + struct objfile *objfile) +{ + char *mac_ptr, *mac_end; + struct macro_source_file *current_file = 0; + + if (dwarf_macinfo_buffer == NULL) + { + complain (&dwarf2_missing_macinfo_section); + return; + } + + mac_ptr = dwarf_macinfo_buffer + offset; + mac_end = dwarf_macinfo_buffer + dwarf_macinfo_size; + + for (;;) + { + enum dwarf_macinfo_record_type macinfo_type; + + /* Do we at least have room for a macinfo type byte? */ + if (mac_ptr >= mac_end) + { + complain (&dwarf2_macros_too_long); + return; + } + + macinfo_type = read_1_byte (abfd, mac_ptr); + mac_ptr++; + + switch (macinfo_type) + { + /* A zero macinfo type indicates the end of the macro + information. */ + case 0: + return; + + case DW_MACINFO_define: + case DW_MACINFO_undef: + { + int bytes_read; + int line; + char *body; + + line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + body = read_string (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + if (! current_file) + complain (&dwarf2_macro_outside_file, + macinfo_type == DW_MACINFO_define ? "definition" : + macinfo_type == DW_MACINFO_undef ? "undefinition" : + "something-or-other", + body); + else + { + if (macinfo_type == DW_MACINFO_define) + parse_macro_definition (current_file, line, body); + else if (macinfo_type == DW_MACINFO_undef) + macro_undef (current_file, line, body); + } + } + break; + + case DW_MACINFO_start_file: + { + int bytes_read; + int line, file; + + line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + current_file = macro_start_file (file, line, + current_file, comp_dir, + lh, objfile); + } + break; + + case DW_MACINFO_end_file: + if (! current_file) + complain (&dwarf2_macro_unmatched_end_file); + else + { + current_file = current_file->included_by; + if (! current_file) + { + enum dwarf_macinfo_record_type next_type; + + /* GCC circa March 2002 doesn't produce the zero + type byte marking the end of the compilation + unit. Complain if it's not there, but exit no + matter what. */ + + /* Do we at least have room for a macinfo type byte? */ + if (mac_ptr >= mac_end) + { + complain (&dwarf2_macros_too_long); + return; + } + + /* We don't increment mac_ptr here, so this is just + a look-ahead. */ + next_type = read_1_byte (abfd, mac_ptr); + if (next_type != 0) + complain (&dwarf2_macros_not_terminated); + + return; + } + } + break; + + case DW_MACINFO_vendor_ext: + { + int bytes_read; + int constant; + char *string; + + constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + string = read_string (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + /* We don't recognize any vendor extensions. */ + } + break; + } + } +} + +/* Check if the attribute's form is a DW_FORM_block* + if so return true else false. */ +static int +attr_form_is_block (struct attribute *attr) +{ + return (attr == NULL ? 0 : + attr->form == DW_FORM_block1 + || attr->form == DW_FORM_block2 + || attr->form == DW_FORM_block4 + || attr->form == DW_FORM_block); +}