X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fstabsread.c;h=8c03a6f7de764dc1f55f946964a02710f3376641;hb=cb74cc240dfca14768005cd4ba34dc06283c2a7c;hp=f79f35142df43854fa7caec53697acf04288cbd1;hpb=dda398c369f499c0468c4cacdae9ff3d44555832;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/stabsread.c b/gdb/stabsread.c index f79f35142d..8c03a6f7de 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -1,5 +1,5 @@ /* Support routines for decoding "stabs" debugging information format. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993 + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -16,7 +16,7 @@ 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. */ /* Support routines for reading and decoding debugging information in the "stabs" format. This format is used with many systems that use @@ -25,16 +25,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Avoid placing any object file format specific code in this file. */ #include "defs.h" +#include "gdb_string.h" #include "bfd.h" #include "obstack.h" #include "symtab.h" #include "gdbtypes.h" +#include "expression.h" #include "symfile.h" #include "objfiles.h" #include "aout/stab_gnu.h" /* We always use GNU stabs, not native */ +#include "libaout.h" +#include "aout/aout64.h" +#include "gdb-stabs.h" #include "buildsym.h" #include "complaints.h" #include "demangle.h" +#include "language.h" #include @@ -69,12 +75,19 @@ struct field_info } *fnlist; }; +static void +read_one_struct_field PARAMS ((struct field_info *, char **, char *, + struct type *, struct objfile *)); + +static char * +get_substring PARAMS ((char **, int)); + static struct type * dbx_alloc_type PARAMS ((int [2], struct objfile *)); static long read_huge_number PARAMS ((char **, int, int *)); -static struct type *error_type PARAMS ((char **)); +static struct type *error_type PARAMS ((char **, struct objfile *)); static void patch_block_stabs PARAMS ((struct pending *, struct pending_stabs *, @@ -137,6 +150,30 @@ static int read_cpp_abbrev PARAMS ((struct field_info *, char **, struct type *, struct objfile *)); +/* new functions added for cfront support */ + +static int +copy_cfront_struct_fields PARAMS ((struct field_info *, struct type *, + struct objfile *)); + +static char * +get_cfront_method_physname PARAMS ((char *)); + +static int +read_cfront_baseclasses PARAMS ((struct field_info *, char **, + struct type *, struct objfile *)); + +static int +read_cfront_static_fields PARAMS ((struct field_info *, char**, + struct type *, struct objfile *)); +static int +read_cfront_member_functions PARAMS ((struct field_info *, char **, + struct type *, struct objfile *)); + +/* end new functions added for cfront support */ + + + static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' }; static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' }; @@ -171,7 +208,7 @@ struct complaint range_type_base_complaint = {"base type %d of range type is not defined", 0, 0}; struct complaint reg_value_complaint = - {"register number too large in symbol %s", 0, 0}; + {"register number %d too large (max %d) in symbol %s", 0, 0}; struct complaint vtbl_notfound_complaint = {"virtual function table pointer not found when defining class `%s'", 0, 0}; @@ -182,6 +219,9 @@ struct complaint unrecognized_cplus_name_complaint = struct complaint rs6000_builtin_complaint = {"Unknown builtin type %d", 0, 0}; +struct complaint unresolved_sym_chain_complaint = + {"%s: common block `%s' from global_sym_chain unresolved", 0, 0}; + struct complaint stabs_general_complaint = {"%s", 0, 0}; @@ -190,14 +230,44 @@ struct complaint stabs_general_complaint = static struct type **undef_types; static int undef_types_allocated; static int undef_types_length; +static struct symbol *current_symbol = NULL; /* Check for and handle cretinous stabs symbol name continuation! */ -#define STABS_CONTINUE(pp) \ +#define STABS_CONTINUE(pp,objfile) \ do { \ - if (**(pp) == '\\') *(pp) = next_symbol_text (); \ + if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \ + *(pp) = next_symbol_text (objfile); \ } while (0) - +/* FIXME: These probably should be our own types (like rs6000_builtin_type + has its own types) rather than builtin_type_*. */ +static struct type **os9k_type_vector[] = { + 0, + &builtin_type_int, + &builtin_type_char, + &builtin_type_long, + &builtin_type_short, + &builtin_type_unsigned_char, + &builtin_type_unsigned_short, + &builtin_type_unsigned_long, + &builtin_type_unsigned_int, + &builtin_type_float, + &builtin_type_double, + &builtin_type_void, + &builtin_type_long_double +}; + +static void os9k_init_type_vector PARAMS ((struct type **)); + +static void +os9k_init_type_vector(tv) + struct type **tv; +{ + int i; + for (i=0; i= type_vector_length) { @@ -263,6 +333,10 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", (type_vector_length * sizeof (struct type *))); memset (&type_vector[old_len], 0, (type_vector_length - old_len) * sizeof (struct type *)); + + if (os9k_stabs) + /* Deal with OS9000 fundamental types. */ + os9k_init_type_vector (type_vector); } return (&type_vector[index]); } @@ -365,6 +439,14 @@ patch_block_stabs (symbols, stabs, objfile) sym = find_symbol_in_list (symbols, name, pp-name); if (!sym) { + /* FIXME-maybe: it would be nice if we noticed whether + the variable was defined *anywhere*, not just whether + it is defined in this compilation unit. But neither + xlc or GCC seem to need such a definition, and until + we do psymtabs (so that the minimal symbols from all + compilation units are available now), I'm not sure + how to get the information. */ + /* On xcoff, if a global is defined and never referenced, ld will remove it from the executable. There is then a N_GSYM stab for it, but no regular (C_EXT) symbol. */ @@ -376,7 +458,7 @@ patch_block_stabs (symbols, stabs, objfile) SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; SYMBOL_NAME (sym) = - obstack_copy0 (&objfile->symbol_obstack, name, pp - name); + obsavestring (name, pp - name, &objfile->symbol_obstack); pp += 2; if (*(pp-1) == 'F' || *(pp-1) == 'f') { @@ -442,13 +524,504 @@ read_type_number (pp, typenums) } -/* To handle GNU C++ typename abbreviation, we need to be able to - fill in a type's name as soon as space for that type is allocated. - `type_synonym_name' is the name of the type being allocated. - It is cleared as soon as it is used (lest all allocated types - get this name). */ +#if !defined (REG_STRUCT_HAS_ADDR) +#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0 +#endif + +#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */ +#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */ +#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */ +#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */ + +#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */ +#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */ + +/* This code added to support parsing of ARM/Cfront stabs strings */ + +/* Get substring from string up to char c, advance string pointer past + suibstring. */ + +static char * +get_substring (p, c) + char ** p; + int c; +{ + char *str; + str = *p; + *p = strchr (*p, c); + if (*p) + { + **p = 0; + (*p)++; + } + else + str = 0; + return str; +} + +/* Physname gets strcat'd onto sname in order to recreate the mangled + name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make + the physname look like that of g++ - take out the initial mangling + eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */ + +static char * +get_cfront_method_physname (fname) + char *fname; +{ + int len = 0; + /* FIXME would like to make this generic for g++ too, but + that is already handled in read_member_funcctions */ + char * p = fname; + + /* search ahead to find the start of the mangled suffix */ + if (*p == '_' && *(p+1)=='_') /* compiler generated; probably a ctor/dtor */ + p += 2; + while (p && ((p+1) - fname) < strlen (fname) && *(p+1) != '_') + p = strchr (p, '_'); + if (!(p && *p == '_' && *(p+1) == '_')) + error ("Invalid mangled function name %s",fname); + p += 2; /* advance past '__' */ + + /* struct name length and name of type should come next; advance past it */ + while (isdigit (*p)) + { + len = len * 10 + (*p - '0'); + p++; + } + p += len; + + return p; +} + +/* Read base classes within cfront class definition. + eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; + ^^^^^^^^^^^^^^^^^^ + + A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; + ^ + */ + +static int +read_cfront_baseclasses (fip, pp, type, objfile) + struct field_info *fip; + struct objfile *objfile; + char ** pp; + struct type *type; +{ + static struct complaint msg_unknown = {"\ + Unsupported token in stabs string %s.\n", + 0, 0}; + static struct complaint msg_notfound = {"\ + Unable to find base type for %s.\n", + 0, 0}; + int bnum = 0; + char * p; + int i; + struct nextfield *new; + + if (**pp == ';') /* no base classes; return */ + { + ++(*pp); + return 1; + } + + /* first count base classes so we can allocate space before parsing */ + for (p = *pp; p && *p && *p != ';'; p++) + { + if (*p == ' ') + bnum++; + } + bnum++; /* add one more for last one */ + + /* now parse the base classes until we get to the start of the methods + (code extracted and munged from read_baseclasses) */ + ALLOCATE_CPLUS_STRUCT_TYPE (type); + TYPE_N_BASECLASSES(type) = bnum; + + /* allocate space */ + { + int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type)); + char *pointer; + + pointer = (char *) TYPE_ALLOC (type, num_bytes); + TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer; + } + B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); + + for (i = 0; i < TYPE_N_BASECLASSES (type); i++) + { + new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); + make_cleanup (free, new); + memset (new, 0, sizeof (struct nextfield)); + new -> next = fip -> list; + fip -> list = new; + new -> field.bitsize = 0; /* this should be an unpacked field! */ + + STABS_CONTINUE (pp, objfile); + + /* virtual? eg: v2@Bvir */ + if (**pp=='v') + { + SET_TYPE_FIELD_VIRTUAL (type, i); + ++(*pp); + } + + /* access? eg: 2@Bvir */ + /* Note: protected inheritance not supported in cfront */ + switch (*(*pp)++) + { + case CFRONT_VISIBILITY_PRIVATE: + new -> visibility = VISIBILITY_PRIVATE; + break; + case CFRONT_VISIBILITY_PUBLIC: + new -> visibility = VISIBILITY_PUBLIC; + break; + default: + /* Bad visibility format. Complain and treat it as + public. */ + { + static struct complaint msg = { + "Unknown visibility `%c' for baseclass", 0, 0}; + complain (&msg, new -> visibility); + new -> visibility = VISIBILITY_PUBLIC; + } + } + + /* "@" comes next - eg: @Bvir */ + if (**pp!='@') + { + complain (&msg_unknown, *pp); + return 1; + } + ++(*pp); + + + /* Set the bit offset of the portion of the object corresponding + to this baseclass. Always zero in the absence of + multiple inheritance. */ + /* Unable to read bit position from stabs; + Assuming no multiple inheritance for now FIXME! */ + /* We may have read this in the structure definition; + now we should fixup the members to be the actual base classes */ + new -> field.bitpos = 0; + + /* Get the base class name and type */ + { + char * bname; /* base class name */ + struct symbol * bsym; /* base class */ + char * p1, * p2; + p1 = strchr(*pp,' '); + p2 = strchr(*pp,';'); + if (p1 field.type = SYMBOL_TYPE(bsym); + new -> field.name = type_name_no_tag (new -> field.type); + } + else + { + complain (&msg_notfound, *pp); + return 1; + } + } + + /* If more base classes to parse, loop again. + We ate the last ' ' or ';' in get_substring, + so on exit we will have skipped the trailing ';' */ + /* if invalid, return 0; add code to detect - FIXME! */ + } + return 1; +} + +/* read cfront member functions. + pp points to string starting with list of functions + eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +*/ + +static int +read_cfront_member_functions(fip, pp, type, objfile) + struct field_info *fip; + char **pp; + struct type *type; + struct objfile *objfile; + { + /* This code extracted from read_member_functions + so as to do the similar thing for our funcs */ + + int nfn_fields = 0; + int length = 0; + /* Total number of member functions defined in this class. If the class + defines two `f' functions, and one `g' function, then this will have + the value 3. */ + int total_length = 0; + int i; + struct next_fnfield + { + struct next_fnfield *next; + struct fn_field fn_field; + } *sublist; + struct type *look_ahead_type; + struct next_fnfieldlist *new_fnlist; + struct next_fnfield *new_sublist; + char *main_fn_name; + char * fname; + struct symbol * ref_func=0; + + /* Process each list until we find something that is not a member function + or find the end of the functions. */ + + /* eg: p = "__ct__1AFv foo__1AFv ;;;" */ + STABS_CONTINUE (pp, objfile); /* handle \\ */ + while (**pp!=';' && (fname = get_substring(pp,' '),fname)) + { + int is_static=0; + int sublist_count=0; + char * pname; + if (fname[0]=='*') /* static member */ + { + is_static=1; + sublist_count++; + fname++; + } + ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name*/ + if (!ref_func) + { + static struct complaint msg = {"\ + Unable to find function symbol for %s\n", + 0, 0}; + complain (&msg, fname); + continue; + } + sublist = NULL; + look_ahead_type = NULL; + length = 0; + + new_fnlist = (struct next_fnfieldlist *) + xmalloc (sizeof (struct next_fnfieldlist)); + make_cleanup (free, new_fnlist); + memset (new_fnlist, 0, sizeof (struct next_fnfieldlist)); + + /* The following is code to work around cfront generated stabs. + The stabs contains full mangled name for each field. + We try to demangle the name and extract the field name out of it. */ + { + char *dem, *dem_p, *dem_args; + int dem_len; + dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS); + if (dem != NULL) + { + dem_p = strrchr (dem, ':'); + if (dem_p != 0 && *(dem_p-1)==':') + dem_p++; + /* get rid of args */ + dem_args = strchr (dem_p, '('); + if (dem_args == NULL) + dem_len = strlen(dem_p); + else + dem_len = dem_args - dem_p; + main_fn_name = + obsavestring (dem_p, dem_len, &objfile -> type_obstack); + } + else + { + main_fn_name = + obsavestring (fname, strlen(fname), &objfile -> type_obstack); + } + } /* end of code for cfront work around */ + + new_fnlist -> fn_fieldlist.name = main_fn_name; + + /*-------------------------------------------------*/ + /* Set up the sublists + Sublists are stuff like args, static, visibility, etc. + so in ARM, we have to set that info some other way. + Multiple sublists happen if overloading + eg: foo::26=##1;:;2A.; + In g++, we'd loop here thru all the sublists... */ + new_sublist = + (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield)); + make_cleanup (free, new_sublist); + memset (new_sublist, 0, sizeof (struct next_fnfield)); + + /* eat 1; from :;2A.; */ + new_sublist -> fn_field.type = SYMBOL_TYPE(ref_func); /* normally takes a read_type */ + /* make this type look like a method stub for gdb */ + TYPE_FLAGS (new_sublist -> fn_field.type) |= TYPE_FLAG_STUB; + TYPE_CODE (new_sublist -> fn_field.type) = TYPE_CODE_METHOD; + + /* If this is just a stub, then we don't have the real name here. */ + if (TYPE_FLAGS (new_sublist -> fn_field.type) & TYPE_FLAG_STUB) + { + if (!TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type)) + TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type) = type; + new_sublist -> fn_field.is_stub = 1; + } + /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i + physname gets strcat'd in order to recreate the onto mangled name */ + pname = get_cfront_method_physname(fname); + new_sublist -> fn_field.physname = savestring (pname, strlen(pname)); + + + /* Set this member function's visibility fields. + Unable to distinguish access from stabs definition! + Assuming public for now. FIXME! + (for private, set new_sublist->fn_field.is_private = 1, + for public, set new_sublist->fn_field.is_protected = 1) */ + + /* Unable to distinguish const/volatile from stabs definition! + Assuming normal for now. FIXME! */ + + new_sublist -> fn_field.is_const = 0; + new_sublist -> fn_field.is_volatile = 0; /* volatile not implemented in cfront */ + + /* set virtual/static function info + How to get vtable offsets ? + Assuming normal for now FIXME!! + For vtables, figure out from whence this virtual function came. + It may belong to virtual function table of + one of its baseclasses. + set: + new_sublist -> fn_field.voffset = vtable offset, + new_sublist -> fn_field.fcontext = look_ahead_type; + where look_ahead_type is type of baseclass */ + if (is_static) + new_sublist -> fn_field.voffset = VOFFSET_STATIC; + else /* normal member function. */ + new_sublist -> fn_field.voffset = 0; + new_sublist -> fn_field.fcontext = 0; + + + /* prepare new sublist */ + new_sublist -> next = sublist; + sublist = new_sublist; + length++; + /* In g++, we loop thu sublists - now we set from function */ + + new_fnlist -> fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile -> type_obstack, + sizeof (struct fn_field) * length); + memset (new_fnlist -> fn_fieldlist.fn_fields, 0, + sizeof (struct fn_field) * length); + for (i = length; (i--, sublist); sublist = sublist -> next) + { + new_fnlist -> fn_fieldlist.fn_fields[i] = sublist -> fn_field; + } + + new_fnlist -> fn_fieldlist.length = length; + new_fnlist -> next = fip -> fnlist; + fip -> fnlist = new_fnlist; + nfn_fields++; + total_length += length; + STABS_CONTINUE (pp, objfile); /* handle \\ */ + } /* end of loop */ + + if (nfn_fields) + { + /* type should already have space */ + TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) + TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields); + memset (TYPE_FN_FIELDLISTS (type), 0, + sizeof (struct fn_fieldlist) * nfn_fields); + TYPE_NFN_FIELDS (type) = nfn_fields; + TYPE_NFN_FIELDS_TOTAL (type) = total_length; + } + + /* end of scope for reading member func */ + + /* eg: ";;" */ + /* skip trailing ';' and bump count of number of fields seen */ + if (**pp == ';') + (*pp)++; + else + return 0; + return 1; +} + +/* This routine fixes up partial cfront types that were created + while parsing the stabs. The main need for this function is + to add information such as methods to classes. + Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */ +void +resolve_cfront_continuation(objfile, sym, p) + struct objfile * objfile; + struct symbol * sym; + char * p; +{ + struct symbol * ref_sym=0; + char * sname; + /* snarfed from read_struct_type */ + struct field_info fi; + struct type *type; + struct cleanup *back_to; + + /* need to make sure that fi isn't gunna conflict with struct + in case struct already had some fnfs */ + fi.list = NULL; + fi.fnlist = NULL; + back_to = make_cleanup (null_cleanup, 0); + + /* we only accept structs, classes and unions at the moment. + Other continuation types include t (typedef), r (long dbl), ... + We may want to add support for them as well; + right now they are handled by duplicating the symbol information + into the type information (see define_symbol) */ + if (*p != 's' /* structs */ + && *p != 'c' /* class */ + && *p != 'u') /* union */ + return; /* only handle C++ types */ + p++; + + /* get symbol typs name and validate + eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */ + sname = get_substring(&p,';'); + if (!sname || strcmp(sname,SYMBOL_NAME(sym))) + error("Internal error: base symbol type name does not match\n"); + + /* find symbol's internal gdb reference */ + ref_sym = lookup_symbol (SYMBOL_NAME(sym), 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name*/ + /* This is the real sym that we want; + sym was a temp hack to make debugger happy */ + /* ref_sym should already have space */ + type = SYMBOL_TYPE(ref_sym); + + + /* Now read the baseclasses, if any, read the regular C struct or C++ + class member fields, attach the fields to the type, read the C++ + member functions, attach them to the type, and then read any tilde + field (baseclass specifier for the class holding the main vtable). */ + + if (!read_cfront_baseclasses (&fi, &p, type, objfile) + /* g++ does this next, but cfront already did this: + || !read_struct_fields (&fi, &p, type, objfile) */ + || !copy_cfront_struct_fields (&fi, type, objfile) + || !read_cfront_member_functions (&fi, &p, type, objfile) + || !read_cfront_static_fields(&fi, &p, type, objfile) + || !attach_fields_to_type (&fi, type, objfile) + || !attach_fn_fields_to_type (&fi, type) + /* g++ does this next, but cfront doesn't seem to have this: + || !read_tilde_fields (&fi, &p, type, objfile) */ + ) + { + type = error_type (&p, objfile); + } + + do_cleanups (back_to); +} +/* End of code added to support parsing of ARM/Cfront stabs strings */ -static char *type_synonym_name; /* ARGSUSED */ struct symbol * @@ -490,10 +1063,23 @@ define_symbol (valu, string, desc, type, objfile) e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */ nameless = (p == string || ((string[0] == ' ') && (string[1] == ':'))); - sym = (struct symbol *) + current_symbol = sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); + switch (type & N_TYPE) + { + case N_TEXT: + SYMBOL_SECTION(sym) = SECT_OFF_TEXT; + break; + case N_DATA: + SYMBOL_SECTION(sym) = SECT_OFF_DATA; + break; + case N_BSS: + SYMBOL_SECTION(sym) = SECT_OFF_BSS; + break; + } + if (processing_gcc_compilation) { /* GCC 2.x puts the line number in desc. SunOS apparently puts in the @@ -505,7 +1091,7 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_LINE(sym) = 0; /* unknown */ } - if (string[0] == CPLUS_MARKER) + if (is_cplus_marker (string[0])) { /* Special GNU C++ names. */ switch (string[1]) @@ -528,6 +1114,12 @@ define_symbol (valu, string, desc, type, objfile) /* This was an anonymous type that was never fixed up. */ goto normal; +#ifdef STATIC_TRANSFORM_NAME + case 'X': + /* SunPRO (3.0 at least) static variable encoding. */ + goto normal; +#endif + default: complain (&unrecognized_cplus_name_complaint, string); goto normal; /* Do *something* with it */ @@ -592,7 +1184,7 @@ define_symbol (valu, string, desc, type, objfile) if (*p != '=') { SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = error_type (&p); + SYMBOL_TYPE (sym) = error_type (&p, objfile); SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &file_symbols); return sym; @@ -666,7 +1258,7 @@ define_symbol (valu, string, desc, type, objfile) if (*p != ',') { - SYMBOL_TYPE (sym) = error_type (&p); + SYMBOL_TYPE (sym) = error_type (&p, objfile); break; } ++p; @@ -683,7 +1275,7 @@ define_symbol (valu, string, desc, type, objfile) default: { SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = error_type (&p); + SYMBOL_TYPE (sym) = error_type (&p, objfile); } } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -712,23 +1304,7 @@ define_symbol (valu, string, desc, type, objfile) We need to convert this to the function-returning-type-X type in GDB. E.g. "int" is converted to "function returning int". */ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC) - { -#if 0 - /* This code doesn't work -- it needs to realloc and can't. */ - /* Attempt to set up to record a function prototype... */ - struct type *new = alloc_type (objfile); - - /* Generate a template for the type of this function. The - types of the arguments will be added as we read the symbol - table. */ - *new = *lookup_function_type (SYMBOL_TYPE(sym)); - SYMBOL_TYPE(sym) = new; - TYPE_OBJFILE (new) = objfile; - in_function_type = new; -#else - SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); -#endif - } + SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); /* fall into process_prototype_types */ process_prototype_types: @@ -767,6 +1343,7 @@ define_symbol (valu, string, desc, type, objfile) /* This case is faked by a conditional above, when there is no code letter in the dbx data. Dbx data never actually contains 'l'. */ + case 's': case 'l': SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LOCAL; @@ -798,17 +1375,15 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type); SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; -#if 0 - /* This doesn't work yet. */ - add_param_to_type (&in_function_type, sym); -#endif add_symbol_to_list (sym, &local_symbols); -#if TARGET_BYTE_ORDER == LITTLE_ENDIAN - /* On little-endian machines, this crud is never necessary, and, - if the extra bytes contain garbage, is harmful. */ - break; -#else /* Big endian. */ + if (TARGET_BYTE_ORDER != BIG_ENDIAN) + { + /* On little-endian machines, this crud is never necessary, + and, if the extra bytes contain garbage, is harmful. */ + break; + } + /* If it's gcc-compiled, if it says `short', believe it. */ if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION) break; @@ -887,15 +1462,14 @@ define_symbol (valu, string, desc, type, objfile) #endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ } #endif /* !BELIEVE_PCC_PROMOTION. */ -#endif /* Big endian. */ case 'P': - /* acc seems to use P to delare the prototypes of functions that + /* acc seems to use P to declare the prototypes of functions that are referenced by this file. gdb is not prepared to deal with this extra information. FIXME, it ought to. */ if (type == N_FUN) { - read_type (&p, objfile); + SYMBOL_TYPE (sym) = read_type (&p, objfile); goto process_prototype_types; } /*FALLTHROUGH*/ @@ -907,7 +1481,8 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS) { - complain (®_value_complaint, SYMBOL_SOURCE_NAME (sym)); + complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, + SYMBOL_SOURCE_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -921,7 +1496,8 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS) { - complain (®_value_complaint, SYMBOL_SOURCE_NAME (sym)); + complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, + SYMBOL_SOURCE_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -930,17 +1506,36 @@ define_symbol (valu, string, desc, type, objfile) /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same name to represent an argument passed in a register. GCC uses 'P' for the same case. So if we find such a symbol pair - we combine it into one 'P' symbol. + we combine it into one 'P' symbol. For Sun cc we need to do this + regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out + the 'p' symbol even if it never saves the argument onto the stack. + + On most machines, we want to preserve both symbols, so that + we can still get information about what is going on with the + stack (VAX for computing args_printed, using stack slots instead + of saved registers in backtraces, etc.). + Note that this code illegally combines - main(argc) int argc; { register int argc = 1; } + main(argc) struct foo argc; { register struct foo argc; } but this case is considered pathological and causes a warning from a decent compiler. */ + if (local_symbols - && local_symbols->nsyms > 0) + && local_symbols->nsyms > 0 +#ifndef USE_REGISTER_NOT_ARG + && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, + SYMBOL_TYPE (sym)) + && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT + || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION + || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET + || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING) +#endif + ) { struct symbol *prev_sym; prev_sym = local_symbols->symbol[local_symbols->nsyms - 1]; - if (SYMBOL_CLASS (prev_sym) == LOC_ARG + if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG + || SYMBOL_CLASS (prev_sym) == LOC_ARG) && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym))) { SYMBOL_CLASS (prev_sym) = LOC_REGPARM; @@ -963,6 +1558,18 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; +#ifdef STATIC_TRANSFORM_NAME + if (SYMBOL_NAME (sym)[0] == '$') + { + struct minimal_symbol *msym; + msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + if (msym != NULL) + { + SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); + } + } +#endif SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &file_symbols); break; @@ -995,7 +1602,13 @@ define_symbol (valu, string, desc, type, objfile) if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL) { - if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR + /* gcc-2.6 or later (when using -fvtable-thunks) + emits a unique named type for a vtable entry. + Some gdb code depends on that specific name. */ + extern const char vtbl_ptr_name[]; + + if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR + && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name)) || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) { /* If we are giving a name to a type such as "pointer to @@ -1030,23 +1643,13 @@ define_symbol (valu, string, desc, type, objfile) synonym = *p == 't'; if (synonym) - { - p++; - type_synonym_name = obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile -> symbol_obstack); - } + p++; /* The semantics of C++ state that "struct foo { ... }" also defines a typedef for "foo". Unfortunately, cfront never makes the typedef when translating C++ into C. We make the typedef here so that "ptype foo" works as expected for cfront translated code. */ else if (current_subfile->language == language_cplus) - { - synonym = 1; - type_synonym_name = obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile -> symbol_obstack); - } + synonym = 1; SYMBOL_TYPE (sym) = read_type (&p, objfile); @@ -1083,8 +1686,23 @@ define_symbol (valu, string, desc, type, objfile) SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; +#ifdef STATIC_TRANSFORM_NAME + if (SYMBOL_NAME (sym)[0] == '$') + { + struct minimal_symbol *msym; + msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + if (msym != NULL) + { + SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); + } + } +#endif SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); + if (os9k_stabs) + add_symbol_to_list (sym, &global_symbols); + else + add_symbol_to_list (sym, &local_symbols); break; case 'v': @@ -1096,6 +1714,21 @@ define_symbol (valu, string, desc, type, objfile) add_symbol_to_list (sym, &local_symbols); break; + case 'a': + /* Reference parameter which is in a register. */ + SYMBOL_TYPE (sym) = read_type (&p, objfile); + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; + SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); + if (SYMBOL_VALUE (sym) >= NUM_REGS) + { + complain (®_value_complaint, SYMBOL_VALUE (sym), NUM_REGS, + SYMBOL_SOURCE_NAME (sym)); + SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ + } + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + add_symbol_to_list (sym, &local_symbols); + break; + case 'X': /* This is used by Sun FORTRAN for "function result value". Sun claims ("dbx and dbxtool interfaces", 2nd ed) @@ -1108,8 +1741,32 @@ define_symbol (valu, string, desc, type, objfile) add_symbol_to_list (sym, &local_symbols); break; + /* New code added to support cfront stabs strings */ + /* Note: case 'P' already handled above */ + case 'Z': + /* Cfront type continuation coming up! + find the original definition and add to it. + We'll have to do this for the typedef too, + since we clloned the symbol to define a type in read_type. + Stabs info examples: + __1C :Ztl + foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24)) + C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;; + where C is the name of the class. */ + /* can't lookup symbol yet 'cuz symbols not read yet + so we save it for processing later */ + process_later(sym,p); + SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */ + SYMBOL_CLASS (sym) = LOC_CONST; + SYMBOL_VALUE (sym) = 0; + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + /* don't add to list - we'll delete it later when + we add the continuation to the real sym */ + return sym; + /* End of new code added to support cfront stabs strings */ + default: - SYMBOL_TYPE (sym) = error_type (&p); + SYMBOL_TYPE (sym) = error_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_VALUE (sym) = 0; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; @@ -1118,20 +1775,24 @@ define_symbol (valu, string, desc, type, objfile) } /* When passing structures to a function, some systems sometimes pass - the address in a register, not the structure itself. - - If REG_STRUCT_HAS_ADDR yields non-zero we have to convert LOC_REGPARM - to LOC_REGPARM_ADDR for structures and unions. */ - -#if !defined (REG_STRUCT_HAS_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p) 0 -#endif - - if (SYMBOL_CLASS (sym) == LOC_REGPARM - && REG_STRUCT_HAS_ADDR (processing_gcc_compilation) - && ( (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT) - || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION))) - SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; + the address in a register, not the structure itself. */ + + if (REG_STRUCT_HAS_ADDR (processing_gcc_compilation, + SYMBOL_TYPE (sym)) + && ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT) + || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) + || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING) + || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET))) + { + /* If REG_STRUCT_HAS_ADDR yields non-zero we have to + convert LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */ + if (SYMBOL_CLASS (sym) == LOC_REGPARM) + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; + /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th and + subsequent arguments on the sparc, for example). */ + else if (SYMBOL_CLASS (sym) == LOC_ARG) + SYMBOL_CLASS (sym) = LOC_REF_ARG; + } return sym; } @@ -1144,7 +1805,7 @@ define_symbol (valu, string, desc, type, objfile) Thus code like this: if (*(*pp)++ != ';') - return error_type (pp); + return error_type (pp, objfile); is wrong because if *pp starts out pointing at '\0' (typically as the result of an earlier error), it will be incremented to point to the @@ -1152,13 +1813,13 @@ define_symbol (valu, string, desc, type, objfile) if you run off the end of the string table. Instead use if (**pp != ';') - return error_type (pp); + return error_type (pp, objfile); ++*pp; or if (**pp != ';') - foo = error_type (pp); + foo = error_type (pp, objfile); else ++*pp; @@ -1167,8 +1828,9 @@ define_symbol (valu, string, desc, type, objfile) debugger will be able to read the new symbol tables. */ static struct type * -error_type (pp) +error_type (pp, objfile) char **pp; + struct objfile *objfile; { complain (&error_type_complaint); while (1) @@ -1180,9 +1842,9 @@ error_type (pp) } /* Check for and handle cretinous dbx symbol name continuation! */ - if ((*pp)[-1] == '\\') + if ((*pp)[-1] == '\\' || (*pp)[-1] == '?') { - *pp = next_symbol_text (); + *pp = next_symbol_text (objfile); } else { @@ -1207,13 +1869,15 @@ read_type (pp, objfile) register struct type *type = 0; struct type *type1; int typenums[2]; - int xtypenums[2]; char type_descriptor; /* Size in bits of type if specified by a type attribute, or -1 if there is no size attribute. */ int type_size = -1; + /* Used to distinguish string and bitstring from char-array and set. */ + int is_string = 0; + /* Read type number if present. The type number may be omitted. for instance in a two-dimensional array declared with type "ar1;1;10;ar1;1;10;4". */ @@ -1222,7 +1886,7 @@ read_type (pp, objfile) || **pp == '-') { if (read_type_number (pp, typenums) != 0) - return error_type (pp); + return error_type (pp, objfile); /* Type is not being defined here. Either it already exists, or this is a forward reference to it. dbx_alloc_type handles @@ -1231,47 +1895,9 @@ read_type (pp, objfile) return dbx_alloc_type (typenums, objfile); /* Type is being defined here. */ - /* Skip the '='. */ - ++(*pp); - - while (**pp == '@') - { - char *p = *pp + 1; - /* It might be a type attribute or a member type. */ - if (isdigit (*p) || *p == '(' || *p == '-') - /* Member type. */ - break; - else - { - /* Type attributes. */ - char *attr = p; - - /* Skip to the semicolon. */ - while (*p != ';' && *p != '\0') - ++p; - *pp = p; - if (*p == '\0') - return error_type (pp); - else - /* Skip the semicolon. */ - ++*pp; - - switch (*attr) - { - case 's': - type_size = atoi (attr + 1); - if (type_size <= 0) - type_size = -1; - break; - default: - /* Ignore unrecognized type attributes, so future compilers - can invent new ones. */ - break; - } - } - } - /* Skip the type descriptor, we get it below with (*pp)[-1]. */ - ++(*pp); + /* Skip the '='. + Also skip the type descriptor - we get it below with (*pp)[-1]. */ + (*pp)+=2; } else { @@ -1281,6 +1907,7 @@ read_type (pp, objfile) (*pp)++; } + again: type_descriptor = (*pp)[-1]; switch (type_descriptor) { @@ -1296,7 +1923,7 @@ read_type (pp, objfile) char *type_name; { - char *from, *to, *p; + char *from, *to, *p, *q1, *q2; /* Set the type code according to the following letter. */ switch ((*pp)[0]) @@ -1322,15 +1949,19 @@ read_type (pp, objfile) } } + q1 = strchr(*pp, '<'); p = strchr(*pp, ':'); if (p == NULL) - return error_type (pp); - while (p[1] == ':') + return error_type (pp, objfile); + while (q1 && p > q1 && p[1] == ':') { + q2 = strchr(q1, '>'); + if (!q2 || q2 < p) + break; p += 2; p = strchr(p, ':'); if (p == NULL) - return error_type (pp); + return error_type (pp, objfile); } to = type_name = (char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1); @@ -1395,41 +2026,34 @@ read_type (pp, objfile) case '8': case '9': case '(': - (*pp)--; - if (read_type_number (pp, xtypenums) != 0) - return error_type (pp); - - if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1]) - /* It's being defined as itself. That means it is "void". */ - type = init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile); - else - { - struct type *xtype = *dbx_lookup_type (xtypenums); - - /* This can happen if we had '-' followed by a garbage character, - for example. */ - if (xtype == NULL) - return error_type (pp); - - /* The type is being defined to another type. So we copy the type. - This loses if we copy a C++ class and so we lose track of how - the names are mangled (but g++ doesn't output stabs like this - now anyway). */ - type = alloc_type (objfile); - memcpy (type, xtype, sizeof (struct type)); + /* We deal with something like t(1,2)=(3,4)=... which + the Lucid compiler and recent gcc versions (post 2.7.3) use. */ - /* The idea behind clearing the names is that the only purpose - for defining a type to another type is so that the name of - one can be different. So we probably don't need to worry much - about the case where the compiler doesn't give a name to the - new type. */ - TYPE_NAME (type) = NULL; - TYPE_TAG_NAME (type) = NULL; - } - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; + /* Allocate and enter the typedef type first. + This handles recursive types. */ + type = dbx_alloc_type (typenums, objfile); + TYPE_CODE (type) = TYPE_CODE_TYPEDEF; + { struct type *xtype = read_type (pp, objfile); + if (type == xtype) + { + /* It's being defined as itself. That means it is "void". */ + TYPE_CODE (type) = TYPE_CODE_VOID; + TYPE_LENGTH (type) = 1; + } + else if (type_size >= 0 || is_string) + { + *type = *xtype; + TYPE_NAME (type) = NULL; + TYPE_TAG_NAME (type) = NULL; + } + else + { + TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB; + TYPE_TARGET_TYPE (type) = xtype; + } + } break; /* In the following types, we must be sure to overwrite any existing @@ -1450,35 +2074,92 @@ read_type (pp, objfile) break; case 'f': /* Function returning another type */ + if (os9k_stabs && **pp == '(') + { + /* Function prototype; parse it. + We must conditionalize this on os9k_stabs because otherwise + it could be confused with a Sun-style (1,3) typenumber + (I think). */ + struct type *t; + ++*pp; + while (**pp != ')') + { + t = read_type(pp, objfile); + if (**pp == ',') ++*pp; + } + } type1 = read_type (pp, objfile); type = make_function_type (type1, dbx_lookup_type (typenums)); break; - case 'k': /* Const qualifier on some type (Sun) */ + case 'k': /* Const qualifier on some type (Sun) */ + case 'c': /* Const qualifier on some type (OS9000) */ + /* Because 'c' means other things to AIX and 'k' is perfectly good, + only accept 'c' in the os9k_stabs case. */ + if (type_descriptor == 'c' && !os9k_stabs) + return error_type (pp, objfile); type = read_type (pp, objfile); /* FIXME! For now, we ignore const and volatile qualifiers. */ break; - case 'B': /* Volatile qual on some type (Sun) */ + case 'B': /* Volatile qual on some type (Sun) */ + case 'i': /* Volatile qual on some type (OS9000) */ + /* Because 'i' means other things to AIX and 'B' is perfectly good, + only accept 'i' in the os9k_stabs case. */ + if (type_descriptor == 'i' && !os9k_stabs) + return error_type (pp, objfile); type = read_type (pp, objfile); /* FIXME! For now, we ignore const and volatile qualifiers. */ break; -/* FIXME -- we should be doing smash_to_XXX types here. */ - case '@': /* Member (class & variable) type */ - { - struct type *domain = read_type (pp, objfile); - struct type *memtype; + case '@': + if (isdigit (**pp) || **pp == '(' || **pp == '-') + { /* Member (class & variable) type */ + /* FIXME -- we should be doing smash_to_XXX types here. */ - if (**pp != ',') - /* Invalid member type data format. */ - return error_type (pp); - ++*pp; + struct type *domain = read_type (pp, objfile); + struct type *memtype; - memtype = read_type (pp, objfile); - type = dbx_alloc_type (typenums, objfile); - smash_to_member_type (type, domain, memtype); - } + if (**pp != ',') + /* Invalid member type data format. */ + return error_type (pp, objfile); + ++*pp; + + memtype = read_type (pp, objfile); + type = dbx_alloc_type (typenums, objfile); + smash_to_member_type (type, domain, memtype); + } + else /* type attribute */ + { + char *attr = *pp; + /* Skip to the semicolon. */ + while (**pp != ';' && **pp != '\0') + ++(*pp); + if (**pp == '\0') + return error_type (pp, objfile); + else + ++*pp; /* Skip the semicolon. */ + + switch (*attr) + { + case 's': + type_size = atoi (attr + 1); + if (type_size <= 0) + type_size = -1; + break; + + case 'S': + is_string = 1; + break; + + default: + /* Ignore unrecognized type attributes, so future compilers + can invent new ones. */ + break; + } + ++*pp; + goto again; + } break; case '#': /* Method (class & fn) type */ @@ -1503,7 +2184,7 @@ read_type (pp, objfile) if (**pp != ',') /* Invalid member type data format. */ - return error_type (pp); + return error_type (pp, objfile); else ++(*pp); @@ -1520,10 +2201,17 @@ read_type (pp, objfile) *dbx_lookup_type (typenums) = type; break; - case 'b': /* Sun ACC builtin int type */ - type = read_sun_builtin_type (pp, typenums, objfile); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; + case 'b': + if (os9k_stabs) + /* Const and volatile qualified type. */ + type = read_type (pp, objfile); + else + { + /* Sun ACC builtin int type */ + type = read_sun_builtin_type (pp, typenums, objfile); + if (typenums[0] != -1) + *dbx_lookup_type (typenums) = type; + } break; case 'R': /* Sun ACC builtin float type */ @@ -1542,11 +2230,6 @@ read_type (pp, objfile) case 's': /* Struct type */ case 'u': /* Union type */ type = dbx_alloc_type (typenums, objfile); - if (!TYPE_NAME (type)) - { - TYPE_NAME (type) = type_synonym_name; - } - type_synonym_name = NULL; switch (type_descriptor) { case 's': @@ -1561,28 +2244,39 @@ read_type (pp, objfile) case 'a': /* Array type */ if (**pp != 'r') - return error_type (pp); + return error_type (pp, objfile); ++*pp; type = dbx_alloc_type (typenums, objfile); type = read_array_type (pp, type, objfile); + if (is_string) + TYPE_CODE (type) = TYPE_CODE_STRING; + break; + + case 'S': + type1 = read_type (pp, objfile); + type = create_set_type ((struct type*) NULL, type1); + if (is_string) + TYPE_CODE (type) = TYPE_CODE_BITSTRING; + if (typenums[0] != -1) + *dbx_lookup_type (typenums) = type; break; default: --*pp; /* Go back to the symbol in error */ /* Particularly important if it was \0! */ - return error_type (pp); + return error_type (pp, objfile); } if (type == 0) { warning ("GDB internal error, type is NULL in stabsread.c\n"); - return error_type (pp); + return error_type (pp, objfile); } /* Size specified in a type attribute overrides any other size. */ if (type_size != -1) - TYPE_LENGTH (type) = type_size / TARGET_CHAR_BIT; + TYPE_LENGTH (type) = (type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT; return type; } @@ -1595,7 +2289,7 @@ rs6000_builtin_type (typenum) int typenum; { /* We recognize types numbered from -NUMBER_RECOGNIZED to -1. */ -#define NUMBER_RECOGNIZED 30 +#define NUMBER_RECOGNIZED 34 /* This includes an empty slot for type number -0. */ static struct type *negative_types[NUMBER_RECOGNIZED + 1]; struct type *rettype = NULL; @@ -1658,7 +2352,7 @@ rs6000_builtin_type (typenum) "unsigned long", NULL); break; case 11: - rettype = init_type (TYPE_CODE_VOID, 0, 0, "void", NULL); + rettype = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL); break; case 12: /* IEEE single precision (32 bit). */ @@ -1678,7 +2372,8 @@ rs6000_builtin_type (typenum) rettype = init_type (TYPE_CODE_INT, 4, 0, "integer", NULL); break; case 16: - rettype = init_type (TYPE_CODE_BOOL, 4, 0, "boolean", NULL); + rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED, + "boolean", NULL); break; case 17: rettype = init_type (TYPE_CODE_FLT, 4, 0, "short real", NULL); @@ -1729,6 +2424,20 @@ rs6000_builtin_type (typenum) case 30: rettype = init_type (TYPE_CODE_CHAR, 2, 0, "wchar", NULL); break; + case 31: + rettype = init_type (TYPE_CODE_INT, 8, 0, "long long", NULL); + break; + case 32: + rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED, + "unsigned long long", NULL); + break; + case 33: + rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED, + "logical*8", NULL); + break; + case 34: + rettype = init_type (TYPE_CODE_INT, 8, 0, "integer*8", NULL); + break; } negative_types[-typenum] = rettype; return rettype; @@ -1736,11 +2445,6 @@ rs6000_builtin_type (typenum) /* This page contains subroutines of read_type. */ -#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */ -#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */ -#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */ -#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */ - /* Read member function stabs info for C++ classes. The form of each member function data is: @@ -1808,7 +2512,7 @@ read_member_functions (fip, pp, type, objfile) make_cleanup (free, new_fnlist); memset (new_fnlist, 0, sizeof (struct next_fnfieldlist)); - if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER) + if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && is_cplus_marker ((*pp)[2])) { /* This is a completely wierd case. In order to stuff in the names that might contain colons (the usual name delimiter), @@ -1825,7 +2529,7 @@ read_member_functions (fip, pp, type, objfile) /* Skip past '::'. */ *pp = p + 2; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); p = *pp; while (*p != '.') { @@ -1854,7 +2558,7 @@ read_member_functions (fip, pp, type, objfile) if (look_ahead_type == NULL) { /* Normal case. */ - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); new_sublist -> fn_field.type = read_type (pp, objfile); if (**pp != ':') @@ -1899,7 +2603,7 @@ read_member_functions (fip, pp, type, objfile) break; } - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); switch (**pp) { case 'A': /* Normal functions. */ @@ -1948,7 +2652,7 @@ read_member_functions (fip, pp, type, objfile) if (nbits != 0) return 0; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); if (**pp == ';' || **pp == '\0') { /* Must be g++ version 1. */ @@ -2005,7 +2709,7 @@ read_member_functions (fip, pp, type, objfile) new_sublist -> next = sublist; sublist = new_sublist; length++; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); } while (**pp != ';' && **pp != '\0'); @@ -2026,7 +2730,7 @@ read_member_functions (fip, pp, type, objfile) fip -> fnlist = new_fnlist; nfn_fields++; total_length += length; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); } if (nfn_fields) @@ -2145,7 +2849,36 @@ read_one_struct_field (fip, pp, p, type, objfile) struct type *type; struct objfile *objfile; { - fip -> list -> field.name = + /* The following is code to work around cfront generated stabs. + The stabs contains full mangled name for each field. + We try to demangle the name and extract the field name out of it. + */ + if (ARM_DEMANGLING && current_subfile->language == language_cplus) + { + char save_p; + char *dem, *dem_p; + save_p = *p; + *p = '\0'; + dem = cplus_demangle (*pp, DMGL_ANSI | DMGL_PARAMS); + if (dem != NULL) + { + dem_p = strrchr (dem, ':'); + if (dem_p != 0 && *(dem_p-1)==':') + dem_p++; + fip->list->field.name = + obsavestring (dem_p, strlen(dem_p), &objfile -> type_obstack); + } + else + { + fip->list->field.name = + obsavestring (*pp, p - *pp, &objfile -> type_obstack); + } + *p = save_p; + } + /* end of code for cfront work around */ + + else + fip -> list -> field.name = obsavestring (*pp, p - *pp, &objfile -> type_obstack); *pp = p + 1; @@ -2238,6 +2971,7 @@ read_one_struct_field (fip, pp, p, type, objfile) and treat enums as if they had the width of ints. */ if (TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_INT + && TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_BOOL && TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_ENUM) { fip -> list -> field.bitsize = 0; @@ -2298,7 +3032,8 @@ read_struct_fields (fip, pp, type, objfile) while (**pp != ';') { - STABS_CONTINUE (pp); + if (os9k_stabs && **pp == ',') break; + STABS_CONTINUE (pp, objfile); /* Get space to record the next field's data. */ new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); make_cleanup (free, new); @@ -2312,12 +3047,9 @@ read_struct_fields (fip, pp, type, objfile) /* If is starts with CPLUS_MARKER it is a special abbreviation, unless the CPLUS_MARKER is followed by an underscore, in which case it is just the name of an anonymous type, which we - should handle like any other type name. We accept either '$' - or '.', because a field name can never contain one of these - characters except as a CPLUS_MARKER (we probably should be - doing that in most parts of GDB). */ + should handle like any other type name. */ - if ((*p == '$' || *p == '.') && p[1] != '_') + if (is_cplus_marker (p[0]) && p[1] != '_') { if (!read_cpp_abbrev (fip, pp, type, objfile)) return 0; @@ -2343,7 +3075,7 @@ read_struct_fields (fip, pp, type, objfile) } read_one_struct_field (fip, pp, p, type, objfile); } - if (p[1] == ':') + if (p[0] == ':' && p[1] == ':') { /* chill the list of fields: the last entry (at the head) is a partially constructed entry which we now scrub. */ @@ -2430,7 +3162,7 @@ read_baseclasses (fip, pp, type, objfile) fip -> list = new; new -> field.bitsize = 0; /* this should be an unpacked field! */ - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); switch (**pp) { case '0': @@ -2512,7 +3244,7 @@ read_tilde_fields (fip, pp, type, objfile) { register char *p; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); /* If we are positioned at a ';', then skip it. */ if (**pp == ';') @@ -2592,17 +3324,6 @@ attach_fn_fields_to_type (fip, type) { register int n; - for (n = 0; n < TYPE_N_BASECLASSES (type); n++) - { - if (TYPE_CODE (TYPE_BASECLASS (type, n)) == TYPE_CODE_UNDEF) - { - /* @@ Memory leak on objfile -> type_obstack? */ - return 0; - } - TYPE_NFN_FIELDS_TOTAL (type) += - TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, n)); - } - for (n = TYPE_NFN_FIELDS (type); fip -> fnlist != NULL; fip -> fnlist = fip -> fnlist -> next) @@ -2613,6 +3334,145 @@ attach_fn_fields_to_type (fip, type) return 1; } +/* read cfront class static data. + pp points to string starting with the list of static data + eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; + ^^^^^^^^ + + A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; + ^ + */ + +static int +read_cfront_static_fields(fip, pp, type, objfile) + struct field_info *fip; + char **pp; + struct type *type; + struct objfile *objfile; +{ + struct nextfield * new; + struct type *stype; + char * sname; + struct symbol * ref_static=0; + + if (**pp==';') /* no static data; return */ + { + ++(*pp); + return 1; + } + + /* Process each field in the list until we find the terminating ";" */ + + /* eg: p = "as__1A ;;;" */ + STABS_CONTINUE (pp, objfile); /* handle \\ */ + while (**pp!=';' && (sname = get_substring(pp,' '),sname)) + { + ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name*/ + if (!ref_static) + { + static struct complaint msg = {"\ + Unable to find symbol for static data field %s\n", + 0, 0}; + complain (&msg, sname); + continue; + } + stype = SYMBOL_TYPE(ref_static); + + /* allocate a new fip */ + new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); + make_cleanup (free, new); + memset (new, 0, sizeof (struct nextfield)); + new -> next = fip -> list; + fip -> list = new; + + /* set visibility */ + /* FIXME! no way to tell visibility from stabs??? */ + new -> visibility = VISIBILITY_PUBLIC; + + /* set field info into fip */ + fip -> list -> field.type = stype; + + /* set bitpos & bitsize */ + fip -> list -> field.bitpos = (long) -1; /* -1 signifies a static member */ + /* YUK! what a hack! bitsize used for physname when field is static */ + fip -> list -> field.bitsize = (long) savestring (sname, strlen(sname)); + + /* set name field */ + /* The following is code to work around cfront generated stabs. + The stabs contains full mangled name for each field. + We try to demangle the name and extract the field name out of it. + */ + if (ARM_DEMANGLING) + { + char *dem, *dem_p; + dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS); + if (dem != NULL) + { + dem_p = strrchr (dem, ':'); + if (dem_p != 0 && *(dem_p-1)==':') + dem_p++; + fip->list->field.name = + obsavestring (dem_p, strlen(dem_p), &objfile -> type_obstack); + } + else + { + fip->list->field.name = + obsavestring (sname, strlen(sname), &objfile -> type_obstack); + } + } /* end of code for cfront work around */ + } /* loop again for next static field */ + return 1; +} + +/* Copy structure fields to fip so attach_fields_to_type will work. + type has already been created with the initial instance data fields. + Now we want to be able to add the other members to the class, + so we want to add them back to the fip and reattach them again + once we have collected all the class members. */ + +static int +copy_cfront_struct_fields(fip, type, objfile) + struct field_info *fip; + struct type *type; + struct objfile *objfile; +{ + int nfields = TYPE_NFIELDS(type); + int i; + struct nextfield * new; + + /* Copy the fields into the list of fips and reset the types + to remove the old fields */ + + for (i=0; i next = fip -> list; + fip -> list = new; + + /* copy field info into fip */ + new -> field = TYPE_FIELD (type, i); + /* set visibility */ + if (TYPE_FIELD_PROTECTED (type, i)) + new -> visibility = VISIBILITY_PROTECTED; + else if (TYPE_FIELD_PRIVATE (type, i)) + new -> visibility = VISIBILITY_PRIVATE; + else + new -> visibility = VISIBILITY_PUBLIC; + } + /* Now delete the fields from the type since we will be + allocing new space once we get the rest of the fields + in attach_fields_to_type. + The pointer TYPE_FIELDS(type) is left dangling but should + be freed later by objstack_free */ + TYPE_FIELDS (type)=0; + TYPE_NFIELDS (type) = 0; + + return 1; +} + /* Create the vector of fields, and record how big it is. We need this info to record proper virtual function table information for this class's virtual functions. */ @@ -2742,7 +3602,7 @@ read_struct_type (pp, type, objfile) int nbits; TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); } /* Now read the baseclasses, if any, read the regular C struct or C++ @@ -2757,8 +3617,7 @@ read_struct_type (pp, type, objfile) || !attach_fn_fields_to_type (&fi, type) || !read_tilde_fields (&fi, pp, type, objfile)) { - do_cleanups (back_to); - return (error_type (pp)); + type = error_type (pp, objfile); } do_cleanups (back_to); @@ -2782,35 +3641,40 @@ read_array_type (pp, type, objfile) int nbits; /* Format of an array type: - "ar;lower;upper;". Put code in - to handle this. + "ar;lower;upper;". + OS9000: "arlower,upper;". Fortran adjustable arrays use Adigits or Tdigits for lower or upper; for these, produce a type like float[][]. */ - index_type = read_type (pp, objfile); - if (**pp != ';') - /* Improper format of array type decl. */ - return error_type (pp); - ++*pp; + if (os9k_stabs) + index_type = builtin_type_int; + else + { + index_type = read_type (pp, objfile); + if (**pp != ';') + /* Improper format of array type decl. */ + return error_type (pp, objfile); + ++*pp; + } - if (!(**pp >= '0' && **pp <= '9')) + if (!(**pp >= '0' && **pp <= '9') && **pp != '-') { (*pp)++; adjustable = 1; } - lower = read_huge_number (pp, ';', &nbits); + lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); - if (!(**pp >= '0' && **pp <= '9')) + if (!(**pp >= '0' && **pp <= '9') && **pp != '-') { (*pp)++; adjustable = 1; } upper = read_huge_number (pp, ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); element_type = read_type (pp, objfile); @@ -2824,19 +3688,6 @@ read_array_type (pp, type, objfile) create_range_type ((struct type *) NULL, index_type, lower, upper); type = create_array_type (type, element_type, range_type); - /* If we have an array whose element type is not yet known, but whose - bounds *are* known, record it to be adjusted at the end of the file. */ - /* FIXME: Why check for zero length rather than TYPE_FLAG_STUB? I think - the two have the same effect except that the latter is cleaner and the - former would be wrong for types which really are zero-length (if we - have any). */ - - if (TYPE_LENGTH (element_type) == 0 && !adjustable) - { - TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB; - add_undefined_type (type); - } - return type; } @@ -2859,6 +3710,8 @@ read_enum_type (pp, type, objfile) struct pending **symlist; struct pending *osyms, *syms; int o_nsyms; + int nbits; + int unsigned_enum = 1; #if 0 /* FIXME! The stabs produced by Sun CC merrily define things that ought @@ -2872,20 +3725,41 @@ read_enum_type (pp, type, objfile) osyms = *symlist; o_nsyms = osyms ? osyms->nsyms : 0; + if (os9k_stabs) + { + /* Size. Perhaps this does not have to be conditionalized on + os9k_stabs (assuming the name of an enum constant can't start + with a digit). */ + read_huge_number (pp, 0, &nbits); + if (nbits != 0) + return error_type (pp, objfile); + } + + /* The aix4 compiler emits an extra field before the enum members; + my guess is it's a type of some sort. Just ignore it. */ + if (**pp == '-') + { + /* Skip over the type. */ + while (**pp != ':') + (*pp)++; + + /* Skip over the colon. */ + (*pp)++; + } + /* Read the value-names and their values. The input syntax is NAME:VALUE,NAME:VALUE, and so on. A semicolon or comma instead of a NAME means the end. */ while (**pp && **pp != ';' && **pp != ',') { - int nbits; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); p = *pp; while (*p != ':') p++; name = obsavestring (*pp, p - *pp, &objfile -> symbol_obstack); *pp = p + 1; n = read_huge_number (pp, ',', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); @@ -2895,6 +3769,8 @@ read_enum_type (pp, type, objfile) SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_VALUE (sym) = n; + if (n < 0) + unsigned_enum = 0; add_symbol_to_list (sym, symlist); nsyms++; } @@ -2904,9 +3780,11 @@ read_enum_type (pp, type, objfile) /* Now fill in the fields of the type-structure. */ - TYPE_LENGTH (type) = sizeof (int); + TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT; TYPE_CODE (type) = TYPE_CODE_ENUM; TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; + if (unsigned_enum) + TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; TYPE_NFIELDS (type) = nsyms; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nsyms); @@ -2920,12 +3798,11 @@ read_enum_type (pp, type, objfile) that in something like "enum {FOO, LAST_THING=FOO}" we print FOO, not LAST_THING. */ - for (syms = *symlist, n = 0; syms; syms = syms->next) + for (syms = *symlist, n = nsyms - 1; syms; syms = syms->next) { - int j = 0; - if (syms == osyms) - j = o_nsyms; - for (; j < syms->nsyms; j++,n++) + int last = syms == osyms ? o_nsyms : 0; + int j = syms->nsyms; + for (; --j >= last; --n) { struct symbol *xsym = syms->symbol[j]; SYMBOL_TYPE (xsym) = type; @@ -2938,17 +3815,6 @@ read_enum_type (pp, type, objfile) break; } -#if 0 - /* This screws up perfectly good C programs with enums. FIXME. */ - /* Is this Modula-2's BOOLEAN type? Flag it as such if so. */ - if(TYPE_NFIELDS(type) == 2 && - ((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") && - STREQ(TYPE_FIELD_NAME(type,1),"FALSE")) || - (STREQ(TYPE_FIELD_NAME(type,1),"TRUE") && - STREQ(TYPE_FIELD_NAME(type,0),"FALSE")))) - TYPE_CODE(type) = TYPE_CODE_BOOL; -#endif - return type; } @@ -2983,7 +3849,7 @@ read_sun_builtin_type (pp, typenums, objfile) signed_type = 0; break; default: - return error_type (pp); + return error_type (pp, objfile); } (*pp)++; @@ -3001,22 +3867,35 @@ read_sun_builtin_type (pp, typenums, objfile) we will ignore it. */ read_huge_number (pp, ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); /* The second number is always 0, so ignore it too. */ read_huge_number (pp, ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); /* The third number is the number of bits for this type. */ type_bits = read_huge_number (pp, 0, &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); + /* The type *should* end with a semicolon. If it are embedded + in a larger type the semicolon may be the only way to know where + the type ends. If this type is at the end of the stabstring we + can deal with the omitted semicolon (but we don't have to like + it). Don't bother to complain(), Sun's compiler omits the semicolon + for "void". */ + if (**pp == ';') + ++(*pp); - return init_type (type_bits == 0 ? TYPE_CODE_VOID : TYPE_CODE_INT, - type_bits / TARGET_CHAR_BIT, - signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL, - objfile); + if (type_bits == 0) + return init_type (TYPE_CODE_VOID, 1, + signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL, + objfile); + else + return init_type (TYPE_CODE_INT, + type_bits / TARGET_CHAR_BIT, + signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL, + objfile); } static struct type * @@ -3033,12 +3912,12 @@ read_sun_floating_type (pp, typenums, objfile) FN_COMPLEX. */ details = read_huge_number (pp, ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); /* The second number is the number of bytes occupied by this type */ nbytes = read_huge_number (pp, ';', &nbits); if (nbits != 0) - return error_type (pp); + return error_type (pp, objfile); if (details == NF_COMPLEX || details == NF_COMPLEX16 || details == NF_COMPLEX32) @@ -3090,7 +3969,11 @@ read_huge_number (pp, end, bits) p++; } - upper_limit = LONG_MAX / radix; + if (os9k_stabs) + upper_limit = ULONG_MAX / radix; + else + upper_limit = LONG_MAX / radix; + while ((c = *p++) >= '0' && c < ('0' + radix)) { if (n <= upper_limit) @@ -3168,22 +4051,27 @@ read_range_type (pp, typenums, objfile) int typenums[2]; struct objfile *objfile; { + char *orig_pp = *pp; int rangenums[2]; long n2, n3; int n2bits, n3bits; int self_subrange; struct type *result_type; - struct type *index_type; + struct type *index_type = NULL; /* First comes a type we are a subrange of. In C it is usually 0, 1 or the type being defined. */ - /* FIXME: according to stabs.texinfo and AIX doc, this can be a type-id - not just a type number. */ if (read_type_number (pp, rangenums) != 0) - return error_type (pp); + return error_type (pp, objfile); self_subrange = (rangenums[0] == typenums[0] && rangenums[1] == typenums[1]); + if (**pp == '=') + { + *pp = orig_pp; + index_type = read_type (pp, objfile); + } + /* A semicolon should now follow; skip it. */ if (**pp == ';') (*pp)++; @@ -3194,8 +4082,11 @@ read_range_type (pp, typenums, objfile) n3 = read_huge_number (pp, ';', &n3bits); if (n2bits == -1 || n3bits == -1) - return error_type (pp); - + return error_type (pp, objfile); + + if (index_type) + goto handle_true_range; + /* If limits are huge, must be large integral type. */ if (n2bits != 0 || n3bits != 0) { @@ -3229,14 +4120,14 @@ read_range_type (pp, typenums, objfile) objfile); } else - return error_type (pp); + return error_type (pp, objfile); } /* A type defined as a subrange of itself, with bounds both 0, is void. */ if (self_subrange && n2 == 0 && n3 == 0) - return init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile); + return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile); - /* If n3 is zero and n2 is not, we want a floating type, + /* If n3 is zero and n2 is positive, we want a floating type, and n2 is the width in bytes. Fortran programs appear to use this for complex types also, @@ -3268,6 +4159,10 @@ read_range_type (pp, typenums, objfile) else if (self_subrange && n2 == 0 && n3 == 127) return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile); + else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill + && !self_subrange) + goto handle_true_range; + /* We used to do this only for subrange of self or subrange of int. */ else if (n2 == 0) { @@ -3303,14 +4198,12 @@ read_range_type (pp, typenums, objfile) /* We have a real range type on our hands. Allocate space and return a real pointer. */ + handle_true_range: - /* At this point I don't have the faintest idea how to deal with - a self_subrange type; I'm going to assume that this is used - as an idiom, and that all of them are special cases. So . . . */ if (self_subrange) - return error_type (pp); - - index_type = *dbx_lookup_type (rangenums); + index_type = builtin_type_int; + else + index_type = *dbx_lookup_type (rangenums); if (index_type == NULL) { /* Does this actually ever happen? Is that why we are worrying @@ -3350,7 +4243,7 @@ read_args (pp, end, objfile) /* Invalid argument list: no ','. */ return (struct type **)-1; (*pp)++; - STABS_CONTINUE (pp); + STABS_CONTINUE (pp, objfile); types[n++] = read_type (pp, objfile); } (*pp)++; /* get past `end' (the ':' character) */ @@ -3436,6 +4329,7 @@ common_block_end (objfile) sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); + /* Note: common_block_name already saved on symbol_obstack */ SYMBOL_NAME (sym) = common_block_name; SYMBOL_CLASS (sym) = LOC_BLOCK; @@ -3458,7 +4352,7 @@ common_block_end (objfile) for (j = common_block_i; j < common_block->nsyms; j++) add_symbol_to_list (common_block->symbol[j], &new); - SYMBOL_NAMESPACE (sym) = (enum namespace)((long) new); + SYMBOL_TYPE (sym) = (struct type *) new; /* Should we be putting local_symbols back to what it was? Does it matter? */ @@ -3478,7 +4372,7 @@ fix_common_block (sym, valu) struct symbol *sym; int valu; { - struct pending *next = (struct pending *) SYMBOL_NAMESPACE (sym); + struct pending *next = (struct pending *) SYMBOL_TYPE (sym); for ( ; next; next = next->next) { register int j; @@ -3532,7 +4426,7 @@ cleanup_undefined_types () case TYPE_CODE_ENUM: { /* Check if it has been defined since. Need to do this here - as well as in check_stub_type to deal with the (legitimate in + as well as in check_typedef to deal with the (legitimate in C though not C++) case of several types with the same name in different source files. */ if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB) @@ -3569,45 +4463,7 @@ cleanup_undefined_types () } break; - case TYPE_CODE_ARRAY: - { - /* This is a kludge which is here for historical reasons - because I suspect that check_stub_type does not get - called everywhere it needs to be called for arrays. Even - with this kludge, those places are broken for the case - where the stub type is defined in another compilation - unit, but this kludge at least deals with it for the case - in which it is the same compilation unit. - - Don't try to do this by calling check_stub_type; it might - cause symbols to be read in lookup_symbol, and the symbol - reader is not reentrant. */ - - struct type *range_type; - int lower, upper; - - if (TYPE_LENGTH (*type) != 0) /* Better be unknown */ - goto badtype; - if (TYPE_NFIELDS (*type) != 1) - goto badtype; - range_type = TYPE_FIELD_TYPE (*type, 0); - if (TYPE_CODE (range_type) != TYPE_CODE_RANGE) - goto badtype; - - /* Now recompute the length of the array type, based on its - number of elements and the target type's length. */ - lower = TYPE_FIELD_BITPOS (range_type, 0); - upper = TYPE_FIELD_BITPOS (range_type, 1); - TYPE_LENGTH (*type) = (upper - lower + 1) - * TYPE_LENGTH (TYPE_TARGET_TYPE (*type)); - - /* If the target type is not a stub, we could be clearing - TYPE_FLAG_TARGET_STUB for *type. */ - } - break; - default: - badtype: { static struct complaint msg = {"\ GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0}; @@ -3632,13 +4488,33 @@ scan_file_globals (objfile) struct minimal_symbol *msymbol; struct symbol *sym, *prev; - if (objfile->msymbols == 0) /* Beware the null file. */ + /* Avoid expensive loop through all minimal symbols if there are + no unresolved symbols. */ + for (hash = 0; hash < HASHSIZE; hash++) + { + if (global_sym_chain[hash]) + break; + } + if (hash >= HASHSIZE) return; - for (msymbol = objfile -> msymbols; SYMBOL_NAME (msymbol) != NULL; msymbol++) + for (msymbol = objfile -> msymbols; + msymbol && SYMBOL_NAME (msymbol) != NULL; + msymbol++) { QUIT; + /* Skip static symbols. */ + switch (MSYMBOL_TYPE (msymbol)) + { + case mst_file_text: + case mst_file_data: + case mst_file_bss: + continue; + default: + break; + } + prev = NULL; /* Get the hash index and check all the symbols @@ -3674,6 +4550,8 @@ scan_file_globals (objfile) { SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol); } + + SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol); if (prev) { @@ -3691,6 +4569,30 @@ scan_file_globals (objfile) } } } + + /* Change the storage class of any remaining unresolved globals to + LOC_UNRESOLVED and remove them from the chain. */ + for (hash = 0; hash < HASHSIZE; hash++) + { + sym = global_sym_chain[hash]; + while (sym) + { + prev = sym; + sym = SYMBOL_VALUE_CHAIN (sym); + + /* Change the symbol address from the misleading chain value + to address zero. */ + SYMBOL_VALUE_ADDRESS (prev) = 0; + + /* Complain about unresolved common block symbols. */ + if (SYMBOL_CLASS (prev) == LOC_STATIC) + SYMBOL_CLASS (prev) = LOC_UNRESOLVED; + else + complain (&unresolved_sym_chain_complaint, + objfile->name, SYMBOL_NAME (prev)); + } + } + memset (global_sym_chain, 0, sizeof (global_sym_chain)); } /* Initialize anything that needs initializing when starting to read @@ -3726,6 +4628,8 @@ void start_stabs () /* FIXME: If common_block_name is not already NULL, we should complain(). */ common_block_name = NULL; + + os9k_stabs = 0; } /* Call after end_symtab() */