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

📄 symtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     I'm not sure whether demangling is needed in the case of     nested function in inner blocks; if so this needs to be changed.          Don't need to mess with the psymtabs; if we have a block,     that file is read in.  If we don't, then we deal later with     all the psymtab stuff that needs checking.  */  if (namespace == VAR_NAMESPACE && block != NULL)    {      struct block *b;      /* Find the right symtab.  */      ALL_SYMTABS (objfile, s)	{	  bv = BLOCKVECTOR (s);	  b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	  if (BLOCK_START (b) <= BLOCK_START (block)	      && BLOCK_END (b) > BLOCK_START (block))	    {	      sym = lookup_demangled_block_symbol (b, name);	      if (sym)		{		  block_found = b;		  if (symtab != NULL)		    *symtab = s;		  return sym;		}	    }	}    }  /* C++: If requested to do so by the caller,      check to see if NAME is a field of `this'. */  if (is_a_field_of_this)    {      struct value *v = value_of_this (0);            *is_a_field_of_this = 0;      if (v && check_field (v, name))	{	  *is_a_field_of_this = 1;	  if (symtab != NULL)	    *symtab = NULL;	  return 0;	}    }  /* Now search all global blocks.  Do the symtab's first, then     check the psymtab's */    ALL_SYMTABS (objfile, s)    {      bv = BLOCKVECTOR (s);      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  /* Check for the possibility of the symbol being a global function     that is stored in one of the minimal symbol tables.  Eventually, all     global symbols might be resolved in this way.  */    if (namespace == VAR_NAMESPACE)    {      msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL);      if (msymbol == NULL)	{	  /* Test each minimal symbol to see if the minimal symbol's name	     is a C++ mangled name that matches a user visible name.  */	  char *demangled;	  ALL_MSYMBOLS (objfile, msymbol)	    {	      demangled = demangle_and_match (msymbol -> name, name,					      DMGL_PARAMS | DMGL_ANSI);	      if (demangled != NULL)		{		  free (demangled);		  goto found_msym;		}	    }	  msymbol = NULL;		/* Not found */        }found_msym:      if (msymbol != NULL)	{	  s = find_pc_symtab (msymbol -> address);	  /* If S is NULL, there are no debug symbols for this file.	     Skip this stuff and check for matching static symbols below. */	  if (s != NULL)	    {	      bv = BLOCKVECTOR (s);	      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);	      sym = lookup_block_symbol (block, msymbol -> name, namespace);              /* We kept static functions in minimal symbol table as well as		 in static scope. We want to find them in the symbol table. */		if (!sym) {		  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);		  sym = lookup_block_symbol (block, msymbol -> name,					     namespace);		}	      /* sym == 0 if symbol was found in the minimal symbol table		 but not in the symtab.		 Return 0 to use the msymbol definition of "foo_".		 This happens for Fortran  "foo_" symbols,		 which are "foo" in the symtab.		 This can also happen if "asm" is used to make a		 regular symbol but not a debugging symbol, e.g.		 asm(".globl _main");		 asm("_main:");		 */	      if (symtab != NULL)		*symtab = s;	      return sym;	    }	}    }        ALL_PSYMTABS (objfile, ps)    {      if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))	{	  s = PSYMTAB_TO_SYMTAB(ps);	  bv = BLOCKVECTOR (s);	  block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);	  sym = lookup_block_symbol (block, name, namespace);	  if (!sym)	    error ("Internal: global symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  /* Now search all per-file blocks.     Not strictly correct, but more useful than an error.     Do the symtabs first, then check the psymtabs */  ALL_SYMTABS (objfile, s)    {      bv = BLOCKVECTOR (s);      block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  ALL_PSYMTABS (objfile, ps)    {      if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))	{	  s = PSYMTAB_TO_SYMTAB(ps);	  bv = BLOCKVECTOR (s);	  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	  sym = lookup_block_symbol (block, name, namespace);	  if (!sym)	    error ("Internal: static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  /* Now search all per-file blocks for static mangled symbols.     Do the symtabs first, then check the psymtabs.  */  if (namespace == VAR_NAMESPACE)    {      ALL_SYMTABS (objfile, s)	{	  bv = BLOCKVECTOR (s);	  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	  sym = lookup_demangled_block_symbol (block, name);	  if (sym) 	    {	      block_found = block;	      if (symtab != NULL)		*symtab = s;	      return sym;	    }	}      ALL_PSYMTABS (objfile, ps)	{	  if (!ps->readin && lookup_demangled_partial_symbol (ps, name))	    {	      s = PSYMTAB_TO_SYMTAB(ps);	      bv = BLOCKVECTOR (s);	      block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	      sym = lookup_demangled_block_symbol (block, name);	      if (!sym)		error ("Internal: mangled static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);	      if (symtab != NULL)		*symtab = s;	      return sym;	    }	}    }  if (symtab != NULL)    *symtab = NULL;  return 0;}/* Look for a static demangled symbol in block BLOCK.  */static struct symbol *lookup_demangled_block_symbol (block, name)     register const struct block *block;     const char *name;{  register int bot, top;  register struct symbol *sym;  char *demangled;  bot = 0;  top = BLOCK_NSYMS (block);  while (bot < top)    {      sym = BLOCK_SYM (block, bot);      if (SYMBOL_NAMESPACE (sym) == VAR_NAMESPACE)	{	  demangled = demangle_and_match (SYMBOL_NAME (sym), name,					  DMGL_PARAMS | DMGL_ANSI);	  if (demangled != NULL)	    {	      free (demangled);	      return (sym);	    }	}      bot++;    }  return (NULL);}/* Look, in partial_symtab PST, for static mangled symbol NAME. */static struct partial_symbol *lookup_demangled_partial_symbol (pst, name)     const struct partial_symtab *pst;     const char *name;{  struct partial_symbol *start, *psym;  int length = pst->n_static_syms;  char *demangled;  if (!length)    return (struct partial_symbol *) 0;    start = pst->objfile->static_psymbols.list + pst->statics_offset;  for (psym = start; psym < start + length; psym++)    {      if (SYMBOL_NAMESPACE (psym) == VAR_NAMESPACE)	{	  demangled = demangle_and_match (SYMBOL_NAME (psym), name,					  DMGL_PARAMS | DMGL_ANSI);	  if (demangled != NULL)	    {	      free (demangled);	      return (psym);	    }	}    }  return (NULL);}/* Look, in partial_symtab PST, for symbol NAME.  Check the global   symbols if GLOBAL, the static symbols if not */static struct partial_symbol *lookup_partial_symbol (pst, name, global, namespace)     struct partial_symtab *pst;     const char *name;     int global;     enum namespace namespace;{  struct partial_symbol *start, *psym;  int length = (global ? pst->n_global_syms : pst->n_static_syms);  if (!length)    return (struct partial_symbol *) 0;    start = (global ?	   pst->objfile->global_psymbols.list + pst->globals_offset :	   pst->objfile->static_psymbols.list + pst->statics_offset  );  if (global)			/* This means we can use a binary */				/* search.  */    {      struct partial_symbol *top, *bottom, *center;      /* Binary search.  This search is guaranteed to end with center         pointing at the earliest partial symbol with the correct	 name.  At that point *all* partial symbols with that name	 will be checked against the correct namespace. */      bottom = start;      top = start + length - 1;      while (top > bottom)	{	  center = bottom + (top - bottom) / 2;	  assert (center < top);	  	  if (strcmp (SYMBOL_NAME (center), name) >= 0)	    top = center;	  else	    bottom = center + 1;	}      assert (top == bottom);            while (!strcmp (SYMBOL_NAME (top), name))	{	  if (SYMBOL_NAMESPACE (top) == namespace)	    return top;	  top ++;	}    }  else    {      /* Can't use a binary search */      for (psym = start; psym < start + length; psym++)	if (namespace == SYMBOL_NAMESPACE (psym)	    && !strcmp (name, SYMBOL_NAME (psym)))	  return psym;    }  return (struct partial_symbol *) 0;}/* Find the psymtab containing main(). *//* FIXME:  What about languages without main() or specially linked   executables that have no main() ? */struct partial_symtab *find_main_psymtab (){  register struct partial_symtab *pst;  register struct objfile *objfile;  ALL_PSYMTABS (objfile, pst)    {      if (lookup_partial_symbol (pst, "main", 1, VAR_NAMESPACE))	{	  return (pst);	}    }  return (NULL);}/* Look for a symbol in block BLOCK.  */struct symbol *lookup_block_symbol (block, name, namespace)     register const struct block *block;     const char *name;     const enum namespace namespace;{  register int bot, top, inc;  register struct symbol *sym, *parameter_sym;  top = BLOCK_NSYMS (block);  bot = 0;  /* If the blocks's symbols were sorted, start with a binary search.  */  if (BLOCK_SHOULD_SORT (block))    {      /* First, advance BOT to not far before	 the first symbol whose name is NAME.  */      while (1)	{	  inc = (top - bot + 1);	  /* No need to keep binary searching for the last few bits worth.  */	  if (inc < 4)	    break;	  inc = (inc >> 1) + bot;	  sym = BLOCK_SYM (block, inc);	  if (SYMBOL_NAME (sym)[0] < name[0])	    bot = inc;	  else if (SYMBOL_NAME (sym)[0] > name[0])	    top = inc;	  else if (strcmp (SYMBOL_NAME (sym), name) < 0)	    bot = inc;	  else	    top = inc;	}      /* Now scan forward until we run out of symbols,	 find one whose name is greater than NAME,	 or find one we want.	 If there is more than one symbol with the right name and namespace,	 we return the first one.  dbxread.c is careful to make sure	 that if one is a register then it comes first.  */      top = BLOCK_NSYMS (block);      while (bot < top)	{	  sym = BLOCK_SYM (block, bot);	  inc = SYMBOL_NAME (sym)[0] - name[0];	  if (inc == 0)	    inc = strcmp (SYMBOL_NAME (sym), name);	  if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)	    return sym;	  if (inc > 0)	    return 0;	  bot++;	}      return 0;    }  /* Here if block isn't sorted.     This loop is equivalent to the loop above,     but hacked greatly for speed.     Note that parameter symbols do not always show up last in the     list; this loop makes sure to take anything else other than     parameter symbols first; it only uses parameter symbols as a     last resort.  Note that this only takes up extra computation     time on a match.  */  parameter_sym = (struct symbol *) 0;  top = BLOCK_NSYMS (block);  inc = name[0];  while (bot < top)    {      sym = BLOCK_SYM (block, bot);      if (SYMBOL_NAME (sym)[0] == inc	  && !strcmp (SYMBOL_NAME (sym), name)	  && SYMBOL_NAMESPACE (sym) == namespace)	{	  if (SYMBOL_CLASS (sym) == LOC_ARG	      || SYMBOL_CLASS (sym) == LOC_LOCAL_ARG	      || SYMBOL_CLASS (sym) == LOC_REF_ARG	      || SYMBOL_CLASS (sym) == LOC_REGPARM)	    parameter_sym = sym;	  else	    return sym;	}      bot++;    }  return parameter_sym;		/* Will be 0 if not found. */}/* Return the symbol for the function which contains a specified   lexical block, described by a struct block BL.  */struct symbol *block_function (bl)     struct block *bl;{  while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)    bl = BLOCK_SUPERBLOCK (bl);  return BLOCK_FUNCTION (bl);}/* Subroutine of find_pc_line */struct symtab *find_pc_symtab (pc)     register CORE_ADDR pc;{  register struct block *b;  struct blockvector *bv;  register struct symtab *s = 0;  register struct partial_symtab *ps;  register struct objfile *objfile;

⌨️ 快捷键说明

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