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

📄 symtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Symbol table lookup for the GNU debugger, GDB.   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.  */#include "defs.h"#include "symtab.h"#include "gdbtypes.h"#include "gdbcore.h"#include "frame.h"#include "target.h"#include "value.h"#include "symfile.h"#include "objfiles.h"#include "gdbcmd.h"#include "call-cmds.h"#include "regex.h"#include "expression.h"#include "language.h"#include "demangle.h"#include <obstack.h>#include <assert.h>#include <sys/types.h>#include <fcntl.h>#include <string.h>#include <sys/stat.h>#include <ctype.h>/* Prototypes for local functions */static char *expensive_mangler PARAMS ((const char *));extern intfind_methods PARAMS ((struct type *, char *, char **, struct symbol **));static voidcompletion_list_add_symbol PARAMS ((char *, char *, int));static struct symtabs_and_linesdecode_line_2 PARAMS ((struct symbol *[], int, int));static voidrbreak_command PARAMS ((char *, int));static voidtypes_info PARAMS ((char *, int));static voidfunctions_info PARAMS ((char *, int));static voidvariables_info PARAMS ((char *, int));static voidsources_info PARAMS ((char *, int));static voidlist_symbols PARAMS ((char *, int, int));static voidoutput_source_filename PARAMS ((char *, int *));static char *operator_chars PARAMS ((char *, char **));static intfind_line_common PARAMS ((struct linetable *, int, int *));static struct partial_symbol *lookup_partial_symbol PARAMS ((struct partial_symtab *, const char *,			       int, enum namespace));static struct partial_symbol *lookup_demangled_partial_symbol PARAMS ((const struct partial_symtab *,					 const char *));static struct symbol *lookup_demangled_block_symbol PARAMS ((const struct block *, const char *));static struct symtab *lookup_symtab_1 PARAMS ((char *));/* *//* The single non-language-specific builtin type */struct type *builtin_type_error;/* Block in which the most recently searched-for symbol was found.   Might be better to make this a parameter to lookup_symbol and    value_of_this. */const struct block *block_found;char no_symtab_msg[] = "No symbol table is loaded.  Use the \"file\" command.";/* While the C++ support is still in flux, issue a possibly helpful hint on   using the new command completion feature on single quoted demangled C++   symbols.  Remove when loose ends are cleaned up.   FIXME -fnf */voidcplusplus_hint (name)     char *name;{  printf ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);  printf ("(Note leading single quote.)\n");}/* Check for a symtab of a specific name; first in symtabs, then in   psymtabs.  *If* there is no '/' in the name, a match after a '/'   in the symtab filename will also work.  */static struct symtab *lookup_symtab_1 (name)     char *name;{  register struct symtab *s;  register struct partial_symtab *ps;  register char *slash;  register struct objfile *objfile; got_symtab:  /* First, search for an exact match */  ALL_SYMTABS (objfile, s)    if (strcmp (name, s->filename) == 0)      return s;  slash = strchr (name, '/');  /* Now, search for a matching tail (only if name doesn't have any dirs) */  if (!slash)    ALL_SYMTABS (objfile, s)      {	char *p = s -> filename;	char *tail = strrchr (p, '/');	if (tail)	  p = tail + 1;	if (strcmp (p, name) == 0)	  return s;      }  /* Same search rules as above apply here, but now we look thru the     psymtabs.  */  ALL_PSYMTABS (objfile, ps)    if (strcmp (name, ps -> filename) == 0)      goto got_psymtab;  if (!slash)    ALL_PSYMTABS (objfile, ps)      {	char *p = ps -> filename;	char *tail = strrchr (p, '/');	if (tail)	  p = tail + 1;	if (strcmp (p, name) == 0)	  goto got_psymtab;      }  return (NULL); got_psymtab:  if (ps -> readin)    error ("Internal: readin %s pst for `%s' found when no symtab found.",	   ps -> filename, name);  s = PSYMTAB_TO_SYMTAB (ps);  if (s)    return s;  /* At this point, we have located the psymtab for this file, but     the conversion to a symtab has failed.  This usually happens     when we are looking up an include file.  In this case,     PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has     been created.  So, we need to run through the symtabs again in     order to find the file.     XXX - This is a crock, and should be fixed inside of the the     symbol parsing routines. */  goto got_symtab;}/* Lookup the symbol table of a source file named NAME.  Try a couple   of variations if the first lookup doesn't work.  */struct symtab *lookup_symtab (name)     char *name;{  register struct symtab *s;  register char *copy;  s = lookup_symtab_1 (name);  if (s) return s;  /* If name not found as specified, see if adding ".c" helps.  */  copy = (char *) alloca (strlen (name) + 3);  strcpy (copy, name);  strcat (copy, ".c");  s = lookup_symtab_1 (copy);  if (s) return s;  /* We didn't find anything; die.  */  return 0;}/* Lookup the partial symbol table of a source file named NAME.  This   only returns true on an exact match (ie. this semantics are   different from lookup_symtab.  */struct partial_symtab *lookup_partial_symtab (name)char *name;{  register struct partial_symtab *pst;  register struct objfile *objfile;    ALL_PSYMTABS (objfile, pst)    {      if (strcmp (name, pst -> filename) == 0)	{	  return (pst);	}    }  return (NULL);}/* Demangle a GDB method stub type.  */char *gdb_mangle_name (type, i, j)     struct type *type;     int i, j;{  int mangled_name_len;  char *mangled_name;  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);  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);  int is_constructor = strcmp(field_name, newname) == 0;  int is_destructor = is_constructor && physname[0] == '_'      && physname[1] == CPLUS_MARKER && physname[2] == '_';  /* Need a new type prefix.  */  char *const_prefix = method->is_const ? "C" : "";  char *volatile_prefix = method->is_volatile ? "V" : "";  char buf[20];#ifndef GCC_MANGLE_BUG  int len = strlen (newname);  if (is_destructor)    {      mangled_name = (char*) xmalloc(strlen(physname)+1);      strcpy(mangled_name, physname);      return mangled_name;    }  sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))			  + strlen (buf) + len			  + strlen (physname)			  + 1);  /* Only needed for GNU-mangled names.  ANSI-mangled names     work with the normal mechanisms.  */  if (OPNAME_PREFIX_P (field_name))    {      char *opname = cplus_mangle_opname (field_name + 3, 0);      if (opname == NULL)	error ("No mangling for \"%s\"", field_name);      mangled_name_len += strlen (opname);      mangled_name = (char *)xmalloc (mangled_name_len);      strncpy (mangled_name, field_name, 3);      mangled_name[3] = '\0';      strcat (mangled_name, opname);    }  else    {      mangled_name = (char *)xmalloc (mangled_name_len);      if (is_constructor)	mangled_name[0] = '\0';      else	strcpy (mangled_name, field_name);    }  strcat (mangled_name, buf);  strcat (mangled_name, newname);#else  char *opname;  if (is_constructor)    {      buf[0] = '\0';    }  else    {      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);    }  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))		      + strlen (buf) + strlen (physname) + 1);  /* Only needed for GNU-mangled names.  ANSI-mangled names     work with the normal mechanisms.  */  if (OPNAME_PREFIX_P (field_name))    {      opname = cplus_mangle_opname (field_name + 3, 0);      if (opname == NULL)	{	  error ("No mangling for \"%s\"", field_name);	}      mangled_name_len += strlen (opname);      mangled_name = (char *) xmalloc (mangled_name_len);      strncpy (mangled_name, field_name, 3);      strcpy (mangled_name + 3, opname);    }  else    {      mangled_name = (char *) xmalloc (mangled_name_len);      if (is_constructor)	{	  mangled_name[0] = '\0';	}      else	{	  strcpy (mangled_name, field_name);	}    }  strcat (mangled_name, buf);#endif  strcat (mangled_name, physname);  return (mangled_name);}/* Find which partial symtab on contains PC.  Return 0 if none.  */struct partial_symtab *find_pc_psymtab (pc)     register CORE_ADDR pc;{  register struct partial_symtab *pst;  register struct objfile *objfile;  ALL_PSYMTABS (objfile, pst)    {      if (pc >= pst -> textlow && pc < pst -> texthigh)	{	  return (pst);	}    }  return (NULL);}/* Find which partial symbol within a psymtab contains PC.  Return 0   if none.  Check all psymtabs if PSYMTAB is 0.  */struct partial_symbol *find_pc_psymbol (psymtab, pc)     struct partial_symtab *psymtab;     CORE_ADDR pc;{  struct partial_symbol *best, *p;  CORE_ADDR best_pc;    if (!psymtab)    psymtab = find_pc_psymtab (pc);  if (!psymtab)    return 0;  best_pc = psymtab->textlow - 1;  for (p = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;       (p - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)	< psymtab->n_static_syms);       p++)    if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE	&& SYMBOL_CLASS (p) == LOC_BLOCK	&& pc >= SYMBOL_VALUE_ADDRESS (p)	&& SYMBOL_VALUE_ADDRESS (p) > best_pc)      {	best_pc = SYMBOL_VALUE_ADDRESS (p);	best = p;      }  if (best_pc == psymtab->textlow - 1)    return 0;  return best;}/* Find the definition for a specified symbol name NAME   in namespace NAMESPACE, visible from lexical block BLOCK.   Returns the struct symbol pointer, or zero if no symbol is found.   If SYMTAB is non-NULL, store the symbol table in which the   symbol was found there, or NULL if not found.   C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if   NAME is a field of the current implied argument `this'.  If so set   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.    BLOCK_FOUND is set to the block in which NAME is found (in the case of   a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */struct symbol *lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)     const char *name;     register const struct block *block;     const enum namespace namespace;     int *is_a_field_of_this;     struct symtab **symtab;{  register struct symbol *sym;  register struct symtab *s;  register struct partial_symtab *ps;  struct blockvector *bv;  register struct objfile *objfile;  register struct block *b;  register struct minimal_symbol *msymbol;  char *temp;  extern char *gdb_completer_word_break_characters;  /* If NAME contains any characters from gdb_completer_word_break_characters     then it is probably from a quoted name string.  So check to see if it     has a C++ mangled equivalent, and if so, use the mangled equivalent. */  if (strpbrk (name, gdb_completer_word_break_characters) != NULL)    {      if ((temp = expensive_mangler (name)) != NULL)	{	  name = temp;	}    }  /* Search specified block and its superiors.  */  while (block != 0)    {      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    {	      /* Search the list of symtabs for one which contains the		 address of the start of this block.  */	      ALL_SYMTABS (objfile, s)		{		  bv = BLOCKVECTOR (s);		  b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);		  if (BLOCK_START (b) <= BLOCK_START (block)		      && BLOCK_END (b) > BLOCK_START (block))		    goto found;		}found:	      *symtab = s;	    }	  return (sym);	}      block = BLOCK_SUPERBLOCK (block);    }  /* But that doesn't do any demangling for the STATIC_BLOCK.

⌨️ 快捷键说明

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