/* 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.
#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));
+
\f
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
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 *));
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. */
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;
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;
}
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;
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
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,
fill_symbuf (abfd);
bufp = &symbuf[symbuf_idx++];
SWAP_SYMBOL (bufp, abfd);
+ OBJSTAT (objfile, n_stabs++);
SET_NAMESTRING ();
fill_symbuf(abfd);
bufp = &symbuf[symbuf_idx++];
SWAP_SYMBOL (bufp, abfd);
+ OBJSTAT (objfile, n_stabs++);
type = bufp->n_type;
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 ();
}
{
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;
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 ();
}
&& 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);
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. */
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. */
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. */
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
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. */
#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)
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;
/* Skip the '='.
Also skip the type descriptor - we get it below with (*pp)[-1]. */
(*pp)+=2;
-
}
else
{
\f
/* 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: