X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarfread.c;h=bd92ad15be4a2533fc2bc8ea7ea550b0bd9e73ab;hb=987622b523bff105af2ebdfb33ef7c4c99b03def;hp=fde32e64527e47e2798d9470605e0b012f77f0be;hpb=cd46ffad4ecefe7d91323f901882483e32ca2f71;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index fde32e6452..bd92ad15be 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -1,5 +1,5 @@ /* DWARF debugging format support for GDB. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. Portions based on dbxread.c, mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port. @@ -17,14 +17,12 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* -FIXME: Figure out how to get the frame pointer register number in the -execution environment of the target. Remove R_FP kludge - -FIXME: Add generation of dependencies list to partial symtab code. +FIXME: Do we need to generate dependencies in partial symtabs? +(Perhaps we don't need to). FIXME: Resolve minor differences between what information we put in the partial symbol table and what dbxread puts in. For example, we don't yet @@ -41,30 +39,136 @@ other things to work on, if you get bored. :-) */ #include "defs.h" -#include -#include -#include - -#include "bfd.h" #include "symtab.h" #include "gdbtypes.h" #include "symfile.h" #include "objfiles.h" -#include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */ #include "elf/dwarf.h" #include "buildsym.h" #include "demangle.h" +#include "expression.h" /* Needed for enum exp_opcode in language.h, sigh... */ +#include "language.h" +#include "complaints.h" -#ifdef MAINTENANCE /* Define to 1 to compile in some maintenance stuff */ -#define SQUAWK(stuff) dwarfwarn stuff -#else -#define SQUAWK(stuff) -#endif +#include +#include "gdb_string.h" -#ifndef R_FP /* FIXME */ -#define R_FP 14 /* Kludge to get frame pointer register number */ +#ifndef NO_SYS_FILE +#include #endif +/* Some macros to provide DIE info for complaints. */ + +#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0) +#define DIE_NAME (curdie!=NULL && curdie->at_name!=NULL) ? curdie->at_name : "" + +/* Complaints that can be issued during DWARF debug info reading. */ + +struct complaint no_bfd_get_N = +{ + "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", 0, 0 +}; + +struct complaint malformed_die = +{ + "DIE @ 0x%x \"%s\", malformed DIE, bad length (%d bytes)", 0, 0 +}; + +struct complaint bad_die_ref = +{ + "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", 0, 0 +}; + +struct complaint unknown_attribute_form = +{ + "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", 0, 0 +}; + +struct complaint unknown_attribute_length = +{ + "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", 0, 0 +}; + +struct complaint unexpected_fund_type = +{ + "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", 0, 0 +}; + +struct complaint unknown_type_modifier = +{ + "DIE @ 0x%x \"%s\", unknown type modifier %u", 0, 0 +}; + +struct complaint volatile_ignored = +{ + "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", 0, 0 +}; + +struct complaint const_ignored = +{ + "DIE @ 0x%x \"%s\", type modifier 'const' ignored", 0, 0 +}; + +struct complaint botched_modified_type = +{ + "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", 0, 0 +}; + +struct complaint op_deref2 = +{ + "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%x not handled", 0, 0 +}; + +struct complaint op_deref4 = +{ + "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%x not handled", 0, 0 +}; + +struct complaint basereg_not_handled = +{ + "DIE @ 0x%x \"%s\", BASEREG %d not handled", 0, 0 +}; + +struct complaint dup_user_type_allocation = +{ + "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", 0, 0 +}; + +struct complaint dup_user_type_definition = +{ + "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", 0, 0 +}; + +struct complaint missing_tag = +{ + "DIE @ 0x%x \"%s\", missing class, structure, or union tag", 0, 0 +}; + +struct complaint bad_array_element_type = +{ + "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", 0, 0 +}; + +struct complaint subscript_data_items = +{ + "DIE @ 0x%x \"%s\", can't decode subscript data items", 0, 0 +}; + +struct complaint unhandled_array_subscript_format = +{ + "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", 0, 0 +}; + +struct complaint unknown_array_subscript_format = +{ + "DIE @ 0x%x \"%s\", unknown array subscript format %x", 0, 0 +}; + +struct complaint not_row_major = +{ + "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0 +}; + typedef unsigned int DIE_REF; /* Reference to a DIE */ #ifndef GCC_PRODUCER @@ -76,15 +180,17 @@ typedef unsigned int DIE_REF; /* Reference to a DIE */ #endif #ifndef LCC_PRODUCER -#define LCC_PRODUCER "NCR C/C++ " +#define LCC_PRODUCER "NCR C/C++" #endif -#ifndef CFRONT_PRODUCER -#define CFRONT_PRODUCER "CFRONT " /* A wild a** guess... */ +#ifndef CHILL_PRODUCER +#define CHILL_PRODUCER "GNU Chill " #endif -#define STREQ(a,b) (strcmp(a,b)==0) -#define STREQN(a,b,n) (strncmp(a,b,n)==0) +/* Provide a default mapping from a DWARF register number to a gdb REGNUM. */ +#ifndef DWARF_REG_TO_REGNUM +#define DWARF_REG_TO_REGNUM(num) (num) +#endif /* Flags to target_to_host() that tell whether or not the data object is expected to be signed. Used, for example, when fetching a signed @@ -189,8 +295,8 @@ struct dieinfo { unsigned long at_bit_size; BLOCK * at_element_list; unsigned long at_stmt_list; - unsigned long at_low_pc; - unsigned long at_high_pc; + CORE_ADDR at_low_pc; + CORE_ADDR at_high_pc; unsigned long at_language; unsigned long at_member; unsigned long at_discr; @@ -204,6 +310,7 @@ struct dieinfo { char * at_prototyped; unsigned int has_at_low_pc:1; unsigned int has_at_stmt_list:1; + unsigned int has_at_byte_size:1; unsigned int short_element_list:1; }; @@ -211,50 +318,49 @@ static int diecount; /* Approximate count of dies for compilation unit */ static struct dieinfo *curdie; /* For warnings and such */ static char *dbbase; /* Base pointer to dwarf info */ +static int dbsize; /* Size of dwarf info in bytes */ static int dbroff; /* Relative offset from start of .debug section */ static char *lnbase; /* Base pointer to line section */ static int isreg; /* Kludge to identify register variables */ -static int offreg; /* Kludge to identify basereg references */ +static int optimized_out; /* Kludge to identify optimized out variables */ +/* Kludge to identify basereg references. Nonzero if we have an offset + relative to a basereg. */ +static int offreg; +/* Which base register is it relative to? */ +static int basereg; /* This value is added to each symbol value. FIXME: Generalize to - the section_offsets structure used by dbxread. */ + the section_offsets structure used by dbxread (once this is done, + pass the appropriate section number to end_symtab). */ static CORE_ADDR baseaddr; /* Add to each symbol value */ /* The section offsets used in the current psymtab or symtab. FIXME, only used to pass one value (baseaddr) at the moment. */ static struct section_offsets *base_section_offsets; -/* Each partial symbol table entry contains a pointer to private data for the - read_symtab() function to use when expanding a partial symbol table entry - to a full symbol table entry. For DWARF debugging info, this data is - contained in the following structure and macros are provided for easy - access to the members given a pointer to a partial symbol table entry. - - dbfoff Always the absolute file offset to the start of the ".debug" - section for the file containing the DIE's being accessed. - - dbroff Relative offset from the start of the ".debug" access to the - first DIE to be accessed. When building the partial symbol - table, this value will be zero since we are accessing the - entire ".debug" section. When expanding a partial symbol - table entry, this value will be the offset to the first - DIE for the compilation unit containing the symbol that - triggers the expansion. - - dblength The size of the chunk of DIE's being examined, in bytes. - - lnfoff The absolute file offset to the line table fragment. Ignored - when building partial symbol tables, but used when expanding - them, and contains the absolute file offset to the fragment - of the ".line" section containing the line numbers for the - current compilation unit. - */ +/* We put a pointer to this structure in the read_symtab_private field + of the psymtab. */ struct dwfinfo { - int dbfoff; /* Absolute file offset to start of .debug section */ - int dbroff; /* Relative offset from start of .debug section */ - int dblength; /* Size of the chunk of DIE's being examined */ - int lnfoff; /* Absolute file offset to line table fragment */ + /* Always the absolute file offset to the start of the ".debug" + section for the file containing the DIE's being accessed. */ + file_ptr dbfoff; + /* Relative offset from the start of the ".debug" section to the + first DIE to be accessed. When building the partial symbol + table, this value will be zero since we are accessing the + entire ".debug" section. When expanding a partial symbol + table entry, this value will be the offset to the first + DIE for the compilation unit containing the symbol that + triggers the expansion. */ + int dbroff; + /* The size of the chunk of DIE's being examined, in bytes. */ + int dblength; + /* The absolute file offset to the line table fragment. Ignored + when building partial symbol tables, but used when expanding + them, and contains the absolute file offset to the fragment + of the ".line" section containing the line numbers for the + current compilation unit. */ + file_ptr lnfoff; }; #define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff) @@ -294,18 +400,46 @@ struct pending **list_in_scope = &file_symbols; we can divide any DIE offset by 4 to obtain a unique index into this fixed size array. Since each element is a 4 byte pointer, it takes exactly as much memory to hold this array as to hold the DWARF info for a given - compilation unit. But it gets freed as soon as we are done with it. */ + compilation unit. But it gets freed as soon as we are done with it. + This has worked well in practice, as a reasonable tradeoff between memory + consumption and speed, without having to resort to much more complicated + algorithms. */ static struct type **utypes; /* Pointer to array of user type pointers */ static int numutypes; /* Max number of user type pointers */ +/* Maintain an array of referenced fundamental types for the current + compilation unit being read. For DWARF version 1, we have to construct + the fundamental types on the fly, since no information about the + fundamental types is supplied. Each such fundamental type is created by + calling a language dependent routine to create the type, and then a + pointer to that type is then placed in the array at the index specified + by it's FT_ value. The array has a fixed size set by the + FT_NUM_MEMBERS compile time constant, which is the number of predefined + fundamental types gdb knows how to construct. */ + +static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */ + +/* Record the language for the compilation unit which is currently being + processed. We know it once we have seen the TAG_compile_unit DIE, + and we need it while processing the DIE's for that compilation unit. + It is eventually saved in the symtab structure, but we don't finalize + the symtab struct until we have processed all the DIE's for the + compilation unit. We also need to get and save a pointer to the + language struct for this language, so we can call the language + dependent routines for doing things such as creating fundamental + types. */ + +static enum language cu_language; +static const struct language_defn *cu_language_defn; + /* Forward declarations of static functions so we don't have to worry about ordering within this file. */ static int attribute_size PARAMS ((unsigned int)); -static unsigned long +static CORE_ADDR target_to_host PARAMS ((char *, int, int, struct objfile *)); static void @@ -324,22 +458,16 @@ static void read_lexical_block_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); -static void -dwarfwarn (); - static void scan_partial_symbols PARAMS ((char *, char *, struct objfile *)); static void -scan_compilation_units PARAMS ((char *, char *, char *, unsigned int, - unsigned int, struct objfile *)); +scan_compilation_units PARAMS ((char *, char *, file_ptr, + file_ptr, struct objfile *)); static void add_partial_symbol PARAMS ((struct dieinfo *, struct objfile *)); -static void -init_psymbol_list PARAMS ((struct objfile *, int)); - static void basicdieinfo PARAMS ((struct dieinfo *, char *, struct objfile *)); @@ -352,7 +480,7 @@ dwarf_psymtab_to_symtab PARAMS ((struct partial_symtab *)); static void psymtab_to_symtab_1 PARAMS ((struct partial_symtab *)); -static struct symtab * +static void read_ofile_symtab PARAMS ((struct partial_symtab *)); static void @@ -366,7 +494,7 @@ static struct type * decode_array_element_type PARAMS ((char *)); static struct type * -decode_subscr_data PARAMS ((char *, char *)); +decode_subscript_data_item PARAMS ((char *, char *)); static void dwarf_read_array_type PARAMS ((struct dieinfo *)); @@ -374,6 +502,9 @@ dwarf_read_array_type PARAMS ((struct dieinfo *)); static void read_tag_pointer_type PARAMS ((struct dieinfo *dip)); +static void +read_tag_string_type PARAMS ((struct dieinfo *dip)); + static void read_subroutine_type PARAMS ((struct dieinfo *, char *, char *)); @@ -416,12 +547,134 @@ alloc_utype PARAMS ((DIE_REF, struct type *)); static struct symbol * new_symbol PARAMS ((struct dieinfo *, struct objfile *)); +static void +synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *, + struct type *)); + static int locval PARAMS ((char *)); static void -record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type, - struct objfile *)); +set_cu_language PARAMS ((struct dieinfo *)); + +static struct type * +dwarf_fundamental_type PARAMS ((struct objfile *, int)); + + +/* + +LOCAL FUNCTION + + dwarf_fundamental_type -- lookup or create a fundamental type + +SYNOPSIS + + struct type * + dwarf_fundamental_type (struct objfile *objfile, int typeid) + +DESCRIPTION + + DWARF version 1 doesn't supply any fundamental type information, + so gdb has to construct such types. It has a fixed number of + fundamental types that it knows how to construct, which is the + union of all types that it knows how to construct for all languages + that it knows about. These are enumerated in gdbtypes.h. + + As an example, assume we find a DIE that references a DWARF + fundamental type of FT_integer. We first look in the ftypes + array to see if we already have such a type, indexed by the + gdb internal value of FT_INTEGER. If so, we simply return a + pointer to that type. If not, then we ask an appropriate + language dependent routine to create a type FT_INTEGER, using + defaults reasonable for the current target machine, and install + that type in ftypes for future reference. + +RETURNS + + Pointer to a fundamental type. + +*/ + +static struct type * +dwarf_fundamental_type (objfile, typeid) + struct objfile *objfile; + int typeid; +{ + if (typeid < 0 || typeid >= FT_NUM_MEMBERS) + { + error ("internal error - invalid fundamental type id %d", typeid); + } + + /* Look for this particular type in the fundamental type vector. If one is + not found, create and install one appropriate for the current language + and the current target machine. */ + + if (ftypes[typeid] == NULL) + { + ftypes[typeid] = cu_language_defn -> la_fund_type(objfile, typeid); + } + + return (ftypes[typeid]); +} + +/* + +LOCAL FUNCTION + + set_cu_language -- set local copy of language for compilation unit + +SYNOPSIS + + void + set_cu_language (struct dieinfo *dip) + +DESCRIPTION + + Decode the language attribute for a compilation unit DIE and + remember what the language was. We use this at various times + when processing DIE's for a given compilation unit. + +RETURNS + + No return value. + + */ + +static void +set_cu_language (dip) + struct dieinfo *dip; +{ + switch (dip -> at_language) + { + case LANG_C89: + case LANG_C: + cu_language = language_c; + break; + case LANG_C_PLUS_PLUS: + cu_language = language_cplus; + break; + case LANG_CHILL: + cu_language = language_chill; + break; + case LANG_MODULA2: + cu_language = language_m2; + break; + case LANG_ADA83: + case LANG_COBOL74: + case LANG_COBOL85: + case LANG_FORTRAN77: + case LANG_FORTRAN90: + case LANG_PASCAL83: + /* We don't know anything special about these yet. */ + cu_language = language_unknown; + break; + default: + /* If no at_language, try to deduce one from the filename */ + cu_language = deduce_language_from_filename (dip -> at_name); + break; + } + cu_language_defn = language_def (cu_language); +} /* @@ -431,18 +684,17 @@ GLOBAL FUNCTION SYNOPSIS - void dwarf_build_psymtabs (int desc, char *filename, + void dwarf_build_psymtabs (struct objfile *objfile, struct section_offsets *section_offsets, - int mainline, unsigned int dbfoff, unsigned int dbsize, - unsigned int lnoffset, unsigned int lnsize, - struct objfile *objfile) + int mainline, file_ptr dbfoff, unsigned int dbfsize, + file_ptr lnoffset, unsigned int lnsize) DESCRIPTION This function is called upon to build partial symtabs from files containing DIE's (Dwarf Information Entries) and DWARF line numbers. - It is passed a file descriptor for an open file containing the DIES + It is passed a bfd* containing the DIES and line number information, the corresponding filename for that file, a base address for relocating the symbols, a flag indicating whether or not this debugging information is from a "main symbol @@ -457,28 +709,28 @@ RETURNS */ void -dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize, - lnoffset, lnsize, objfile) - int desc; - char *filename; +dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize, + lnoffset, lnsize) + struct objfile *objfile; struct section_offsets *section_offsets; int mainline; - unsigned int dbfoff; - unsigned int dbsize; - unsigned int lnoffset; + file_ptr dbfoff; + unsigned int dbfsize; + file_ptr lnoffset; unsigned int lnsize; - struct objfile *objfile; { + bfd *abfd = objfile->obfd; struct cleanup *back_to; current_objfile = objfile; + dbsize = dbfsize; dbbase = xmalloc (dbsize); dbroff = 0; - if ((lseek (desc, dbfoff, 0) != dbfoff) || - (read (desc, dbbase, dbsize) != dbsize)) + if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) || + (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) { free (dbbase); - error ("can't read DWARF data from '%s'", filename); + error ("can't read DWARF data from '%s'", bfd_get_filename (abfd)); } back_to = make_cleanup (free, dbbase); @@ -501,95 +753,12 @@ dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize, table entry for each one. Save enough information about each compilation unit to locate the full DWARF information later. */ - scan_compilation_units (filename, dbbase, dbbase + dbsize, - dbfoff, lnoffset, objfile); + scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile); do_cleanups (back_to); current_objfile = NULL; } - -/* - -LOCAL FUNCTION - - record_minimal_symbol -- add entry to gdb's minimal symbol table - -SYNOPSIS - - static void record_minimal_symbol (char *name, CORE_ADDR address, - enum minimal_symbol_type ms_type, - struct objfile *objfile) - -DESCRIPTION - - Given a pointer to the name of a symbol that should be added to the - minimal symbol table, and the address associated with that - symbol, records this information for later use in building the - minimal symbol table. - - */ - -static void -record_minimal_symbol (name, address, ms_type, objfile) - char *name; - CORE_ADDR address; - enum minimal_symbol_type ms_type; - struct objfile *objfile; -{ - name = obsavestring (name, strlen (name), &objfile -> symbol_obstack); - prim_record_minimal_symbol (name, address, ms_type); -} - -/* - -LOCAL FUNCTION - - dwarfwarn -- issue a DWARF related warning - -DESCRIPTION - - Issue warnings about DWARF related things that aren't serious enough - to warrant aborting with an error, but should not be ignored either. - This includes things like detectable corruption in DIE's, missing - DIE's, unimplemented features, etc. - - In general, running across tags or attributes that we don't recognize - is not considered to be a problem and we should not issue warnings - about such. - -NOTES - - We mostly follow the example of the error() routine, but without - returning to command level. It is arguable about whether warnings - should be issued at all, and if so, where they should go (stdout or - stderr). - - We assume that curdie is valid and contains at least the basic - information for the DIE where the problem was noticed. -*/ - -static void -dwarfwarn (va_alist) - va_dcl -{ - va_list ap; - char *fmt; - - va_start (ap); - fmt = va_arg (ap, char *); - warning_setup (); - fprintf (stderr, "warning: DWARF ref 0x%x: ", curdie -> die_ref); - if (curdie -> at_name) - { - fprintf (stderr, "'%s': ", curdie -> at_name); - } - vfprintf (stderr, fmt, ap); - fprintf (stderr, "\n"); - fflush (stderr); - va_end (ap); -} - /* LOCAL FUNCTION @@ -657,7 +826,7 @@ lookup_utype (die_ref) utypeidx = (die_ref - dbroff) / 4; if ((utypeidx < 0) || (utypeidx >= numutypes)) { - dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); + complain (&bad_die_ref, DIE_ID, DIE_NAME); } else { @@ -700,13 +869,13 @@ alloc_utype (die_ref, utypep) typep = utypes + utypeidx; if ((utypeidx < 0) || (utypeidx >= numutypes)) { - utypep = lookup_fundamental_type (current_objfile, FT_INTEGER); - dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); + utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER); + complain (&bad_die_ref, DIE_ID, DIE_NAME); } else if (*typep != NULL) { utypep = *typep; - SQUAWK (("internal error: dup user type allocation")); + complain (&dup_user_type_allocation, DIE_ID, DIE_NAME); } else { @@ -763,7 +932,7 @@ decode_die_type (dip) } else { - type = lookup_fundamental_type (current_objfile, FT_INTEGER); + type = dwarf_fundamental_type (current_objfile, FT_INTEGER); } return (type); } @@ -804,9 +973,9 @@ struct_type (dip, thisdie, enddie, objfile) struct nextfield *new; int nfields = 0; int n; - char *tpart1; struct dieinfo mbr; char *nextdie; + int anonymous_size; if ((type = lookup_utype (dip -> die_ref)) == NULL) { @@ -816,19 +985,19 @@ struct_type (dip, thisdie, enddie, objfile) INIT_CPLUS_SPECIFIC(type); switch (dip -> die_tag) { + case TAG_class_type: + TYPE_CODE (type) = TYPE_CODE_CLASS; + break; case TAG_structure_type: TYPE_CODE (type) = TYPE_CODE_STRUCT; - tpart1 = "struct"; break; case TAG_union_type: TYPE_CODE (type) = TYPE_CODE_UNION; - tpart1 = "union"; break; default: /* Should never happen */ TYPE_CODE (type) = TYPE_CODE_UNDEF; - tpart1 = "???"; - SQUAWK (("missing structure or union tag")); + complain (&missing_tag, DIE_ID, DIE_NAME); break; } /* Some compilers try to be helpful by inventing "fake" names for @@ -838,13 +1007,15 @@ struct_type (dip, thisdie, enddie, objfile) && *dip -> at_name != '~' && *dip -> at_name != '.') { - TYPE_NAME (type) = obconcat (&objfile -> type_obstack, - tpart1, " ", dip -> at_name); - } - if (dip -> at_byte_size != 0) - { - TYPE_LENGTH (type) = dip -> at_byte_size; + TYPE_TAG_NAME (type) = obconcat (&objfile -> type_obstack, + "", "", dip -> at_name); } + /* Use whatever size is known. Zero is a valid size. We might however + wish to check has_at_byte_size to make sure that some byte size was + given explicitly, but DWARF doesn't specify that explicit sizes of + zero have to present, so complaining about missing sizes should + probably not be the default. */ + TYPE_LENGTH (type) = dip -> at_byte_size; thisdie += dip -> die_length; while (thisdie < enddie) { @@ -877,25 +1048,47 @@ struct_type (dip, thisdie, enddie, objfile) list -> field.bitpos = 8 * locval (mbr.at_location); /* Handle bit fields. */ list -> field.bitsize = mbr.at_bit_size; -#if BITS_BIG_ENDIAN - /* For big endian bits, the at_bit_offset gives the additional - bit offset from the MSB of the containing anonymous object to - the MSB of the field. We don't have to do anything special - since we don't need to know the size of the anonymous object. */ - list -> field.bitpos += mbr.at_bit_offset; -#else - /* For little endian bits, we need to have a non-zero at_bit_size, - so that we know we are in fact dealing with a bitfield. Compute - the bit offset to the MSB of the anonymous object, subtract off - the number of bits from the MSB of the field to the MSB of the - object, and then subtract off the number of bits of the field - itself. The result is the bit offset of the LSB of the field. */ - if (mbr.at_bit_size > 0) + if (BITS_BIG_ENDIAN) { - list -> field.bitpos += - mbr.at_byte_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; + /* For big endian bits, the at_bit_offset gives the + additional bit offset from the MSB of the containing + anonymous object to the MSB of the field. We don't + have to do anything special since we don't need to + know the size of the anonymous object. */ + list -> field.bitpos += mbr.at_bit_offset; + } + else + { + /* For little endian bits, we need to have a non-zero + at_bit_size, so that we know we are in fact dealing + with a bitfield. Compute the bit offset to the MSB + of the anonymous object, subtract off the number of + bits from the MSB of the field to the MSB of the + object, and then subtract off the number of bits of + the field itself. The result is the bit offset of + the LSB of the field. */ + if (mbr.at_bit_size > 0) + { + if (mbr.has_at_byte_size) + { + /* The size of the anonymous object containing + the bit field is explicit, so use the + indicated size (in bytes). */ + anonymous_size = mbr.at_byte_size; + } + else + { + /* The size of the anonymous object containing + the bit field matches the size of an object + of the bit field's type. DWARF allows + at_byte_size to be left out in such cases, as + a debug information size optimization. */ + anonymous_size = TYPE_LENGTH (list -> field.type); + } + list -> field.bitpos += + anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; + } } -#endif nfields++; break; default: @@ -917,8 +1110,7 @@ struct_type (dip, thisdie, enddie, objfile) { TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile -> type_obstack, - sizeof (struct field) * nfields); + TYPE_ALLOC (type, sizeof (struct field) * nfields); /* Copy the saved-up fields into the field vector. */ for (n = nfields; list; list = list -> next) { @@ -975,9 +1167,14 @@ read_structure_scope (dip, thisdie, enddie, objfile) type = struct_type (dip, thisdie, enddie, objfile); if (!(TYPE_FLAGS (type) & TYPE_FLAG_STUB)) { - if ((sym = new_symbol (dip, objfile)) != NULL) + sym = new_symbol (dip, objfile); + if (sym != NULL) { SYMBOL_TYPE (sym) = type; + if (cu_language == language_cplus) + { + synthesize_typedef (dip, objfile, type); + } } } } @@ -1016,8 +1213,8 @@ decode_array_element_type (scan) scan += SIZEOF_ATTRIBUTE; if ((nbytes = attribute_size (attribute)) == -1) { - SQUAWK (("bad array element type attribute 0x%x", attribute)); - typep = lookup_fundamental_type (current_objfile, FT_INTEGER); + complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); + typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); } else { @@ -1043,8 +1240,8 @@ decode_array_element_type (scan) typep = decode_mod_u_d_type (scan); break; default: - SQUAWK (("bad array element type attribute 0x%x", attribute)); - typep = lookup_fundamental_type (current_objfile, FT_INTEGER); + complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); + typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); break; } } @@ -1055,11 +1252,12 @@ decode_array_element_type (scan) LOCAL FUNCTION - decode_subscr_data -- decode array subscript and element type data + decode_subscript_data_item -- decode array subscript item SYNOPSIS - static struct type *decode_subscr_data (char *scan, char *end) + static struct type * + decode_subscript_data_item (char *scan, char *end) DESCRIPTION @@ -1071,9 +1269,21 @@ DESCRIPTION source (I.E. leftmost dimension first, next to leftmost second, etc). + The data items describing each array dimension consist of four + parts: (1) a format specifier, (2) type type of the subscript + index, (3) a description of the low bound of the array dimension, + and (4) a description of the high bound of the array dimension. + + The last data item is the description of the type of each of + the array elements. + We are passed a pointer to the start of the block of bytes - containing the data items, and a pointer to the first byte past - the data. This function decodes the data and returns a type. + containing the remaining data items, and a pointer to the first + byte past the data. This function recursively decodes the + remaining data items and returns a type. + + If we somehow fail to decode some data, we complain about it + and return a type "array of int". BUGS FIXME: This code only implements the forms currently used @@ -1084,12 +1294,14 @@ BUGS */ static struct type * -decode_subscr_data (scan, end) +decode_subscript_data_item (scan, end) char *scan; char *end; { - struct type *typep = NULL; - struct type *nexttype; + struct type *typep = NULL; /* Array type we are building */ + struct type *nexttype; /* Type of each element (may be array) */ + struct type *indextype; /* Type of this index */ + struct type *rangetype; unsigned int format; unsigned short fundtype; unsigned long lowbound; @@ -1107,32 +1319,23 @@ decode_subscr_data (scan, end) case FMT_FT_C_C: fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED, current_objfile); + indextype = decode_fund_type (fundtype); scan += SIZEOF_FMT_FT; - if (fundtype != FT_integer && fundtype != FT_signed_integer - && fundtype != FT_unsigned_integer) - { - SQUAWK (("array subscripts must be integral types, not type 0x%x", - fundtype)); - } - else + nbytes = TARGET_FT_LONG_SIZE (current_objfile); + lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile); + scan += nbytes; + highbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile); + scan += nbytes; + nexttype = decode_subscript_data_item (scan, end); + if (nexttype == NULL) { - nbytes = TARGET_FT_LONG_SIZE (current_objfile); - lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, - current_objfile); - scan += nbytes; - highbound = target_to_host (scan, nbytes, GET_UNSIGNED, - current_objfile); - scan += nbytes; - nexttype = decode_subscr_data (scan, end); - if (nexttype != NULL) - { - typep = alloc_type (current_objfile); - TYPE_CODE (typep) = TYPE_CODE_ARRAY; - TYPE_LENGTH (typep) = TYPE_LENGTH (nexttype); - TYPE_LENGTH (typep) *= (highbound - lowbound) + 1; - TYPE_TARGET_TYPE (typep) = nexttype; - } + /* Munged subscript data or other problem, fake it. */ + complain (&subscript_data_items, DIE_ID, DIE_NAME); + nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); } + rangetype = create_range_type ((struct type *) NULL, indextype, + lowbound, highbound); + typep = create_array_type ((struct type *) NULL, nexttype, rangetype); break; case FMT_FT_C_X: case FMT_FT_X_C: @@ -1141,10 +1344,16 @@ decode_subscr_data (scan, end) case FMT_UT_C_X: case FMT_UT_X_C: case FMT_UT_X_X: - SQUAWK (("array subscript format 0x%x not handled yet", format)); + complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format); + nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); + rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); + typep = create_array_type ((struct type *) NULL, nexttype, rangetype); break; default: - SQUAWK (("unknown array subscript format %x", format)); + complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format); + nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); + rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); + typep = create_array_type ((struct type *) NULL, nexttype, rangetype); break; } return (typep); @@ -1180,7 +1389,7 @@ dwarf_read_array_type (dip) if (dip -> at_ordering != ORD_row_major) { /* FIXME: Can gdb even handle column major arrays? */ - SQUAWK (("array not row major; not handled correctly")); + complain (¬_row_major, DIE_ID, DIE_NAME); } if ((sub = dip -> at_subscr_data) != NULL) { @@ -1188,30 +1397,29 @@ dwarf_read_array_type (dip) blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile); subend = sub + nbytes + blocksz; sub += nbytes; - type = decode_subscr_data (sub, subend); - if (type == NULL) + type = decode_subscript_data_item (sub, subend); + if ((utype = lookup_utype (dip -> die_ref)) == NULL) { - if ((utype = lookup_utype (dip -> die_ref)) == NULL) - { - utype = alloc_utype (dip -> die_ref, NULL); - } - TYPE_CODE (utype) = TYPE_CODE_ARRAY; - TYPE_TARGET_TYPE (utype) = - lookup_fundamental_type (current_objfile, FT_INTEGER); - TYPE_LENGTH (utype) = 1 * TYPE_LENGTH (TYPE_TARGET_TYPE (utype)); + /* Install user defined type that has not been referenced yet. */ + alloc_utype (dip -> die_ref, type); + } + else if (TYPE_CODE (utype) == TYPE_CODE_UNDEF) + { + /* Ick! A forward ref has already generated a blank type in our + slot, and this type probably already has things pointing to it + (which is what caused it to be created in the first place). + If it's just a place holder we can plop our fully defined type + on top of it. We can't recover the space allocated for our + new type since it might be on an obstack, but we could reuse + it if we kept a list of them, but it might not be worth it + (FIXME). */ + *utype = *type; } else { - if ((utype = lookup_utype (dip -> die_ref)) == NULL) - { - alloc_utype (dip -> die_ref, type); - } - else - { - TYPE_CODE (utype) = TYPE_CODE_ARRAY; - TYPE_LENGTH (utype) = TYPE_LENGTH (type); - TYPE_TARGET_TYPE (utype) = TYPE_TARGET_TYPE (type); - } + /* Double ick! Not only is a type already in our slot, but + someone has decorated it. Complain and leave it alone. */ + complain (&dup_user_type_definition, DIE_ID, DIE_NAME); } } } @@ -1261,6 +1469,69 @@ read_tag_pointer_type (dip) /* +LOCAL FUNCTION + + read_tag_string_type -- read TAG_string_type DIE + +SYNOPSIS + + static void read_tag_string_type (struct dieinfo *dip) + +DESCRIPTION + + Extract all information from a 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 attribute to reference it. + */ + +static void +read_tag_string_type (dip) + struct dieinfo *dip; +{ + struct type *utype; + struct type *indextype; + struct type *rangetype; + unsigned long lowbound = 0; + unsigned long highbound; + + if (dip -> has_at_byte_size) + { + /* A fixed bounds string */ + highbound = dip -> at_byte_size - 1; + } + else + { + /* A varying length string. Stub for now. (FIXME) */ + highbound = 1; + } + indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER); + rangetype = create_range_type ((struct type *) NULL, indextype, lowbound, + highbound); + + utype = lookup_utype (dip -> die_ref); + if (utype == NULL) + { + /* No type defined, go ahead and create a blank one to use. */ + utype = alloc_utype (dip -> die_ref, (struct type *) NULL); + } + else + { + /* Already a type in our slot due to a forward reference. Make sure it + is a blank one. If not, complain and leave it alone. */ + if (TYPE_CODE (utype) != TYPE_CODE_UNDEF) + { + complain (&dup_user_type_definition, DIE_ID, DIE_NAME); + return; + } + } + + /* Create the string type using the blank type we either found or created. */ + utype = create_string_type (utype, rangetype); +} + +/* + LOCAL FUNCTION read_subroutine_type -- process TAG_subroutine_type dies @@ -1309,15 +1580,18 @@ read_subroutine_type (dip, thisdie, enddie) ftype = lookup_function_type (type); alloc_utype (dip -> die_ref, ftype); } - else + else if (TYPE_CODE (ftype) == TYPE_CODE_UNDEF) { /* We have an existing partially constructed type, so bash it into the correct type. */ TYPE_TARGET_TYPE (ftype) = type; - TYPE_FUNCTION_TYPE (type) = ftype; TYPE_LENGTH (ftype) = 1; TYPE_CODE (ftype) = TYPE_CODE_FUNC; } + else + { + complain (&dup_user_type_definition, DIE_ID, DIE_NAME); + } } /* @@ -1354,9 +1628,14 @@ read_enumeration (dip, thisdie, enddie, objfile) struct symbol *sym; type = enum_type (dip, objfile); - if ((sym = new_symbol (dip, objfile)) != NULL) + sym = new_symbol (dip, objfile); + if (sym != NULL) { SYMBOL_TYPE (sym) = type; + if (cu_language == language_cplus) + { + synthesize_typedef (dip, objfile, type); + } } } @@ -1424,8 +1703,8 @@ enum_type (dip, objfile) && *dip -> at_name != '~' && *dip -> at_name != '.') { - TYPE_NAME (type) = obconcat (&objfile -> type_obstack, "enum", - " ", dip -> at_name); + TYPE_TAG_NAME (type) = obconcat (&objfile -> type_obstack, + "", "", dip -> at_name); } if (dip -> at_byte_size != 0) { @@ -1465,6 +1744,7 @@ enum_type (dip, objfile) memset (sym, 0, sizeof (struct symbol)); SYMBOL_NAME (sym) = create_name (list -> field.name, &objfile->symbol_obstack); + SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_TYPE (sym) = type; @@ -1567,6 +1847,7 @@ handle_producer (producer) processing_gcc_compilation = STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) + || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER)) || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)); /* Select a demangling style if we can identify the producer and if @@ -1574,8 +1855,7 @@ handle_producer (producer) is not auto. We also leave the demangling style alone if we find a gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */ -#if 1 /* Works, but is experimental. -fnf */ - if (current_demangling_style == auto_demangling) + if (AUTO_DEMANGLING) { if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))) { @@ -1585,12 +1865,7 @@ handle_producer (producer) { set_demangling_style (LUCID_DEMANGLING_STYLE_STRING); } - else if (STREQN (producer, CFRONT_PRODUCER, strlen (CFRONT_PRODUCER))) - { - set_demangling_style (CFRONT_DEMANGLING_STYLE_STRING); - } } -#endif } @@ -1632,6 +1907,7 @@ read_file_scope (dip, thisdie, enddie, objfile) objfile -> ei.entry_file_lowpc = dip -> at_low_pc; objfile -> ei.entry_file_highpc = dip -> at_high_pc; } + set_cu_language (dip); if (dip -> at_producer != NULL) { handle_producer (dip -> at_producer); @@ -1640,23 +1916,16 @@ read_file_scope (dip, thisdie, enddie, objfile) utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *)); back_to = make_cleanup (free, utypes); memset (utypes, 0, numutypes * sizeof (struct type *)); + memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *)); start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc); decode_line_numbers (lnbase); process_dies (thisdie + dip -> die_length, enddie, objfile); - symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile); - /* FIXME: The following may need to be expanded for other languages */ - switch (dip -> at_language) + + symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile, 0); + if (symtab != NULL) { - case LANG_C89: - case LANG_C: - symtab -> language = language_c; - break; - case LANG_C_PLUS_PLUS: - symtab -> language = language_cplus; - break; - default: - ; - } + symtab -> language = cu_language; + } do_cleanups (back_to); utypes = NULL; numutypes = 0; @@ -1710,10 +1979,21 @@ process_dies (thisdie, enddie, objfile) { nextdie = thisdie + di.die_length; } +#ifdef SMASH_TEXT_ADDRESS + /* I think that these are always text, not data, addresses. */ + SMASH_TEXT_ADDRESS (di.at_low_pc); + SMASH_TEXT_ADDRESS (di.at_high_pc); +#endif switch (di.die_tag) { case TAG_compile_unit: - read_file_scope (&di, thisdie, nextdie, objfile); + /* Skip Tag_compile_unit if we are already inside a compilation + unit, we are unable to handle nested compilation units + properly (FIXME). */ + if (current_subfile == NULL) + read_file_scope (&di, thisdie, nextdie, objfile); + else + nextdie = thisdie + di.die_length; break; case TAG_global_subroutine: case TAG_subroutine: @@ -1725,6 +2005,7 @@ process_dies (thisdie, enddie, objfile) case TAG_lexical_block: read_lexical_block_scope (&di, thisdie, nextdie, objfile); break; + case TAG_class_type: case TAG_structure_type: case TAG_union_type: read_structure_scope (&di, thisdie, nextdie, objfile); @@ -1741,6 +2022,9 @@ process_dies (thisdie, enddie, objfile) case TAG_pointer_type: read_tag_pointer_type (&di); break; + case TAG_string_type: + read_tag_string_type (&di); + break; default: new_symbol (&di, objfile); break; @@ -1863,6 +2147,9 @@ DESCRIPTION Given pointer to a string of bytes that define a location, compute the location and return the value. + A location description containing no atoms indicates that the + object is optimized out. The global optimized_out flag is set for + those, the return value is meaningless. When computing values involving the current value of the frame pointer, the value zero is used, which results in a value relative to the frame @@ -1890,7 +2177,6 @@ locval (loc) auto long stack[64]; int stacki; char *end; - long regno; int loc_atom_code; int loc_value_size; @@ -1902,9 +2188,11 @@ locval (loc) stack[stacki] = 0; isreg = 0; offreg = 0; + optimized_out = 1; loc_value_size = TARGET_FT_LONG_SIZE (current_objfile); while (loc < end) { + optimized_out = 0; loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED, current_objfile); loc += SIZEOF_LOC_ATOM_CODE; @@ -1916,27 +2204,22 @@ locval (loc) break; case OP_REG: /* push register (number) */ - stack[++stacki] = target_to_host (loc, loc_value_size, - GET_UNSIGNED, current_objfile); + stack[++stacki] + = DWARF_REG_TO_REGNUM (target_to_host (loc, loc_value_size, + GET_UNSIGNED, + current_objfile)); loc += loc_value_size; isreg = 1; break; case OP_BASEREG: /* push value of register (number) */ - /* Actually, we compute the value as if register has 0 */ + /* Actually, we compute the value as if register has 0, so the + value ends up being the offset from that register. */ offreg = 1; - regno = target_to_host (loc, loc_value_size, GET_UNSIGNED, - current_objfile); + basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED, + current_objfile); loc += loc_value_size; - if (regno == R_FP) - { - stack[++stacki] = 0; - } - else - { - stack[++stacki] = 0; - SQUAWK (("BASEREG %d not handled!", regno)); - } + stack[++stacki] = 0; break; case OP_ADDR: /* push address (relocated address) */ @@ -1952,10 +2235,10 @@ locval (loc) break; case OP_DEREF2: /* pop, deref and push 2 bytes (as a long) */ - SQUAWK (("OP_DEREF2 address 0x%x not handled", stack[stacki])); + complain (&op_deref2, DIE_ID, DIE_NAME, stack[stacki]); break; case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */ - SQUAWK (("OP_DEREF4 address 0x%x not handled", stack[stacki])); + complain (&op_deref4, DIE_ID, DIE_NAME, stack[stacki]); break; case OP_ADD: /* pop top 2 items, add, push result */ stack[stacki - 1] += stack[stacki]; @@ -1974,25 +2257,24 @@ LOCAL FUNCTION SYNOPSIS - static struct symtab *read_ofile_symtab (struct partial_symtab *pst) + static void read_ofile_symtab (struct partial_symtab *pst) DESCRIPTION When expanding a partial symbol table entry to a full symbol table entry, this is the function that gets called to read in the symbols - for the compilation unit. - - Returns a pointer to the newly constructed symtab (which is now - the new first one on the objfile's symtab list). + for the compilation unit. A pointer to the newly constructed symtab, + which is now the new first one on the objfile's symtab list, is + stashed in the partial symbol table entry. */ -static struct symtab * +static void read_ofile_symtab (pst) struct partial_symtab *pst; { struct cleanup *back_to; unsigned long lnsize; - int foffset; + file_ptr foffset; bfd *abfd; char lnsizedata[SIZEOF_LINETBL_LENGTH]; @@ -2003,13 +2285,14 @@ read_ofile_symtab (pst) unit, seek to the location in the file, and read in all the DIE's. */ diecount = 0; - dbbase = xmalloc (DBLENGTH(pst)); + dbsize = DBLENGTH (pst); + dbbase = xmalloc (dbsize); dbroff = DBROFF(pst); foffset = DBFOFF(pst) + dbroff; base_section_offsets = pst->section_offsets; baseaddr = ANOFFSET (pst->section_offsets, 0); - if (bfd_seek (abfd, foffset, 0) || - (bfd_read (dbbase, DBLENGTH(pst), 1, abfd) != DBLENGTH(pst))) + if (bfd_seek (abfd, foffset, SEEK_SET) || + (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) { free (dbbase); error ("can't read DWARF data"); @@ -2024,7 +2307,7 @@ read_ofile_symtab (pst) lnbase = NULL; if (LNFOFF (pst)) { - if (bfd_seek (abfd, LNFOFF (pst), 0) || + if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) || (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) != sizeof (lnsizedata))) { @@ -2033,7 +2316,7 @@ read_ofile_symtab (pst) lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED, pst -> objfile); lnbase = xmalloc (lnsize); - if (bfd_seek (abfd, LNFOFF (pst), 0) || + if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) || (bfd_read (lnbase, lnsize, 1, abfd) != lnsize)) { free (lnbase); @@ -2042,10 +2325,10 @@ read_ofile_symtab (pst) make_cleanup (free, lnbase); } - process_dies (dbbase, dbbase + DBLENGTH(pst), pst -> objfile); + process_dies (dbbase, dbbase + dbsize, pst -> objfile); do_cleanups (back_to); current_objfile = NULL; - return (pst -> objfile -> symtabs); + pst -> symtab = pst -> objfile -> symtabs; } /* @@ -2089,14 +2372,14 @@ psymtab_to_symtab_1 (pst) /* Inform about additional files that need to be read in. */ if (info_verbose) { - fputs_filtered (" ", stdout); + fputs_filtered (" ", gdb_stdout); wrap_here (""); - fputs_filtered ("and ", stdout); + fputs_filtered ("and ", gdb_stdout); wrap_here (""); printf_filtered ("%s...", pst -> dependencies[i] -> filename); wrap_here (""); - fflush (stdout); /* Flush output */ + gdb_flush (gdb_stdout); /* Flush output */ } psymtab_to_symtab_1 (pst -> dependencies[i]); } @@ -2105,12 +2388,12 @@ psymtab_to_symtab_1 (pst) { buildsym_init (); old_chain = make_cleanup (really_free_pendings, 0); - pst -> symtab = read_ofile_symtab (pst); + read_ofile_symtab (pst); if (info_verbose) { printf_filtered ("%d DIE's, sorting...", diecount); wrap_here (""); - fflush (stdout); + gdb_flush (gdb_stdout); } sort_symtab_syms (pst -> symtab); do_cleanups (old_chain); @@ -2160,7 +2443,7 @@ dwarf_psymtab_to_symtab (pst) { printf_filtered ("Reading in symbols for %s...", pst -> filename); - fflush (stdout); + gdb_flush (gdb_stdout); } psymtab_to_symtab_1 (pst); @@ -2178,7 +2461,7 @@ dwarf_psymtab_to_symtab (pst) if (info_verbose) { printf_filtered ("done.\n"); - fflush (stdout); + gdb_flush (gdb_stdout); } } } @@ -2187,54 +2470,6 @@ dwarf_psymtab_to_symtab (pst) /* -LOCAL FUNCTION - - init_psymbol_list -- initialize storage for partial symbols - -SYNOPSIS - - static void init_psymbol_list (struct objfile *objfile, int total_symbols) - -DESCRIPTION - - Initializes storage for all of the partial symbols that will be - created by dwarf_build_psymtabs and subsidiaries. - */ - -static void -init_psymbol_list (objfile, total_symbols) - struct objfile *objfile; - int total_symbols; -{ - /* Free any previously allocated psymbol lists. */ - - if (objfile -> global_psymbols.list) - { - mfree (objfile -> md, (PTR)objfile -> global_psymbols.list); - } - if (objfile -> static_psymbols.list) - { - mfree (objfile -> md, (PTR)objfile -> static_psymbols.list); - } - - /* Current best guess is that there are approximately a twentieth - of the total symbols (in a debugging file) are global or static - oriented symbols */ - - objfile -> global_psymbols.size = total_symbols / 10; - objfile -> static_psymbols.size = total_symbols / 10; - objfile -> global_psymbols.next = - objfile -> global_psymbols.list = (struct partial_symbol *) - xmmalloc (objfile -> md, objfile -> global_psymbols.size - * sizeof (struct partial_symbol)); - objfile -> static_psymbols.next = - objfile -> static_psymbols.list = (struct partial_symbol *) - xmmalloc (objfile -> md, objfile -> static_psymbols.size - * sizeof (struct partial_symbol)); -} - -/* - LOCAL FUNCTION add_enum_psymbol -- add enumeration members to partial symbol table @@ -2273,7 +2508,8 @@ add_enum_psymbol (dip, objfile) { scan += TARGET_FT_LONG_SIZE (objfile); ADD_PSYMBOL_TO_LIST (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST, - objfile -> static_psymbols, 0); + objfile -> static_psymbols, 0, cu_language, + objfile); scan += strlen (scan) + 1; } } @@ -2291,6 +2527,9 @@ DESCRIPTION add to a partial symbol table, finish filling in the die info and then add a partial symbol table entry for it. +NOTES + + The caller must ensure that the DIE has a valid name attribute. */ static void @@ -2301,55 +2540,54 @@ add_partial_symbol (dip, objfile) switch (dip -> die_tag) { case TAG_global_subroutine: - record_minimal_symbol (dip -> at_name, dip -> at_low_pc, mst_text, - objfile); ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), VAR_NAMESPACE, LOC_BLOCK, objfile -> global_psymbols, - dip -> at_low_pc); + dip -> at_low_pc, cu_language, objfile); break; case TAG_global_variable: - record_minimal_symbol (dip -> at_name, locval (dip -> at_location), - mst_data, objfile); ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), VAR_NAMESPACE, LOC_STATIC, objfile -> global_psymbols, - 0); + 0, cu_language, objfile); break; case TAG_subroutine: ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), VAR_NAMESPACE, LOC_BLOCK, objfile -> static_psymbols, - dip -> at_low_pc); + dip -> at_low_pc, cu_language, objfile); break; case TAG_local_variable: ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), VAR_NAMESPACE, LOC_STATIC, objfile -> static_psymbols, - 0); + 0, cu_language, objfile); break; case TAG_typedef: ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), VAR_NAMESPACE, LOC_TYPEDEF, objfile -> static_psymbols, - 0); + 0, cu_language, objfile); break; + case TAG_class_type: case TAG_structure_type: case TAG_union_type: + case TAG_enumeration_type: + /* Do not add opaque aggregate definitions to the psymtab. */ + if (!dip -> has_at_byte_size) + break; ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), STRUCT_NAMESPACE, LOC_TYPEDEF, objfile -> static_psymbols, - 0); - break; - case TAG_enumeration_type: - if (dip -> at_name) + 0, cu_language, objfile); + if (cu_language == language_cplus) { + /* For C++, these implicitly act as typedefs as well. */ ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - STRUCT_NAMESPACE, LOC_TYPEDEF, + VAR_NAMESPACE, LOC_TYPEDEF, objfile -> static_psymbols, - 0); + 0, cu_language, objfile); } - add_enum_psymbol (dip, objfile); break; } } @@ -2364,15 +2602,50 @@ DESCRIPTION Process the DIE's within a single compilation unit, looking for interesting DIE's that contribute to the partial symbol table entry - for this compilation unit. Since we cannot follow any sibling - chains without reading the complete DIE info for every DIE, - it is probably faster to just sequentially check each one to - see if it is one of the types we are interested in, and if so, - then extract all the attributes info and generate a partial - symbol table entry. + for this compilation unit. NOTES + There are some DIE's that may appear both at file scope and within + the scope of a function. We are only interested in the ones at file + scope, and the only way to tell them apart is to keep track of the + scope. For example, consider the test case: + + static int i; + main () { int j; } + + for which the relevant DWARF segment has the structure: + + 0x51: + 0x23 global subrtn sibling 0x9b + name main + fund_type FT_integer + low_pc 0x800004cc + high_pc 0x800004d4 + + 0x74: + 0x23 local var sibling 0x97 + name j + fund_type FT_integer + location OP_BASEREG 0xe + OP_CONST 0xfffffffc + OP_ADD + 0x97: + 0x4 + + 0x9b: + 0x1d local var sibling 0xb8 + name i + fund_type FT_integer + location OP_ADDR 0x800025dc + + 0xb8: + 0x4 + + We want to include the symbol 'i' in the partial symbol table, but + not the symbol 'j'. In essence, we want to skip all the dies within + the scope of a TAG_global_subroutine DIE. + Don't attempt to add anonymous structures or unions since they have no name. Anonymous enumerations however are processed, because we want to extract their member names (the check for a tag name is @@ -2390,6 +2663,7 @@ scan_partial_symbols (thisdie, enddie, objfile) struct objfile *objfile; { char *nextdie; + char *temp; struct dieinfo di; while (thisdie < enddie) @@ -2408,6 +2682,29 @@ scan_partial_symbols (thisdie, enddie, objfile) { case TAG_global_subroutine: case TAG_subroutine: + completedieinfo (&di, objfile); + if (di.at_name && (di.has_at_low_pc || di.at_location)) + { + add_partial_symbol (&di, objfile); + /* If there is a sibling attribute, adjust the nextdie + pointer to skip the entire scope of the subroutine. + Apply some sanity checking to make sure we don't + overrun or underrun the range of remaining DIE's */ + if (di.at_sibling != 0) + { + temp = dbbase + di.at_sibling - dbroff; + if ((temp < thisdie) || (temp >= enddie)) + { + complain (&bad_die_ref, DIE_ID, DIE_NAME, + di.at_sibling); + } + else + { + nextdie = temp; + } + } + } + break; case TAG_global_variable: case TAG_local_variable: completedieinfo (&di, objfile); @@ -2417,6 +2714,7 @@ scan_partial_symbols (thisdie, enddie, objfile) } break; case TAG_typedef: + case TAG_class_type: case TAG_structure_type: case TAG_union_type: completedieinfo (&di, objfile); @@ -2427,7 +2725,11 @@ scan_partial_symbols (thisdie, enddie, objfile) break; case TAG_enumeration_type: completedieinfo (&di, objfile); - add_partial_symbol (&di, objfile); + if (di.at_name) + { + add_partial_symbol (&di, objfile); + } + add_enum_psymbol (&di, objfile); break; } } @@ -2479,12 +2781,11 @@ RETURNS */ static void -scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) - char *filename; +scan_compilation_units (thisdie, enddie, dbfoff, lnoffset, objfile) char *thisdie; char *enddie; - unsigned int dbfoff; - unsigned int lnoffset; + file_ptr dbfoff; + file_ptr lnoffset; struct objfile *objfile; { char *nextdie; @@ -2492,7 +2793,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) struct partial_symtab *pst; int culength; int curoff; - int curlnoffset; + file_ptr curlnoffset; while (thisdie < enddie) { @@ -2508,6 +2809,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) else { completedieinfo (&di, objfile); + set_cu_language (&di); if (di.at_sibling != 0) { nextdie = dbbase + di.at_sibling - dbroff; @@ -2522,8 +2824,8 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) /* First allocate a new partial symbol table structure */ - pst = start_psymtab_common (objfile, base_section_offsets, di.at_name, - di.at_low_pc, + pst = start_psymtab_common (objfile, base_section_offsets, + di.at_name, di.at_low_pc, objfile -> global_psymbols.next, objfile -> static_psymbols.next); @@ -2585,11 +2887,20 @@ new_symbol (dip, objfile) sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip -> at_name, &objfile->symbol_obstack); + SYMBOL_NAME (sym) = create_name (dip -> at_name, + &objfile->symbol_obstack); /* default assumptions */ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_TYPE (sym) = decode_die_type (dip); + + /* If this symbol is from a C++ compilation, then attempt to cache the + demangled form for future reference. This is a typical time versus + space tradeoff, that was decided in favor of time because it sped up + C++ symbol lookups by a factor of about 20. */ + + SYMBOL_LANGUAGE (sym) = cu_language; + SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile -> symbol_obstack); switch (dip -> die_tag) { case TAG_label: @@ -2624,13 +2935,18 @@ new_symbol (dip, objfile) { SYMBOL_VALUE (sym) = locval (dip -> at_location); add_symbol_to_list (sym, list_in_scope); - if (isreg) + if (optimized_out) + { + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; + } + else if (isreg) { SYMBOL_CLASS (sym) = LOC_REGISTER; } else if (offreg) { - SYMBOL_CLASS (sym) = LOC_LOCAL; + SYMBOL_CLASS (sym) = LOC_BASEREG; + SYMBOL_BASEREG (sym) = basereg; } else { @@ -2649,6 +2965,11 @@ new_symbol (dip, objfile) { SYMBOL_CLASS (sym) = LOC_REGPARM; } + else if (offreg) + { + SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; + SYMBOL_BASEREG (sym) = basereg; + } else { SYMBOL_CLASS (sym) = LOC_ARG; @@ -2658,6 +2979,7 @@ new_symbol (dip, objfile) /* From varargs functions; gdb doesn't seem to have any interest in this information, so just ignore it for now. (FIXME?) */ break; + case TAG_class_type: case TAG_structure_type: case TAG_union_type: case TAG_enumeration_type: @@ -2682,6 +3004,51 @@ new_symbol (dip, objfile) /* +LOCAL FUNCTION + + synthesize_typedef -- make a symbol table entry for a "fake" typedef + +SYNOPSIS + + static void synthesize_typedef (struct dieinfo *dip, + struct objfile *objfile, + struct type *type); + +DESCRIPTION + + Given a pointer to a DWARF information entry, synthesize a typedef + for the name in the DIE, using the specified type. + + This is used for C++ class, structs, unions, and enumerations to + set up the tag name as a type. + + */ + +static void +synthesize_typedef (dip, objfile, type) + struct dieinfo *dip; + struct objfile *objfile; + struct type *type; +{ + struct symbol *sym = NULL; + + if (dip -> at_name != NULL) + { + sym = (struct symbol *) + obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); + memset (sym, 0, sizeof (struct symbol)); + SYMBOL_NAME (sym) = create_name (dip -> at_name, + &objfile->symbol_obstack); + SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); + SYMBOL_TYPE (sym) = type; + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + add_symbol_to_list (sym, list_in_scope); + } +} + +/* + LOCAL FUNCTION decode_mod_fund_type -- decode a modified fundamental type @@ -2846,8 +3213,8 @@ decode_modified_type (modifiers, modcount, mtype) } break; default: - SQUAWK (("botched modified type decoding (mtype 0x%x)", mtype)); - typep = lookup_fundamental_type (current_objfile, FT_INTEGER); + complain (&botched_modified_type, DIE_ID, DIE_NAME, mtype); + typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); break; } } @@ -2864,17 +3231,16 @@ decode_modified_type (modifiers, modcount, mtype) typep = lookup_reference_type (typep); break; case MOD_const: - SQUAWK (("type modifier 'const' ignored")); /* FIXME */ + complain (&const_ignored, DIE_ID, DIE_NAME); /* FIXME */ break; case MOD_volatile: - SQUAWK (("type modifier 'volatile' ignored")); /* FIXME */ + complain (&volatile_ignored, DIE_ID, DIE_NAME); /* FIXME */ break; default: if (!(MOD_lo_user <= (unsigned char) modifier && (unsigned char) modifier <= MOD_hi_user)) { - SQUAWK (("unknown type modifier %u", - (unsigned char) modifier)); + complain (&unknown_type_modifier, DIE_ID, DIE_NAME, modifier); } break; } @@ -2896,10 +3262,12 @@ DESCRIPTION NOTES - If we encounter a fundamental type that we are unprepared to - deal with, and it is not in the range of those types defined - as application specific types, then we issue a warning and - treat the type as an "int". + For robustness, if we are asked to translate a fundamental + type that we are unprepared to deal with, we return int so + callers can always depend upon a valid type being returned, + and so gdb may at least do something reasonable by default. + If the type is not in the range of those types defined as + application specific types, we also issue a warning. */ static struct type * @@ -2912,108 +3280,111 @@ decode_fund_type (fundtype) { case FT_void: - typep = lookup_fundamental_type (current_objfile, FT_VOID); + typep = dwarf_fundamental_type (current_objfile, FT_VOID); break; case FT_boolean: /* Was FT_set in AT&T version */ - typep = lookup_fundamental_type (current_objfile, FT_BOOLEAN); + typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN); break; case FT_pointer: /* (void *) */ - typep = lookup_fundamental_type (current_objfile, FT_VOID); + typep = dwarf_fundamental_type (current_objfile, FT_VOID); typep = lookup_pointer_type (typep); break; case FT_char: - typep = lookup_fundamental_type (current_objfile, FT_CHAR); + typep = dwarf_fundamental_type (current_objfile, FT_CHAR); break; case FT_signed_char: - typep = lookup_fundamental_type (current_objfile, FT_SIGNED_CHAR); + typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR); break; case FT_unsigned_char: - typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR); + typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR); break; case FT_short: - typep = lookup_fundamental_type (current_objfile, FT_SHORT); + typep = dwarf_fundamental_type (current_objfile, FT_SHORT); break; case FT_signed_short: - typep = lookup_fundamental_type (current_objfile, FT_SIGNED_SHORT); + typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT); break; case FT_unsigned_short: - typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT); + typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT); break; case FT_integer: - typep = lookup_fundamental_type (current_objfile, FT_INTEGER); + typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); break; case FT_signed_integer: - typep = lookup_fundamental_type (current_objfile, FT_SIGNED_INTEGER); + typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER); break; case FT_unsigned_integer: - typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER); + typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER); break; case FT_long: - typep = lookup_fundamental_type (current_objfile, FT_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_LONG); break; case FT_signed_long: - typep = lookup_fundamental_type (current_objfile, FT_SIGNED_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG); break; case FT_unsigned_long: - typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG); break; case FT_long_long: - typep = lookup_fundamental_type (current_objfile, FT_LONG_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG); break; case FT_signed_long_long: - typep = lookup_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG); break; case FT_unsigned_long_long: - typep = lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG); + typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG); break; case FT_float: - typep = lookup_fundamental_type (current_objfile, FT_FLOAT); + typep = dwarf_fundamental_type (current_objfile, FT_FLOAT); break; case FT_dbl_prec_float: - typep = lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT); + typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT); break; case FT_ext_prec_float: - typep = lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT); + typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT); break; case FT_complex: - typep = lookup_fundamental_type (current_objfile, FT_COMPLEX); + typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX); break; case FT_dbl_prec_complex: - typep = lookup_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX); + typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX); break; case FT_ext_prec_complex: - typep = lookup_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX); + typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX); break; } - if ((typep == NULL) && !(FT_lo_user <= fundtype && fundtype <= FT_hi_user)) + if (typep == NULL) { - SQUAWK (("unexpected fundamental type 0x%x", fundtype)); - typep = lookup_fundamental_type (current_objfile, FT_VOID); + typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); + if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user)) + { + complain (&unexpected_fund_type, DIE_ID, DIE_NAME, fundtype); + } } return (typep); @@ -3092,6 +3463,12 @@ NOTES that if a padding DIE is used for alignment and the amount needed is less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big enough to align to the next alignment boundry. + + We do some basic sanity checking here, such as verifying that the + length of the die would not cause it to overrun the recorded end of + the buffer holding the DIE info. If we find a DIE that is either + too small or too large, we force it's length to zero which should + cause the caller to take appropriate action. */ static void @@ -3106,9 +3483,11 @@ basicdieinfo (dip, diep, objfile) dip -> die_ref = dbroff + (diep - dbbase); dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED, objfile); - if (dip -> die_length < SIZEOF_DIE_LENGTH) + if ((dip -> die_length < SIZEOF_DIE_LENGTH) || + ((diep + dip -> die_length) > (dbbase + dbsize))) { - dwarfwarn ("malformed DIE, bad length (%d bytes)", dip -> die_length); + complain (&malformed_die, DIE_ID, DIE_NAME, dip -> die_length); + dip -> die_length = 0; } else if (dip -> die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG)) { @@ -3175,7 +3554,7 @@ completedieinfo (dip, objfile) diep += SIZEOF_ATTRIBUTE; if ((nbytes = attribute_size (attr)) == -1) { - SQUAWK (("unknown attribute length, skipped remaining attributes"));; + complain (&unknown_attribute_length, DIE_ID, DIE_NAME); diep = end; continue; } @@ -3224,6 +3603,7 @@ completedieinfo (dip, objfile) case AT_byte_size: dip -> at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED, objfile); + dip -> has_at_byte_size = 1; break; case AT_bit_size: dip -> at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED, @@ -3331,8 +3711,7 @@ completedieinfo (dip, objfile) diep += strlen (diep) + 1; break; default: - SQUAWK (("unknown attribute form (0x%x)", form)); - SQUAWK (("unknown attribute length, skipped remaining attributes"));; + complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); diep = end; break; } @@ -3364,16 +3743,18 @@ NOTES use it as signed data, then we need to explicitly sign extend the result until the bfd library is able to do this for us. + FIXME: Would a 32 bit target ever need an 8 byte result? + */ -static unsigned long +static CORE_ADDR target_to_host (from, nbytes, signextend, objfile) char *from; int nbytes; int signextend; /* FIXME: Unused */ struct objfile *objfile; { - unsigned long rtnval; + CORE_ADDR rtnval; switch (nbytes) { @@ -3390,7 +3771,7 @@ target_to_host (from, nbytes, signextend, objfile) rtnval = bfd_get_8 (objfile -> obfd, (bfd_byte *) from); break; default: - dwarfwarn ("no bfd support for %d byte data object", nbytes); + complain (&no_bfd_get_N, DIE_ID, DIE_NAME, nbytes); rtnval = 0; break; } @@ -3446,7 +3827,7 @@ attribute_size (attr) nbytes = TARGET_FT_POINTER_SIZE (objfile); break; default: - SQUAWK (("unknown attribute form (0x%x)", form)); + complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); nbytes = -1; break; }