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

📄 stabsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Support routines for decoding "stabs" debugging information format.   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992             Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* Support routines for reading and decoding debugging information in   the "stabs" format.  This format is used with many systems that use   the a.out object file format, as well as some systems that use   COFF or ELF where the stabs data is placed in a special section.   Avoid placing any object file format specific code in this file. */#include "defs.h"#include "bfd.h"#include "obstack.h"#include "symtab.h"#include "gdbtypes.h"#include "symfile.h"		/* Needed for "struct complaint" */#include "objfiles.h"#include "aout/stab_gnu.h"	/* We always use GNU stabs, not native */#include "buildsym.h"/* Ask stabsread.h to define the vars it normally declares `extern'.  */#define	EXTERN	/**/#include "stabsread.h"		/* Our own declarations */#undef	EXTERNstatic struct type *dbx_alloc_type PARAMS ((int [2], struct objfile *));static voidread_huge_number PARAMS ((char **, int, long *, int *));static voidpatch_block_stabs PARAMS ((struct pending *, struct pending_stabs *,			   struct objfile *));static voidfix_common_block PARAMS ((struct symbol *, int));static struct type *read_range_type PARAMS ((char **, int [2], struct objfile *));static struct type *read_sun_builtin_type PARAMS ((char **, int [2], struct objfile *));static struct type *read_sun_floating_type PARAMS ((char **, int [2], struct objfile *));static struct type *read_enum_type PARAMS ((char **, struct type *, struct objfile *));static struct type *read_struct_type PARAMS ((char **, struct type *, struct objfile *));static struct type *read_array_type PARAMS ((char **, struct type *, struct objfile *));static struct type **read_args PARAMS ((char **, int, struct objfile *));static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' };static const char vb_name[] =   { '_','v','b',CPLUS_MARKER,'\0' };/* Define this as 1 if a pcc declaration of a char or short argument   gives the correct address.  Otherwise assume pcc gives the   address of the corresponding int, which is not the same on a   big-endian machine.  */#ifndef BELIEVE_PCC_PROMOTION#define BELIEVE_PCC_PROMOTION 0#endif/* During some calls to read_type (and thus to read_range_type), this   contains the name of the type being defined.  Range types are only   used in C as basic types.  We use the name to distinguish the otherwise   identical basic types "int" and "long" and their unsigned versions.   FIXME, this should disappear with better type management.  */static char *long_kludge_name;#if 0struct complaint dbx_class_complaint ={  "encountered DBX-style class variable debugging information.\n\You seem to have compiled your program with \\"g++ -g0\" instead of \"g++ -g\".\n\Therefore GDB will not know about your class variables", 0, 0};#endifstruct complaint invalid_cpp_abbrev_complaint =  {"invalid C++ abbreviation `%s'", 0, 0};struct complaint invalid_cpp_type_complaint =  {"C++ abbreviated type name unknown at symtab pos %d", 0, 0};struct complaint member_fn_complaint =  {"member function type missing, got '%c'", 0, 0};struct complaint const_vol_complaint =  {"const/volatile indicator missing, got '%c'", 0, 0};struct complaint error_type_complaint =  {"debug info mismatch between compiler and debugger", 0, 0};struct complaint invalid_member_complaint =  {"invalid (minimal) member type data format at symtab pos %d.", 0, 0};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};/* Make a list of forward references which haven't been defined.  */static struct type **undef_types;static int undef_types_allocated;static int undef_types_length;inthashname (name)     char *name;{  register char *p = name;  register int total = p[0];  register int c;  c = p[1];  total += c << 2;  if (c)    {      c = p[2];      total += c << 4;      if (c)	{	  total += p[3] << 6;	}    }  /* Ensure result is positive.  */  if (total < 0)    {      total += (1000 << 6);    }  return (total % HASHSIZE);}/* Look up a dbx type-number pair.  Return the address of the slot   where the type for that number-pair is stored.   The number-pair is in TYPENUMS.   This can be used for finding the type associated with that pair   or for associating a new type with the pair.  */struct type **dbx_lookup_type (typenums)     int typenums[2];{  register int filenum = typenums[0];  register int index = typenums[1];  unsigned old_len;  register int real_filenum;  register struct header_file *f;  int f_orig_length;  if (filenum == -1)		/* -1,-1 is for temporary types.  */    return 0;  if (filenum < 0 || filenum >= n_this_object_header_files)    error ("Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",	   filenum, index, symnum);  if (filenum == 0)    {      /* Type is defined outside of header files.	 Find it in this object file's type vector.  */      if (index >= type_vector_length)	{	  old_len = type_vector_length;	  if (old_len == 0)	    {	      type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;	      type_vector = (struct type **)		malloc (type_vector_length * sizeof (struct type *));	    }	  while (index >= type_vector_length)	    {	      type_vector_length *= 2;	    }	  type_vector = (struct type **)	    xrealloc ((char *) type_vector,		      (type_vector_length * sizeof (struct type *)));	  memset (&type_vector[old_len], 0,		  (type_vector_length - old_len) * sizeof (struct type *));	}      return (&type_vector[index]);    }  else    {      real_filenum = this_object_header_files[filenum];      if (real_filenum >= n_header_files)	{	  abort ();	}      f = &header_files[real_filenum];      f_orig_length = f->length;      if (index >= f_orig_length)	{	  while (index >= f->length)	    {	      f->length *= 2;	    }	  f->vector = (struct type **)	    xrealloc ((char *) f->vector, f->length * sizeof (struct type *));	  memset (&f->vector[f_orig_length], 0,		  (f->length - f_orig_length) * sizeof (struct type *));	}      return (&f->vector[index]);    }}/* Make sure there is a type allocated for type numbers TYPENUMS   and return the type object.   This can create an empty (zeroed) type object.   TYPENUMS may be (-1, -1) to return a new type object that is not   put into the type vector, and so may not be referred to by number. */static struct type *dbx_alloc_type (typenums, objfile)     int typenums[2];     struct objfile *objfile;{  register struct type **type_addr;  if (typenums[0] == -1)    {      return (alloc_type (objfile));    }  type_addr = dbx_lookup_type (typenums);  /* If we are referring to a type not known at all yet,     allocate an empty type for it.     We will fill it in later if we find out how.  */  if (*type_addr == 0)    {      *type_addr = alloc_type (objfile);    }  return (*type_addr);}/* for all the stabs in a given stab vector, build appropriate types    and fix their symbols in given symbol vector. */static voidpatch_block_stabs (symbols, stabs, objfile)     struct pending *symbols;     struct pending_stabs *stabs;     struct objfile *objfile;{  int ii;  char *name;  char *pp;  struct symbol *sym;  if (stabs)    {            /* for all the stab entries, find their corresponding symbols and 	 patch their types! */            for (ii = 0; ii < stabs->count; ++ii)	{	  name = stabs->stab[ii];	  pp = (char*) strchr (name, ':');	  sym = find_symbol_in_list (symbols, name, pp-name);	  if (!sym)	    {#ifndef IBM6000_TARGET	      printf ("ERROR! stab symbol not found!\n");	/* FIXME */#endif	    }	  else	    {	      pp += 2;	      if (*(pp-1) == 'F' || *(pp-1) == 'f')		{		  SYMBOL_TYPE (sym) =		    lookup_function_type (read_type (&pp, objfile));		}	      else		{		  SYMBOL_TYPE (sym) = read_type (&pp, objfile);		}	    }	}    }}/* Read a number by which a type is referred to in dbx data,   or perhaps read a pair (FILENUM, TYPENUM) in parentheses.   Just a single number N is equivalent to (0,N).   Return the two numbers by storing them in the vector TYPENUMS.   TYPENUMS will then be used as an argument to dbx_lookup_type.  */voidread_type_number (pp, typenums)     register char **pp;     register int *typenums;{  if (**pp == '(')    {      (*pp)++;      typenums[0] = read_number (pp, ',');      typenums[1] = read_number (pp, ')');    }  else    {      typenums[0] = 0;      typenums[1] = read_number (pp, 0);    }}/* 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).  */static char *type_synonym_name;/* ARGSUSED */struct symbol *define_symbol (valu, string, desc, type, objfile)     unsigned int valu;     char *string;     int desc;     int type;     struct objfile *objfile;{  register struct symbol *sym;  char *p = (char *) strchr (string, ':');  int deftype;  int synonym = 0;  register int i;  struct type *temptype;  /* We would like to eliminate nameless symbols, but keep their types.     E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer     to type 2, but, should not creat a symbol to address that type. Since     the symbol will be nameless, there is no way any user can refer to it. */  int nameless;  /* Ignore syms with empty names.  */  if (string[0] == 0)    return 0;  /* Ignore old-style symbols from cc -go  */  if (p == 0)    return 0;  /* If a nameless stab entry, all we need is the type, not the symbol.     e.g. ":t10=*2" */  nameless = (p == string);  sym = (struct symbol *)     obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));  memset (sym, 0, sizeof (struct symbol));  if (processing_gcc_compilation)    {      /* GCC 2.x puts the line number in desc.  SunOS apparently puts in the	 number of bytes occupied by a type or object, which we ignore.  */      SYMBOL_LINE(sym) = desc;    }  else    {      SYMBOL_LINE(sym) = 0;			/* unknown */    }  if (string[0] == CPLUS_MARKER)    {      /* Special GNU C++ names.  */      switch (string[1])	{	  case 't':	    SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"),					      &objfile -> symbol_obstack);	    break;	  case 'v': /* $vtbl_ptr_type */	    /* Was: SYMBOL_NAME (sym) = "vptr"; */	    goto normal;	  case 'e':	    SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"),					      &objfile -> symbol_obstack);	    break;	  case '_':	    /* This was an anonymous type that was never fixed up.  */	    goto normal;	  default:	    abort ();	}    }  else    {    normal:      SYMBOL_NAME (sym)	= (char *)	obstack_alloc (&objfile -> symbol_obstack, ((p - string) + 1));      /* Open-coded bcopy--saves function call time.  */      {	register char *p1 = string;	register char *p2 = SYMBOL_NAME (sym);	while (p1 != p)	  {	    *p2++ = *p1++;	  }	*p2++ = '\0';      }    }

⌨️ 快捷键说明

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