📄 stabsread.c
字号:
/* 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 + -