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

📄 symtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
   *EXPR -- line in which address EXPR appears.   FUNCTION may be an undebuggable function found in minimal symbol table.   If the argument FUNFIRSTLINE is nonzero, we want the first line   of real code inside a function when a function is specified.   DEFAULT_SYMTAB specifies the file to use if none is specified.   It defaults to current_source_symtab.   DEFAULT_LINE specifies the line number to use for relative   line numbers (that start with signs).  Defaults to current_source_line.   Note that it is possible to return zero for the symtab   if no file is validly specified.  Callers must check that.   Also, the line number returned may be invalid.  */struct symtabs_and_linesdecode_line_1 (argptr, funfirstline, default_symtab, default_line)     char **argptr;     int funfirstline;     struct symtab *default_symtab;     int default_line;{  struct symtabs_and_lines values;#ifdef HPPA_COMPILER_BUG  /* FIXME: The native HP 9000/700 compiler has a bug which appears     when optimizing this file with target i960-vxworks.  I haven't     been able to construct a simple test case.  The problem is that     in the second call to SKIP_PROLOGUE below, the compiler somehow     does not realize that the statement val = find_pc_line (...) will     change the values of the fields of val.  It extracts the elements     into registers at the top of the block, and does not update the     registers after the call to find_pc_line.  You can check this by     inserting a printf at the end of find_pc_line to show what values     it is returning for val.pc and val.end and another printf after     the call to see what values the function actually got (remember,     this is compiling with cc -O, with this patch removed).  You can     also examine the assembly listing: search for the second call to     skip_prologue; the LDO statement before the next call to     find_pc_line loads the address of the structure which     find_pc_line will return; if there is a LDW just before the LDO,     which fetches an element of the structure, then the compiler     still has the bug.     Setting val to volatile avoids the problem.  We must undef     volatile, because the HPPA native compiler does not define     __STDC__, although it does understand volatile, and so volatile     will have been defined away in defs.h.  */#undef volatile  volatile struct symtab_and_line val;#define volatile /*nothing*/#else  struct symtab_and_line val;#endif  register char *p, *p1;  char *q, *q1;  register struct symtab *s;  register struct symbol *sym;  /* The symtab that SYM was found in.  */  struct symtab *sym_symtab;  register CORE_ADDR pc;  register struct minimal_symbol *msymbol;  char *copy;  struct symbol *sym_class;  int i1;  int is_quoted;  struct symbol **sym_arr;  struct type *t;  char **physnames;  char *saved_arg = *argptr;  extern char *gdb_completer_quote_characters;    /* Defaults have defaults.  */  if (default_symtab == 0)    {      default_symtab = current_source_symtab;      default_line = current_source_line;    }  /* See if arg is *PC */  if (**argptr == '*')    {      if (**argptr == '*')	{	  (*argptr)++;	}      pc = parse_and_eval_address_1 (argptr);      values.sals = (struct symtab_and_line *)	xmalloc (sizeof (struct symtab_and_line));      values.nelts = 1;      values.sals[0] = find_pc_line (pc, 0);      values.sals[0].pc = pc;      return values;    }  /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */  s = NULL;  is_quoted = (strchr (gdb_completer_quote_characters, **argptr) != NULL);  for (p = *argptr; *p; p++)    {      if (p[0] == ':' || p[0] == ' ' || p[0] == '\t')	break;    }  while (p[0] == ' ' || p[0] == '\t') p++;  if ((p[0] == ':') && !is_quoted)    {      /*  C++  */      if (p[1] ==':')	{	  /* Extract the class name.  */	  p1 = p;	  while (p != *argptr && p[-1] == ' ') --p;	  copy = (char *) alloca (p - *argptr + 1);	  memcpy (copy, *argptr, p - *argptr);	  copy[p - *argptr] = 0;	  /* Discard the class name from the arg.  */	  p = p1 + 2;	  while (*p == ' ' || *p == '\t') p++;	  *argptr = p;	  sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0, 				     (struct symtab **)NULL);       	  if (sym_class &&	      (   TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT	       || TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))	    {	      /* Arg token is not digits => try it as a function name		 Find the next token (everything up to end or next whitespace). */	      p = *argptr;	      while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;	      q = operator_chars (*argptr, &q1);	      if (q1 - q)		{		  char *opname;		  char *tmp = alloca (q1 - q + 1);		  memcpy (tmp, q, q1 - q);		  tmp[q1 - q] = '\0';		  opname = cplus_mangle_opname (tmp, DMGL_ANSI);		  if (opname == NULL)		    {		      warning ("no mangling for \"%s\"", tmp);		      cplusplus_hint (saved_arg);		      return_to_top_level ();		    }		  copy = (char*) alloca (3 + strlen(opname));		  sprintf (copy, "__%s", opname);		  p = q1;		}	      else		{		  copy = (char *) alloca (p - *argptr + 1 + (q1 - q));		  memcpy (copy, *argptr, p - *argptr);		  copy[p - *argptr] = '\0';		}	      /* no line number may be specified */	      while (*p == ' ' || *p == '\t') p++;	      *argptr = p;	      sym = 0;	      i1 = 0;		/*  counter for the symbol array */	      t = SYMBOL_TYPE (sym_class);	      sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*));	      physnames = (char **) alloca (TYPE_NFN_FIELDS_TOTAL (t) * sizeof(char*));	      if (destructor_name_p (copy, t))		{		  /* destructors are a special case.  */		  struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0);		  int len = TYPE_FN_FIELDLIST_LENGTH (t, 0) - 1;		  char *phys_name = TYPE_FN_FIELD_PHYSNAME (f, len);		  physnames[i1] = (char *)alloca (strlen (phys_name) + 1);		  strcpy (physnames[i1], phys_name);		  sym_arr[i1] =		    lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class),				   VAR_NAMESPACE, 0, (struct symtab **)NULL);		  if (sym_arr[i1]) i1++;		}	      else		i1 = find_methods (t, copy, physnames, sym_arr);	      if (i1 == 1)		{		  /* There is exactly one field with that name.  */		  sym = sym_arr[0];		  if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)		    {		      /* Arg is the name of a function */		      pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET;		      if (funfirstline)			SKIP_PROLOGUE (pc);		      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));		      values.nelts = 1;		      values.sals[0] = find_pc_line (pc, 0);		      values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc;		    }		  else		    {		      values.nelts = 0;		    }		  return values;		}	      if (i1 > 0)		{		  /* There is more than one field with that name		     (overloaded).  Ask the user which one to use.  */		  return decode_line_2 (sym_arr, i1, funfirstline);		}	      else		{		  char *tmp;		  if (OPNAME_PREFIX_P (copy))		    {		      tmp = (char *)alloca (strlen (copy+3) + 9);		      strcpy (tmp, "operator ");		      strcat (tmp, copy+3);		    }		  else		    tmp = copy;		  if (tmp[0] == '~')		    warning ("the class `%s' does not have destructor defined",			     sym_class->name);		  else		    warning ("the class %s does not have any method named %s",			     sym_class->name, tmp);		  cplusplus_hint (saved_arg);		  return_to_top_level ();		}	    }	  else	    {	      /* The quotes are important if copy is empty.  */	      warning ("can't find class, struct, or union named \"%s\"",		       copy);	      cplusplus_hint (saved_arg);	      return_to_top_level ();	    }	}      /*  end of C++  */      /* Extract the file name.  */      p1 = p;      while (p != *argptr && p[-1] == ' ') --p;      copy = (char *) alloca (p - *argptr + 1);      memcpy (copy, *argptr, p - *argptr);      copy[p - *argptr] = 0;      /* Find that file's data.  */      s = lookup_symtab (copy);      if (s == 0)	{	  if (!have_full_symbols () && !have_partial_symbols ())	    error (no_symtab_msg);	  error ("No source file named %s.", copy);	}      /* Discard the file name from the arg.  */      p = p1 + 1;      while (*p == ' ' || *p == '\t') p++;      *argptr = p;    }  /* S is specified file's symtab, or 0 if no file specified.     arg no longer contains the file name.  */  /* Check whether arg is all digits (and sign) */  p = *argptr;  if (*p == '-' || *p == '+') p++;  while (*p >= '0' && *p <= '9')    p++;  if (p != *argptr && (*p == 0 || *p == ' ' || *p == '\t' || *p == ','))    {      /* We found a token consisting of all digits -- at least one digit.  */      enum sign {none, plus, minus} sign = none;      /* This is where we need to make sure that we have good defaults.	 We must guarantee that this section of code is never executed	 when we are called with just a function name, since	 select_source_symtab calls us with such an argument  */      if (s == 0 && default_symtab == 0)	{	  select_source_symtab (0);	  default_symtab = current_source_symtab;	  default_line = current_source_line;	}      if (**argptr == '+')	sign = plus, (*argptr)++;      else if (**argptr == '-')	sign = minus, (*argptr)++;      val.line = atoi (*argptr);      switch (sign)	{	case plus:	  if (p == *argptr)	    val.line = 5;	  if (s == 0)	    val.line = default_line + val.line;	  break;	case minus:	  if (p == *argptr)	    val.line = 15;	  if (s == 0)	    val.line = default_line - val.line;	  else	    val.line = 1;	  break;	case none:	  break;	/* No need to adjust val.line.  */	}      while (*p == ' ' || *p == '\t') p++;      *argptr = p;      if (s == 0)	s = default_symtab;      val.symtab = s;      val.pc = 0;      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));      values.sals[0] = val;      values.nelts = 1;      return values;    }  /* Arg token is not digits => try it as a variable name     Find the next token (everything up to end or next whitespace).  */  p = skip_quoted (*argptr);  copy = (char *) alloca (p - *argptr + 1);  memcpy (copy, *argptr, p - *argptr);  copy[p - *argptr] = '\0';  if ((copy[0] == copy [p - *argptr - 1])      && strchr (gdb_completer_quote_characters, copy[0]) != NULL)    {      char *temp;      copy [p - *argptr - 1] = '\0';      copy++;      if ((temp = expensive_mangler (copy)) != NULL)	{	  copy = temp;	}    }  while (*p == ' ' || *p == '\t') p++;  *argptr = p;  /* Look up that token as a variable.     If file specified, use that file's per-file block to start with.  */  sym = lookup_symbol (copy,		       (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)			: get_selected_block ()),		       VAR_NAMESPACE, 0, &sym_symtab);  if (sym != NULL)    {      if (SYMBOL_CLASS (sym) == LOC_BLOCK)	{	  /* Arg is the name of a function */	  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET;	  if (funfirstline)	    SKIP_PROLOGUE (pc);	  val = find_pc_line (pc, 0);#ifdef PROLOGUE_FIRSTLINE_OVERLAP	  /* Convex: no need to suppress code on first line, if any */	  val.pc = pc;#else	  /* If SKIP_PROLOGUE left us in mid-line, and the next line is still	     part of the same function:		advance to next line, 	        recalculate its line number (might not be N+1).  */	  if (val.pc != pc && val.end &&	      lookup_minimal_symbol_by_pc (pc) == lookup_minimal_symbol_by_pc (val.end)) {	    pc = val.end;	/* First pc of next line */	    val = find_pc_line (pc, 0);	  }	  val.pc = pc;#endif	  values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));	  values.sals[0] = val;	  values.nelts = 1;	  	  /* I think this is always the same as the line that	     we calculate above, but the general principle is	     "trust the symbols more than stuff like	     SKIP_PROLOGUE".  */	  if (SYMBOL_LINE (sym) != 0)	    values.sals[0].line = SYMBOL_LINE (sym);	  	  return values;	}      else if (SYMBOL_LINE (sym) != 0)	{	  /* We know its line number.  */	  values.sals = (struct symtab_and_line *)	    xmalloc (sizeof (struct symtab_and_line));	  values.nelts = 1;	  memset (&values.sals[0], 0, sizeof (values.sals[0]));	  values.sals[0].symtab = sym_symtab;	  values.sals[0].line = SYMBOL_LINE (sym);	  return values;	}      else	/* This can happen if it is compiled with a compiler which doesn't	   put out line numbers for variables.  */	error ("Line number not known for symbol \"%s\"", copy);    }  msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL);  if (msymbol != NULL)    {      val.symtab = 0;      val.line = 0;      val.pc = msymbol -> address + FUNCTION_START_OFFSET;      if (funfirstline)	SKIP_PROLOGUE (val.pc);      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));      values.sals[0] = val;      values.nelts = 1;      return values;    }  if (!have_full_symbols () &&      !have_partial_symbols () && !have_minimal_symbols ())    error (no_symtab_msg);  error ("Function \"%s\" not defined.", copy);  return values;	/* for lint */}struct symtabs_and_linesdecode_line_spec (string, funfirstline)     char *string;     int funfirstline;{  struct symtabs_and_lines sals;  if (string == 0)    error ("Empty line specification.");  sals = decode_line_1 (&string, funfirstline,			current_source_symtab, current_source_line);  if (*string)    error ("Junk at end of line specification: %s", string);  return sals;}/* Given a list of NELTS symbols in sym_arr (with corresponding   mangled names in physnames), return a list of lines to operate on   (ask user if necessary).  */static struct symtabs_and_linesdecode_line_2 (sym_arr, nelts, funfirstline)     struct symbol *sym_arr[];     int nelts;     int funfirstline;{  struct symtabs_and_lines values, return_values;  register CORE_ADDR pc;  char *args, *arg1;  int i;  char *prompt;  char *demangled;  values.sals = (struct symtab_and_line *) alloca (nelts * sizeof(struct symtab_and_line));  return_values.sals = (struct symtab_and_line *) xmalloc (nelts * sizeof(struct symtab_and_line));  i = 0;  printf("[0] cancel\n[1] all\n");  while (i < nelts)    {      if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)	{	  /* Arg is the name of a function */	  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i])) 	       + FUNCTION_START_OFFSET;	  if (funfirstline)

⌨️ 快捷键说明

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