⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stabsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		case 'B': /* `const' member functions. */		  new_sublist->fn_field.is_const = 1;		  new_sublist->fn_field.is_volatile = 0;	          (*pp)++;		  break;		case 'C': /* `volatile' member function. */		  new_sublist->fn_field.is_const = 0;		  new_sublist->fn_field.is_volatile = 1;	          (*pp)++;		  break;		case 'D': /* `const volatile' member function. */		  new_sublist->fn_field.is_const = 1;		  new_sublist->fn_field.is_volatile = 1;	          (*pp)++;		  break;		case '*': /* File compiled with g++ version 1 -- no info */		case '?':		case '.':		  break;		default:		  complain (&const_vol_complaint, (char *) (long) **pp);		  break;		}	      switch (*(*pp)++)		{		case '*':		  /* virtual member function, followed by index.  */		  /* The sign bit is set to distinguish pointers-to-methods		     from virtual function indicies.  Since the array is		     in words, the quantity must be shifted left by 1		     on 16 bit machine, and by 2 on 32 bit machine, forcing		     the sign bit out, and usable as a valid index into		     the array.  Remove the sign bit here.  */		  new_sublist->fn_field.voffset =		      (0x7fffffff & read_number (pp, ';')) + 2;		  if (**pp == '\\') *pp = next_symbol_text ();		  if (**pp == ';' || **pp == '\0')		    /* Must be g++ version 1.  */		    new_sublist->fn_field.fcontext = 0;		  else		    {		      /* Figure out from whence this virtual function came.			 It may belong to virtual function table of			 one of its baseclasses.  */		      look_ahead_type = read_type (pp, objfile);		      if (**pp == ':')			{ /* g++ version 1 overloaded methods. */ }		      else			{			  new_sublist->fn_field.fcontext = look_ahead_type;			  if (**pp != ';')			    return error_type (pp);			  else			    ++*pp;			  look_ahead_type = NULL;		        }		    }		  break;		case '?':		  /* static member function.  */		  new_sublist->fn_field.voffset = VOFFSET_STATIC;		  if (strncmp (new_sublist->fn_field.physname,			       main_fn_name, strlen (main_fn_name)))		    new_sublist->fn_field.is_stub = 1;		  break;		default:		  /* error */		  complain (&member_fn_complaint, (char *) (long) (*pp)[-1]);		  /* Fall through into normal member function.  */		case '.':		  /* normal member function.  */		  new_sublist->fn_field.voffset = 0;		  new_sublist->fn_field.fcontext = 0;		  break;		}	      new_sublist->next = sublist;	      sublist = new_sublist;	      length++;	      if (**pp == '\\') *pp = next_symbol_text ();	    }	  while (**pp != ';' && **pp != '\0');	  *pp += 1;	  new_mainlist->fn_fieldlist.fn_fields = (struct fn_field *)	    obstack_alloc (&objfile -> type_obstack,			   sizeof (struct fn_field) * length);	  memset (new_mainlist->fn_fieldlist.fn_fields, 0,		  sizeof (struct fn_field) * length);	  for (i = length; (i--, sublist); sublist = sublist->next)	    new_mainlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;	  new_mainlist->fn_fieldlist.length = length;	  new_mainlist->next = mainlist;	  mainlist = new_mainlist;	  nfn_fields++;	  total_length += length;	  if (**pp == '\\') *pp = next_symbol_text ();	}      while (**pp != ';');    }  *pp += 1;  if (nfn_fields)    {      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;    }  {    int i;    for (i = 0; i < TYPE_N_BASECLASSES (type); ++i)      {	if (TYPE_CODE (TYPE_BASECLASS (type, i)) == TYPE_CODE_UNDEF)	  /* @@ Memory leak on objfile->type_obstack?  */	  return error_type (pp);	TYPE_NFN_FIELDS_TOTAL (type) +=	  TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, i));      }  }  for (n = nfn_fields; mainlist; mainlist = mainlist->next) {    --n;                      /* Circumvent Sun3 compiler bug */    TYPE_FN_FIELDLISTS (type)[n] = mainlist->fn_fieldlist;  }  if (**pp == '~')    {      *pp += 1;      if (**pp == '=' || **pp == '+' || **pp == '-')	{	  /* Obsolete flags that used to indicate the presence	     of constructors and/or destructors. */	  *pp += 1;	}      /* Read either a '%' or the final ';'.  */      if (*(*pp)++ == '%')	{	  /* We'd like to be able to derive the vtable pointer field	     from the type information, but when it's inherited, that's	     hard.  A reason it's hard is because we may read in the	     info about a derived class before we read in info about	     the base class that provides the vtable pointer field.	     Once the base info has been read, we could fill in the info	     for the derived classes, but for the fact that by then,	     we don't remember who needs what.  */#if 0	  int predicted_fieldno = -1;#endif	  /* Now we must record the virtual function table pointer's	     field information.  */	  struct type *t;	  int i;#if 0	  {	    /* In version 2, we derive the vfield ourselves.  */	    for (n = 0; n < nfields; n++)	      {		if (! strncmp (TYPE_FIELD_NAME (type, n), vptr_name, 			       sizeof (vptr_name) -1))		  {		    predicted_fieldno = n;		    break;		  }	      }	    if (predicted_fieldno < 0)	      for (n = 0; n < TYPE_N_BASECLASSES (type); n++)		if (! TYPE_FIELD_VIRTUAL (type, n)		    && TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, n)) >= 0)		  {		    predicted_fieldno = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, n));		    break;		  }	  }#endif	  t = read_type (pp, objfile);	  p = (*pp)++;	  while (*p != '\0' && *p != ';')	    p++;	  if (*p == '\0')	    /* Premature end of symbol.  */	    return error_type (pp);	  	  TYPE_VPTR_BASETYPE (type) = t;	  if (type == t)	    {	      if (TYPE_FIELD_NAME (t, TYPE_N_BASECLASSES (t)) == 0)		{		  /* FIXME-tiemann: what's this?  */#if 0		  TYPE_VPTR_FIELDNO (type) = i = TYPE_N_BASECLASSES (t);#else		  error_type (pp);#endif		}	      else for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); --i)		if (! strncmp (TYPE_FIELD_NAME (t, i), vptr_name, 			       sizeof (vptr_name) - 1))		  {		    TYPE_VPTR_FIELDNO (type) = i;		    break;		  }	      if (i < 0)		/* Virtual function table field not found.  */		return error_type (pp);	    }	  else	    TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);#if 0	  if (TYPE_VPTR_FIELDNO (type) != predicted_fieldno)	    error ("TYPE_VPTR_FIELDNO miscalculated");#endif	  *pp = p + 1;	}    }  return type;}/* Read a definition of an array type,   and create and return a suitable type object.   Also creates a range type which represents the bounds of that   array.  */static struct type *read_array_type (pp, type, objfile)     register char **pp;     register struct type *type;     struct objfile *objfile;{  struct type *index_type, *element_type, *range_type;  int lower, upper;  int adjustable = 0;  /* Format of an array type:     "ar<index type>;lower;upper;<array_contents_type>".  Put code in     to handle this.     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 (!(**pp >= '0' && **pp <= '9'))    {      *pp += 1;      adjustable = 1;    }  lower = read_number (pp, ';');  if (!(**pp >= '0' && **pp <= '9'))    {      *pp += 1;      adjustable = 1;    }  upper = read_number (pp, ';');    element_type = read_type (pp, objfile);  if (adjustable)    {      lower = 0;      upper = -1;    }  {    /* Create range type.  */    range_type = alloc_type (objfile);    TYPE_CODE (range_type) = TYPE_CODE_RANGE;    TYPE_TARGET_TYPE (range_type) = index_type;    /* This should never be needed.  */    TYPE_LENGTH (range_type) = sizeof (int);    TYPE_NFIELDS (range_type) = 2;    TYPE_FIELDS (range_type) = (struct field *)      TYPE_ALLOC (range_type, 2 * sizeof (struct field));    memset (TYPE_FIELDS (range_type), 0, 2 * sizeof (struct field));    TYPE_FIELD_BITPOS (range_type, 0) = lower;    TYPE_FIELD_BITPOS (range_type, 1) = upper;  }  TYPE_CODE (type) = TYPE_CODE_ARRAY;  TYPE_TARGET_TYPE (type) = element_type;  TYPE_LENGTH (type) = (upper - lower + 1) * TYPE_LENGTH (element_type);  TYPE_NFIELDS (type) = 1;  TYPE_FIELDS (type) = (struct field *)    TYPE_ALLOC (type, sizeof (struct field));  memset (TYPE_FIELDS (type), 0, sizeof (struct field));  TYPE_FIELD_TYPE (type, 0) = 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.  */  if (TYPE_LENGTH (element_type) == 0 && !adjustable)    add_undefined_type (type);  return type;}/* Read a definition of an enumeration type,   and create and return a suitable type object.   Also defines the symbols that represent the values of the type.  */static struct type *read_enum_type (pp, type, objfile)     register char **pp;     register struct type *type;     struct objfile *objfile;{  register char *p;  char *name;  register long n;  register struct symbol *sym;  int nsyms = 0;  struct pending **symlist;  struct pending *osyms, *syms;  int o_nsyms;#if 0  /* FIXME!  The stabs produced by Sun CC merrily define things that ought     to be file-scope, between N_FN entries, using N_LSYM.  What's a mother     to do?  For now, force all enum values to file scope.  */  if (within_function)    symlist = &local_symbols;  else#endif    symlist = &file_symbols;  osyms = *symlist;  o_nsyms = osyms ? osyms->nsyms : 0;  /* 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 != ',')    {      /* Check for and handle cretinous dbx symbol name continuation!  */      if (**pp == '\\')	*pp = next_symbol_text ();      p = *pp;      while (*p != ':') p++;      name = obsavestring (*pp, p - *pp, &objfile -> symbol_obstack);      *pp = p + 1;      n = read_number (pp, ',');      sym = (struct symbol *)	obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));      memset (sym, 0, sizeof (struct symbol));      SYMBOL_NAME (sym) = name;      SYMBOL_CLASS (sym) = LOC_CONST;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      SYMBOL_VALUE (sym) = n;      add_symbol_to_list (sym, symlist);      nsyms++;    }  if (**pp == ';')    (*pp)++;			/* Skip the semicolon.  */  /* Now fill in the fields of the type-structure.  */  TYPE_LENGTH (type) = sizeof (int);  TYPE_CODE (type) = TYPE_CODE_ENUM;  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;  TYPE_NFIELDS (type) = nsyms;  TYPE_FIELDS (type) = (struct field *)    TYPE_ALLOC (type, sizeof (struct field) * nsyms);  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nsyms);  /* Find the symbols for the values and put them into the type.     The symbols can be found in the symlist that we put them on     to cause them to be defined.  osyms contains the old value     of that symlist; everything up to there was defined by us.  */  /* Note that we preserve the order of the enum constants, so     that in something like "enum {FOO, LAST_THING=FOO}" we print     FOO, not LAST_THING.  */  for (syms = *symlist, n = 0; syms; syms = syms->next)    {      int j = 0;      if (syms == osyms)	j = o_nsyms;      for (; j < syms->nsyms; j++,n++)	{	  struct symbol *xsym = syms->symbol[j];	  SYMBOL_TYPE (xsym) = type;	  TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);	  TYPE_FIELD_VALUE (type, n) = 0;	  TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);	  TYPE_FIELD_BITSIZE (type, n) = 0;	}      if (syms == osyms)	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 &&     ((!strcmp(TYPE_FIELD_NAME(type,0),"TRUE") &&       !strcmp(TYPE_FIELD_NAME(type,1),"FALSE")) ||      (!strcmp(TYPE_FIELD_NAME(type,1),"TRUE") &&       !strcmp(TYPE_FIELD_NAME(type,0),"FALSE"))))     TYPE_CODE(type) = TYPE_CODE_BOOL;#endif  return type;}/* Sun's ACC uses a somewhat saner method for specifying the builtin   typedefs in every file (for int, long, etc):	type = b <signed> <width>; <offset>; <nbits>	signed = u or s.  Possible c in addition to u or s (for char?).	offset = offset from high order bit to start bit of type.	width is # bytes in object of this type, nbits is # bits in type.   The width/offset stuff appears to be for small objects stored in   larger ones (e.g. `shorts' in `int' registers).  We i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -