diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/dbxread.c | 118 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 196 | ||||
-rw-r--r-- | gdb/partial-stab.h | 3 | ||||
-rw-r--r-- | gdb/stabsread.c | 513 |
4 files changed, 814 insertions, 16 deletions
diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 9ec4c16..720c6b4 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1,5 +1,5 @@ /* Read dbx symbol tables and convert to internal format, for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995 + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -65,6 +65,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "aout/aout64.h" #include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */ +/* defined in stabsread.c; used for completing cfront stabs strings */ +extern void resolve_cont PARAMS((struct objfile * objfile, struct symbol * sym, char * p)); + /* We put a pointer to this structure in the read_symtab_private field of the psymtab. */ @@ -242,7 +245,7 @@ static void init_bincl_list PARAMS ((int, struct objfile *)); static char * -dbx_next_symbol_text PARAMS ((void)); +dbx_next_symbol_text PARAMS ((struct objfile *)); static void fill_symbuf PARAMS ((bfd *)); @@ -706,6 +709,7 @@ dbx_symfile_init (objfile) DBX_STRINGTAB (objfile) = (char *) obstack_alloc (&objfile -> psymbol_obstack, DBX_STRINGTAB_SIZE (objfile)); + OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile)); /* Now read in the string table in one big gulp. */ @@ -742,6 +746,68 @@ static struct internal_nlist symbuf[4096]; static int symbuf_idx; static int symbuf_end; +/* cont_elem is used for continuing information in cfront. + It saves information about which types need to be fixed up and + completed after all the stabs are read. */ +struct cont_elem + { + /* sym and stabsstring for continuing information in cfront */ + struct symbol * sym; + char * stabs; + /* state dependancies (statics that must be preserved) */ + int sym_idx; + int sym_end; + int symnum; + /* other state dependancies include: + (assumption is that these will not change since process_now FIXME!!) + stringtab_global + n_stabs + objfile + symfile_bfd */ +}; +static struct cont_elem cont_list[100]; +static int cont_count = 0; + +void +process_later(sym,p) + struct symbol * sym; + char * p; +{ + /* save state so we can process these stabs later */ + cont_list[cont_count].sym_idx = symbuf_idx; + cont_list[cont_count].sym_end = symbuf_end; + cont_list[cont_count].symnum = symnum; + cont_list[cont_count].sym = sym; + cont_list[cont_count].stabs = p; + cont_count++; +} + +void +process_now(objfile) + struct objfile * objfile; +{ + int i; + /* save original state */ + int save_symbuf_idx = symbuf_idx; + int save_symbuf_end = symbuf_end; + int save_symnum = symnum; + for (i=0; i<cont_count; i++) + { + /* set state as if we were parsing stabs strings + for this symbol */ + symbuf_idx = cont_list[i].sym_idx; /* statics used by gdb */ + symbuf_end = cont_list[i].sym_end; + symnum = cont_list[i].symnum; + resolve_cont(objfile,cont_list[i].sym,cont_list[i].stabs); + } + /* restore original state */ + symbuf_idx = save_symbuf_idx; + symbuf_end = save_symbuf_end; + symnum = save_symnum; + cont_count=0; /* reset for next run */ +} + + /* Name of last function encountered. Used in Solaris to approximate object file boundaries. */ static char *last_function_name; @@ -825,12 +891,14 @@ fill_symbuf (sym_bfd) call this function to get the continuation. */ static char * -dbx_next_symbol_text () +dbx_next_symbol_text (objfile) + struct objfile *objfile; { if (symbuf_idx == symbuf_end) fill_symbuf (symfile_bfd); symnum++; SWAP_SYMBOL(&symbuf[symbuf_idx], symfile_bfd); + OBJSTAT (objfile, n_stabs++); return symbuf[symbuf_idx++].n_strx + stringtab_global + file_string_table_offset; } @@ -1066,6 +1134,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size) int nsl; int past_first_source_file = 0; CORE_ADDR last_o_file_start = 0; + CORE_ADDR last_function_start = 0; struct cleanup *back_to; bfd *abfd; @@ -1128,6 +1197,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size) if (bufp->n_type == (unsigned char)N_SLINE) continue; SWAP_SYMBOL (bufp, abfd); + OBJSTAT (objfile, n_stabs++); /* Ok. There is a lot of code duplicated in the rest of this switch statement (for efficiency reasons). Since I don't @@ -1207,8 +1277,8 @@ start_psymtab (objfile, section_offsets, char *filename; CORE_ADDR textlow; int ldsymoff; - struct partial_symbol *global_syms; - struct partial_symbol *static_syms; + struct partial_symbol **global_syms; + struct partial_symbol **static_syms; { struct partial_symtab *result = start_psymtab_common(objfile, section_offsets, @@ -1561,6 +1631,7 @@ read_ofile_symtab (pst) fill_symbuf (abfd); bufp = &symbuf[symbuf_idx++]; SWAP_SYMBOL (bufp, abfd); + OBJSTAT (objfile, n_stabs++); SET_NAMESTRING (); @@ -1616,6 +1687,7 @@ read_ofile_symtab (pst) fill_symbuf(abfd); bufp = &symbuf[symbuf_idx++]; SWAP_SYMBOL (bufp, abfd); + OBJSTAT (objfile, n_stabs++); type = bufp->n_type; @@ -1669,8 +1741,17 @@ read_ofile_symtab (pst) if (last_source_start_addr == 0) last_source_start_addr = text_offset; - pst->symtab = end_symtab (text_offset + text_size, 0, 0, objfile, - SECT_OFF_TEXT); + /* In reordered executables last_source_start_addr may not be the + lower bound for this symtab, instead use text_offset which comes + from pst->textlow which is correct. */ + if (last_source_start_addr > text_offset) + last_source_start_addr = text_offset; + + pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT); + + if (ARM_DEMANGLING) /* process incomplete C++ types now */ + process_now(objfile); + end_stabs (); } @@ -1745,6 +1826,21 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile) { case N_FUN: case N_FNAME: + + if (! strcmp (name, "")) + { + /* This N_FUN marks the end of a function. This closes off the + current block. */ + within_function = 0; + new = pop_context (); + + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + function_start_offset, function_start_offset + valu, + objfile); + break; + } + /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); goto define_a_symbol; @@ -1896,7 +1992,7 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile) patch_subfile_names (current_subfile, name); break; /* Ignore repeated SOs */ } - end_symtab (valu, 0, 0, objfile, SECT_OFF_TEXT); + end_symtab (valu, objfile, SECT_OFF_TEXT); end_stabs (); } @@ -2131,7 +2227,8 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile) && SYMBOL_NAME (m) [l] == '\0') /* last_pc_address was in this function */ valu = SYMBOL_VALUE (m); - else if (m && STREQN (SYMBOL_NAME (m+1), name, l) + else if (m && SYMBOL_NAME (m+1) + && STREQN (SYMBOL_NAME (m+1), name, l) && SYMBOL_NAME (m+1) [l] == '\0') /* last_pc_address was in last function */ valu = SYMBOL_VALUE (m+1); @@ -2268,6 +2365,7 @@ coffstab_build_psymtabs (objfile, section_offsets, mainline, error ("ridiculous string table size: %d bytes", stabstrsize); DBX_STRINGTAB (objfile) = (char *) obstack_alloc (&objfile->psymbol_obstack, stabstrsize+1); + OBJSTAT (objfile, sz_strtab += stabstrsize+1); /* Now read in the string table in one big gulp. */ @@ -2373,6 +2471,7 @@ elfstab_build_psymtabs (objfile, section_offsets, mainline, error ("ridiculous string table size: %d bytes", stabstrsize); DBX_STRINGTAB (objfile) = (char *) obstack_alloc (&objfile->psymbol_obstack, stabstrsize+1); + OBJSTAT (objfile, sz_strtab += stabstrsize+1); /* Now read in the string table in one big gulp. */ @@ -2460,6 +2559,7 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name, error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile)); DBX_STRINGTAB (objfile) = (char *) obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1); + OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1); /* Now read in the string table in one big gulp. */ diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 13a111f..44827ab 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -971,6 +971,199 @@ check_typedef (type) return type; } +/* New code added to support parsing of Cfront stabs strings */ +#include <ctype.h> +#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; } +#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; } +struct extra { char str[128]; int len; }; /* maximum extention is 128! FIXME */ +void +add_name(pextras,n) + struct extra * pextras; + char * n; +{ + char lenstr[512]; /* FIXME! hardcoded :-( */ + int nlen, lenstrlen; + if ((nlen = (n ? strlen(n) : 0))==0) + return; + sprintf(pextras->str+pextras->len,"%d%s",nlen,n); + pextras->len=strlen(pextras->str); +} + +void +add_mangled_type(pextras,t) + struct extra * pextras; + struct type * t; +{ + enum type_code tcode; + int tlen, tflags; + char * tname; + + tcode = TYPE_CODE(t); + tlen = TYPE_LENGTH(t); + tflags = TYPE_FLAGS(t); + tname = TYPE_NAME(t); + /* args of "..." seem to get mangled as "e" */ + + switch (tcode) + { + case TYPE_CODE_INT: + if (tflags==1) + ADD_EXTRA('U'); + switch (tlen) + { + case 1: + ADD_EXTRA('c'); + break; + case 2: + ADD_EXTRA('s'); + break; + case 4: + { + char* pname; + if ((pname=strrchr(tname,'l'),pname) && !strcmp(pname,"long")) + ADD_EXTRA('l') + else + ADD_EXTRA('i') + } + break; + default: + { + + static struct complaint msg = {"Bad int type code length x%x\n",0,0}; + + complain (&msg, tlen); + + } + } + break; + case TYPE_CODE_FLT: + switch (tlen) + { + case 4: + ADD_EXTRA('f'); + break; + case 8: + ADD_EXTRA('d'); + break; + case 16: + ADD_EXTRA('r'); + break; + default: + { + static struct complaint msg = {"Bad float type code length x%x\n",0,0}; + complain (&msg, tlen); + } + } + break; + case TYPE_CODE_REF: + ADD_EXTRA('R'); + /* followed by what it's a ref to */ + break; + case TYPE_CODE_PTR: + ADD_EXTRA('P'); + /* followed by what it's a ptr to */ + break; + case TYPE_CODE_TYPEDEF: + { + static struct complaint msg = {"Typedefs in overloaded functions not yet supported\n",0,0}; + complain (&msg); + } + /* followed by type bytes & name */ + break; + case TYPE_CODE_FUNC: + ADD_EXTRA('F'); + /* followed by func's arg '_' & ret types */ + break; + case TYPE_CODE_VOID: + ADD_EXTRA('v'); + break; + case TYPE_CODE_METHOD: + ADD_EXTRA('M'); + /* followed by name of class and func's arg '_' & ret types */ + add_name(pextras,tname); + ADD_EXTRA('F'); /* then mangle function */ + break; + case TYPE_CODE_STRUCT: /* C struct */ + case TYPE_CODE_UNION: /* C union */ + case TYPE_CODE_ENUM: /* Enumeration type */ + /* followed by name of type */ + add_name(pextras,tname); + break; + + /* errors possible types/not supported */ + case TYPE_CODE_CHAR: + case TYPE_CODE_ARRAY: /* Array type */ + case TYPE_CODE_MEMBER: /* Member type */ + case TYPE_CODE_BOOL: + case TYPE_CODE_COMPLEX: /* Complex float */ + case TYPE_CODE_UNDEF: + case TYPE_CODE_SET: /* Pascal sets */ + case TYPE_CODE_RANGE: + case TYPE_CODE_STRING: + case TYPE_CODE_BITSTRING: + case TYPE_CODE_ERROR: + default: + { + static struct complaint msg = {"Unknown type code x%x\n",0,0}; + complain (&msg, tcode); + } + } + if (t->target_type) + add_mangled_type(pextras,t->target_type); +} + +char * +cfront_mangle_name(type, i, j) + struct type *type; + int i; + int j; +{ + struct fn_field *f; + char *mangled_name = gdb_mangle_name (type, i, j); + + f = TYPE_FN_FIELDLIST1 (type, i); /* moved from below */ + + /* kludge to support cfront methods - gdb expects to find "F" for + ARM_mangled names, so when we mangle, we have to add it here */ + if (ARM_DEMANGLING) + { + int k; + char * arm_mangled_name; + struct fn_field *method = &f[j]; + char *field_name = TYPE_FN_FIELDLIST_NAME (type, i); + char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); + char *newname = type_name_no_tag (type); + + struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); + int nargs = TYPE_NFIELDS(ftype); /* number of args */ + struct extra extras, * pextras = &extras; + INIT_EXTRA + + if (TYPE_FN_FIELD_STATIC_P (f, j)) /* j for sublist within this list */ + ADD_EXTRA('S') + ADD_EXTRA('F') + /* add args here! */ + if (nargs <= 1) /* no args besides this */ + ADD_EXTRA('v') + else { + for (k=1; k<nargs; k++) + { + struct type * t; + t = TYPE_FIELD_TYPE(ftype,k); + add_mangled_type(pextras,t); + } + } + ADD_EXTRA('\0') + printf("add_mangled_type: %s\n",extras.str); /* FIXME */ + arm_mangled_name = malloc(strlen(mangled_name)+extras.len); + sprintf(arm_mangled_name,"%s%s",mangled_name,extras.str); + free(mangled_name); + mangled_name = arm_mangled_name; + } +} +#undef ADD_EXTRA +/* End of new code added to support parsing of Cfront stabs strings */ + /* Ugly hack to convert method stubs into method types. He ain't kiddin'. This demangles the name of the method into a string @@ -1075,7 +1268,8 @@ check_stub_method (type, i, j) free (demangled_name); - f = TYPE_FN_FIELDLIST1 (type, i); + f = TYPE_FN_FIELDLIST1 (type, i); + TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name; /* Now update the old "stub" type into a real type. */ diff --git a/gdb/partial-stab.h b/gdb/partial-stab.h index d006809..9fe653b 100644 --- a/gdb/partial-stab.h +++ b/gdb/partial-stab.h @@ -635,6 +635,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ case '8': case '9': case '-': + /* added to support cfront stabs strings */ + case 'Z': /* for definition continuations */ + case 'P': /* for prototypes */ continue; case ':': diff --git a/gdb/stabsread.c b/gdb/stabsread.c index fce9162..64f87cd 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -497,6 +497,489 @@ read_type_number (pp, typenums) #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; + char 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: class A : Bpri, public Bpub, virtual Bvir + A:T(0,27)=s20b__4Bpri:(0,3),0,32;OBpub:(0,25),32,8;a__1A:(0,3),64,32;PBvir:(0,28)=*(0,26),96,32;OBvir:(0,26),128,8;; + A:ZcA;2@Bpri 1@Bpub v2@Bvir;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_noterm = {"\ + Base classes not terminated while reading stabs string %s.\n", + 0, 0}; + 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; + } + + /* 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 from read_baseclasses) */ + 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; + } + ++(*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<p2) + bname = get_substring(pp,' '); + else + bname = get_substring(pp,';'); + if (!bname || !*bname) + { + complain (&msg_unknown, *pp); + return; + } + /* FIXME! attach base info to type */ + bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name*/ + if (bsym) + { + struct type * btype = SYMBOL_TYPE(bsym); + new -> field.type = btype; + new -> field.name = type_name_no_tag (new -> field.type); + } + else + { + complain (&msg_notfound, *pp); + return; + } + } + + /* 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; +} + +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_cont(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 field_info * fip = &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) */ + || !attach_fields_to_type (&fi, type, objfile) + || !read_cfront_member_functions (&fi, &p, 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 */ + + /* ARGSUSED */ struct symbol * define_symbol (valu, string, desc, type, objfile) @@ -1215,6 +1698,30 @@ 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, objfile); SYMBOL_CLASS (sym) = LOC_CONST; @@ -1349,7 +1856,6 @@ read_type (pp, objfile) /* Skip the '='. Also skip the type descriptor - we get it below with (*pp)[-1]. */ (*pp)+=2; - } else { @@ -1897,11 +2403,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: |