X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarfread.c;h=bd92ad15be4a2533fc2bc8ea7ea550b0bd9e73ab;hb=987622b523bff105af2ebdfb33ef7c4c99b03def;hp=709b9584e72361329779509eb2ec52b30c2a0d42;hpb=b2bebdb0f184e8c09c59f9efdc06aea8514939de;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 709b9584e7..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,13 +17,10 @@ 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: Do we need to generate dependencies in partial symtabs? (Perhaps we don't need to). @@ -42,12 +39,10 @@ other things to work on, if you get bored. :-) */ #include "defs.h" -#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" @@ -56,18 +51,12 @@ other things to work on, if you get bored. :-) #include "complaints.h" #include -#include -#include +#include "gdb_string.h" #ifndef NO_SYS_FILE #include #endif -/* FIXME -- convert this to SEEK_SET a la POSIX, move to config files. */ -#ifndef L_SET -#define L_SET 0 -#endif - /* Some macros to provide DIE info for complaints. */ #define DIE_ID (curdie!=NULL ? curdie->die_ref : 0) @@ -180,10 +169,6 @@ struct complaint not_row_major = "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0 }; -#ifndef R_FP /* FIXME */ -#define R_FP 14 /* Kludge to get frame pointer register number */ -#endif - typedef unsigned int DIE_REF; /* Reference to a DIE */ #ifndef GCC_PRODUCER @@ -202,6 +187,11 @@ typedef unsigned int DIE_REF; /* Reference to a DIE */ #define CHILL_PRODUCER "GNU Chill " #endif +/* 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 integer in the target environment which is used as a signed integer @@ -305,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; @@ -332,7 +322,12 @@ 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 (once this is done, @@ -343,37 +338,29 @@ static CORE_ADDR baseaddr; /* Add to each symbol value */ 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 { - file_ptr 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 */ - file_ptr 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) @@ -452,7 +439,7 @@ static const struct language_defn *cu_language_defn; static int attribute_size PARAMS ((unsigned int)); -static unsigned long +static CORE_ADDR target_to_host PARAMS ((char *, int, int, struct objfile *)); static void @@ -481,9 +468,6 @@ scan_compilation_units PARAMS ((char *, char *, file_ptr, 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 *)); @@ -570,10 +554,6 @@ synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *, static int locval PARAMS ((char *)); -static void -record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type, - struct objfile *)); - static void set_cu_language PARAMS ((struct dieinfo *)); @@ -746,7 +726,7 @@ dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize, dbsize = dbfsize; dbbase = xmalloc (dbsize); dbroff = 0; - if ((bfd_seek (abfd, dbfoff, L_SET) != 0) || + if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) || (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) { free (dbbase); @@ -779,39 +759,6 @@ dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize, 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 @@ -1028,9 +975,7 @@ struct_type (dip, thisdie, enddie, objfile) int n; struct dieinfo mbr; char *nextdie; -#if !BITS_BIG_ENDIAN int anonymous_size; -#endif if ((type = lookup_utype (dip -> die_ref)) == NULL) { @@ -1103,39 +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) { - 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 + /* 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) { - /* 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); + 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; } - list -> field.bitpos += - anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; } -#endif nfields++; break; default: @@ -1632,7 +1585,6 @@ read_subroutine_type (dip, thisdie, enddie) /* 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; } @@ -2027,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: @@ -2184,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 @@ -2211,7 +2177,6 @@ locval (loc) auto long stack[64]; int stacki; char *end; - long regno; int loc_atom_code; int loc_value_size; @@ -2223,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; @@ -2237,28 +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; - - complain (&basereg_not_handled, DIE_ID, DIE_NAME, regno); - } + stack[++stacki] = 0; break; case OP_ADDR: /* push address (relocated address) */ @@ -2330,7 +2291,7 @@ read_ofile_symtab (pst) foffset = DBFOFF(pst) + dbroff; base_section_offsets = pst->section_offsets; baseaddr = ANOFFSET (pst->section_offsets, 0); - if (bfd_seek (abfd, foffset, L_SET) || + if (bfd_seek (abfd, foffset, SEEK_SET) || (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) { free (dbbase); @@ -2346,7 +2307,7 @@ read_ofile_symtab (pst) lnbase = NULL; if (LNFOFF (pst)) { - if (bfd_seek (abfd, LNFOFF (pst), L_SET) || + if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) || (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) != sizeof (lnsizedata))) { @@ -2355,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), L_SET) || + if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) || (bfd_read (lnbase, lnsize, 1, abfd) != lnsize)) { free (lnbase); @@ -2411,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]); } @@ -2432,7 +2393,7 @@ psymtab_to_symtab_1 (pst) { printf_filtered ("%d DIE's, sorting...", diecount); wrap_here (""); - fflush (stdout); + gdb_flush (gdb_stdout); } sort_symtab_syms (pst -> symtab); do_cleanups (old_chain); @@ -2482,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); @@ -2500,7 +2461,7 @@ dwarf_psymtab_to_symtab (pst) if (info_verbose) { printf_filtered ("done.\n"); - fflush (stdout); + gdb_flush (gdb_stdout); } } } @@ -2509,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 @@ -2627,16 +2540,12 @@ 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, 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, @@ -2664,6 +2573,9 @@ add_partial_symbol (dip, objfile) 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, @@ -3023,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 { @@ -3048,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; @@ -3821,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) {