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

📄 stabsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  p++;  /* Determine the type of name being defined.  */  /* The Acorn RISC machine's compiler can put out locals that don't     start with "234=" or "(3,4)=", so assume anything other than the     deftypes we know how to handle is a local.  */  if (!strchr ("cfFGpPrStTvVXCR", *p))    deftype = 'l';  else    deftype = *p++;  /* c is a special case, not followed by a type-number.     SYMBOL:c=iVALUE for an integer constant symbol.     SYMBOL:c=rVALUE for a floating constant symbol.     SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.        e.g. "b:c=e6,0" for "const b = blob1"	(where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */  if (deftype == 'c')    {      if (*p++ != '=')	error ("Invalid symbol data at symtab pos %d.", symnum);      switch (*p++)	{	case 'r':	  {	    double d = atof (p);	    char *dbl_valu;	    SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile,							 FT_DBL_PREC_FLOAT);	    dbl_valu = (char *)	      obstack_alloc (&objfile -> symbol_obstack, sizeof (double));	    memcpy (dbl_valu, &d, sizeof (double));	    SWAP_TARGET_AND_HOST (dbl_valu, sizeof (double));	    SYMBOL_VALUE_BYTES (sym) = dbl_valu;	    SYMBOL_CLASS (sym) = LOC_CONST_BYTES;	  }	  break;	case 'i':	  {	    SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile,							 FT_INTEGER);	    SYMBOL_VALUE (sym) = atoi (p);	    SYMBOL_CLASS (sym) = LOC_CONST;	  }	  break;	case 'e':	  /* SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.	     e.g. "b:c=e6,0" for "const b = blob1"	     (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */	  {	    int typenums[2];	    	    read_type_number (&p, typenums);	    if (*p++ != ',')	      error ("Invalid symbol data: no comma in enum const symbol");	    	    SYMBOL_TYPE (sym) = *dbx_lookup_type (typenums);	    SYMBOL_VALUE (sym) = atoi (p);	    SYMBOL_CLASS (sym) = LOC_CONST;	  }	  break;	default:	  error ("Invalid symbol data at symtab pos %d.", symnum);	}      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &file_symbols);      return sym;    }  /* Now usually comes a number that says which data type,     and possibly more stuff to define the type     (all of which is handled by read_type)  */  if (deftype == 'p' && *p == 'F')    /* pF is a two-letter code that means a function parameter in Fortran.       The type-number specifies the type of the return value.       Translate it into a pointer-to-function type.  */    {      p++;      SYMBOL_TYPE (sym)	= lookup_pointer_type (lookup_function_type (read_type (&p, objfile)));    }  else    {      /* The symbol class letter is followed by a type (typically the	 type of the symbol, or its return-type, or etc).  Read it.  */      synonym = *p == 't';      if (synonym)	{	  p += 1;	  type_synonym_name = obsavestring (SYMBOL_NAME (sym),					    strlen (SYMBOL_NAME (sym)),					    &objfile -> symbol_obstack);	}      /* Here we save the name of the symbol for read_range_type, which	 ends up reading in the basic types.  In stabs, unfortunately there	 is no distinction between "int" and "long" types except their	 names.  Until we work out a saner type policy (eliminating most	 builtin types and using the names specified in the files), we	 save away the name so that far away from here in read_range_type,	 we can examine it to decide between "int" and "long".  FIXME.  */      long_kludge_name = SYMBOL_NAME (sym);      SYMBOL_TYPE (sym) = read_type (&p, objfile);    }  switch (deftype)    {    case 'C':      /* The name of a caught exception.  */      SYMBOL_CLASS (sym) = LOC_LABEL;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      SYMBOL_VALUE_ADDRESS (sym) = valu;      add_symbol_to_list (sym, &local_symbols);      break;    case 'f':      /* A static function definition.  */      SYMBOL_CLASS (sym) = LOC_BLOCK;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &file_symbols);      /* fall into process_function_types.  */    process_function_types:      /* Function result types are described as the result type in stabs.	 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	}      /* fall into process_prototype_types */    process_prototype_types:      /* Sun acc puts declared types of arguments here.  We don't care	 about their actual types (FIXME -- we should remember the whole	 function prototype), but the list may define some new types	 that we have to remember, so we must scan it now.  */      while (*p == ';') {	p++;	read_type (&p, objfile);      }      break;    case 'F':      /* A global function definition.  */      SYMBOL_CLASS (sym) = LOC_BLOCK;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &global_symbols);      goto process_function_types;    case 'G':      /* For a class G (global) symbol, it appears that the	 value is not correct.  It is necessary to search for the	 corresponding linker definition to find the value.	 These definitions appear at the end of the namelist.  */      i = hashname (SYMBOL_NAME (sym));      SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];      global_sym_chain[i] = sym;      SYMBOL_CLASS (sym) = LOC_STATIC;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &global_symbols);      break;      /* 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 'l':      SYMBOL_CLASS (sym) = LOC_LOCAL;      SYMBOL_VALUE (sym) = valu;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &local_symbols);      break;    case 'p':      /* Normally this is a parameter, a LOC_ARG.  On the i960, it	 can also be a LOC_LOCAL_ARG depending on symbol type.  */#ifndef DBX_PARM_SYMBOL_CLASS#define	DBX_PARM_SYMBOL_CLASS(type)	LOC_ARG#endif      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 it's gcc-compiled, if it says `short', believe it.  */      if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)	break;#if defined(BELIEVE_PCC_PROMOTION_TYPE)      /* This macro is defined on machines (e.g. sparc) where	 we should believe the type of a PCC 'short' argument,	 but shouldn't believe the address (the address is	 the address of the corresponding int).  Note that	 this is only different from the BELIEVE_PCC_PROMOTION	 case on big-endian machines.	 My guess is that this correction, as opposed to changing	 the parameter to an 'int' (as done below, for PCC	 on most machines), is the right thing to do	 on all machines, but I don't want to risk breaking	 something that already works.  On most PCC machines,	 the sparc problem doesn't come up because the calling	 function has to zero the top bytes (not knowing whether	 the called function wants an int or a short), so there	 is no practical difference between an int and a short	 (except perhaps what happens when the GDB user types	 "print short_arg = 0x10000;"). 	 Hacked for SunOS 4.1 by gnu@cygnus.com.  In 4.1, the compiler	 actually produces the correct address (we don't need to fix it	 up).  I made this code adapt so that it will offset the symbol	 if it was pointing at an int-aligned location and not	 otherwise.  This way you can use the same gdb for 4.0.x and	 4.1 systems.	If the parameter is shorter than an int, and is integral	(e.g. char, short, or unsigned equivalent), and is claimed to	be passed on an integer boundary, don't believe it!  Offset the	parameter's address to the tail-end of that integer.  */      temptype = lookup_fundamental_type (objfile, FT_INTEGER);      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)	  && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT	  && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))	{	  SYMBOL_VALUE (sym) += TYPE_LENGTH (temptype)			      - TYPE_LENGTH (SYMBOL_TYPE (sym));	}      break;#else /* no BELIEVE_PCC_PROMOTION_TYPE.  */      /* If PCC says a parameter is a short or a char,	 it is really an int.  */      temptype = lookup_fundamental_type (objfile, FT_INTEGER);      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)	  && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)	{	  SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))	    ? lookup_fundamental_type (objfile, FT_UNSIGNED_INTEGER)	      : temptype;      }      break;#endif /* no BELIEVE_PCC_PROMOTION_TYPE.  */    case 'P':      /* acc seems to use P to delare 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)	goto process_prototype_types;      /* Parameter which is in a register.  */      SYMBOL_CLASS (sym) = LOC_REGPARM;      SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);      if (SYMBOL_VALUE (sym) >= NUM_REGS)	{	  complain (&reg_value_complaint, SYMBOL_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 'R':    case 'r':      /* Register variable (either global or local).  */      /* XXX */#ifdef sparc      if (! processing_gcc_compilation) {	      struct symbol *s0;	      	      /*	       * If we see a parm decl immediately followed by a reg decl of	       * the same name (and in the same block), we change it to a	       * single instance of a reg parm.  Sun's cc will generate these.	       */	      if (local_symbols && 		  (s0 = local_symbols->symbol[local_symbols->nsyms - 1]) &&		  SYMBOL_CLASS(s0) == LOC_ARG && 		  strcmp(SYMBOL_NAME(s0), SYMBOL_NAME(sym)) == 0) {		      SYMBOL_CLASS (s0) = LOC_REGPARM;		      SYMBOL_VALUE (s0) = STAB_REG_TO_REGNUM (valu);		      SYMBOL_NAMESPACE (s0) = VAR_NAMESPACE;		      return s0;	      }      }#endif      SYMBOL_CLASS (sym) = LOC_REGISTER;      SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);      if (SYMBOL_VALUE (sym) >= NUM_REGS)	{	  complain (&reg_value_complaint, SYMBOL_NAME (sym));	  SYMBOL_VALUE (sym) = SP_REGNUM;  /* Known safe, though useless */	}      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      if (within_function)        add_symbol_to_list (sym, &local_symbols);      else        add_symbol_to_list (sym, &file_symbols);      break;    case 'S':      /* Static symbol at top level of file */      SYMBOL_CLASS (sym) = LOC_STATIC;      SYMBOL_VALUE_ADDRESS (sym) = valu;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &file_symbols);      break;    case 't':      /* For a nameless type, we don't want a create a symbol, thus we	 did not use `sym'. Return without further processing. */      if (nameless) return NULL;      SYMBOL_CLASS (sym) = LOC_TYPEDEF;      SYMBOL_VALUE (sym) = valu;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      /* C++ vagaries: we may have a type which is derived from	a base type which did not have its name defined when the	derived class was output.  We fill in the derived class's	base part member's name here in that case.  */      if (TYPE_NAME (SYMBOL_TYPE (sym)) != NULL)        if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT		 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)		&& TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)))	 {	   int j;	   for (j = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; j >= 0; j--)	     if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) == 0)	       TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) =		 type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), j));	 }      add_symbol_to_list (sym, &file_symbols);      break;    case 'T':      /* For a nameless type, we don't want a create a symbol, thus we	 did not use `sym'. Return without further processing. */      if (nameless) return NULL;      SYMBOL_CLASS (sym) = LOC_TYPEDEF;      SYMBOL_VALUE (sym) = valu;      SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;      if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)	TYPE_NAME (SYMBOL_TYPE (sym))	  = obconcat (&objfile -> type_obstack, "",		      (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM		       ? "enum "		       : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT			  ? "struct " : "union ")),		      SYMBOL_NAME (sym));      add_symbol_to_list (sym, &file_symbols);      if (synonym)	{	  register struct symbol *typedef_sym = (struct symbol *)	    obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));	  memset (typedef_sym, 0, sizeof (struct symbol));	  SYMBOL_NAME (typedef_sym) = SYMBOL_NAME (sym);	  SYMBOL_TYPE (typedef_sym) = SYMBOL_TYPE (sym);	  SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF;	  SYMBOL_VALUE (typedef_sym) = valu;	  SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;	  add_symbol_to_list (typedef_sym, &file_symbols);	}      break;    case 'V':      /* Static symbol of local scope */      SYMBOL_CLASS (sym) = LOC_STATIC;      SYMBOL_VALUE_ADDRESS (sym) = valu;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &local_symbols);      break;    case 'v':      /* Reference parameter */      SYMBOL_CLASS (sym) = LOC_REF_ARG;      SYMBOL_VALUE (sym) = valu;      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)	 that Pascal uses it too, but when I tried it Pascal used	 "x:3" (local symbol) instead.  */      SYMBOL_CLASS (sym) = LOC_LOCAL;      SYMBOL_VALUE (sym) = valu;      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;      add_symbol_to_list (sym, &local_symbols);      break;    default:      error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum);    }  return sym;}/* Skip rest of this symbol and return an error type.   General notes on error recovery:  error_type always skips to the   end of the symbol (modulo cretinous dbx symbol name continuation).   Thus code like this:   if (*(*pp)++ != ';')     return error_type (pp);   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   start of the next symbol, which might produce strange results, at least   if you run off the end of the string table.  Instead use   if (**pp != ';')     return error_type (pp);   ++*pp;   or

⌨️ 快捷键说明

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