stabs.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,559 行 · 第 1/5 页

C
2,559
字号
			  xrealloc ((PTR) args, alloc * sizeof *args));		}	      args[n] = parse_stab_type (dhandle, info, (const char *) NULL,					 pp, (debug_type **) NULL);	      if (args[n] == DEBUG_TYPE_NULL)		return DEBUG_TYPE_NULL;	      ++n;	    }	  ++*pp;	  /* If the last type is not void, then this function takes a	     variable number of arguments.  Otherwise, we must strip	     the void type.  */	  if (n == 0	      || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)	    varargs = true;	  else	    {	      --n;	      varargs = false;	    }	  args[n] = DEBUG_TYPE_NULL;	  dtype = debug_make_method_type (dhandle, return_type, domain, args,					  varargs);	}      break;    case 'r':      /* Range type.  */      dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);      break;    case 'b':      /* FIXME: gdb checks os9k_stabs here.  */      /* Sun ACC builtin int type.  */      dtype = parse_stab_sun_builtin_type (dhandle, pp);      break;    case 'R':      /* Sun ACC builtin float type.  */      dtype = parse_stab_sun_floating_type (dhandle, pp);      break;    case 'e':      /* Enumeration type.  */      dtype = parse_stab_enum_type (dhandle, pp);      break;    case 's':    case 'u':      /* Struct or union type.  */      dtype = parse_stab_struct_type (dhandle, info, typename, pp,				      descriptor == 's', typenums);      break;    case 'a':      /* Array type.  */      if (**pp != 'r')	{	  bad_stab (orig);	  return DEBUG_TYPE_NULL;	}      ++*pp;      dtype = parse_stab_array_type (dhandle, info, pp, stringp);      break;    case 'S':      dtype = debug_make_set_type (dhandle,				   parse_stab_type (dhandle, info,						    (const char *) NULL,						    pp,						    (debug_type **) NULL),				   stringp);      break;    default:      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  if (dtype == DEBUG_TYPE_NULL)    return DEBUG_TYPE_NULL;  if (typenums[0] != -1)    {      if (! stab_record_type (dhandle, info, typenums, dtype))	return DEBUG_TYPE_NULL;    }  if (size != -1)    {      if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))	return DEBUG_TYPE_NULL;    }  return dtype;}/* 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.  */static booleanparse_stab_type_number (pp, typenums)     const char **pp;     int *typenums;{  const char *orig;  orig = *pp;  if (**pp != '(')    {      typenums[0] = 0;      typenums[1] = (int) parse_number (pp, (boolean *) NULL);    }  else    {      ++*pp;      typenums[0] = (int) parse_number (pp, (boolean *) NULL);      if (**pp != ',')	{	  bad_stab (orig);	  return false;	}      ++*pp;      typenums[1] = (int) parse_number (pp, (boolean *) NULL);      if (**pp != ')')	{	  bad_stab (orig);	  return false;	}      ++*pp;    }  return true;}/* Parse a range type.  */static debug_typeparse_stab_range_type (dhandle, info, typename, pp, typenums)     PTR dhandle;     struct stab_handle *info;     const char *typename;     const char **pp;     const int *typenums;{  const char *orig;  int rangenums[2];  boolean self_subrange;  debug_type index_type;  const char *s2, *s3;  bfd_signed_vma n2, n3;  boolean ov2, ov3;  orig = *pp;  index_type = DEBUG_TYPE_NULL;  /* First comes a type we are a subrange of.     In C it is usually 0, 1 or the type being defined.  */  if (! parse_stab_type_number (pp, rangenums))    return DEBUG_TYPE_NULL;  self_subrange = (rangenums[0] == typenums[0]		   && rangenums[1] == typenums[1]);  if (**pp == '=')    {      *pp = orig;      index_type = parse_stab_type (dhandle, info, (const char *) NULL,				    pp, (debug_type **) NULL);      if (index_type == DEBUG_TYPE_NULL)	return DEBUG_TYPE_NULL;    }  if (**pp == ';')    ++*pp;  /* The remaining two operands are usually lower and upper bounds of     the range.  But in some special cases they mean something else.  */  s2 = *pp;  n2 = parse_number (pp, &ov2);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  ++*pp;  s3 = *pp;  n3 = parse_number (pp, &ov3);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  ++*pp;  if (ov2 || ov3)    {      /* gcc will emit range stabs for long long types.  Handle this         as a special case.  FIXME: This needs to be more general.  */#define LLLOW  "01000000000000000000000;"#define LLHIGH "0777777777777777777777;"#define ULLHIGH "01777777777777777777777;"      if (index_type == DEBUG_TYPE_NULL)	{	  if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0	      && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)	    return debug_make_int_type (dhandle, 8, false);	  if (! ov2	      && n2 == 0	      && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)	    return debug_make_int_type (dhandle, 8, true);	}      warn_stab (orig, _("numeric overflow"));    }  if (index_type == DEBUG_TYPE_NULL)    {      /* A type defined as a subrange of itself, with both bounds 0,         is void.  */      if (self_subrange && n2 == 0 && n3 == 0)	return debug_make_void_type (dhandle);      /* A type defined as a subrange of itself, with n2 positive and	 n3 zero, is a complex type, and n2 is the number of bytes.  */      if (self_subrange && n3 == 0 && n2 > 0)	return debug_make_complex_type (dhandle, n2);      /* If n3 is zero and n2 is positive, this is a floating point         type, and n2 is the number of bytes.  */      if (n3 == 0 && n2 > 0)	return debug_make_float_type (dhandle, n2);      /* If the upper bound is -1, this is an unsigned int.  */      if (n2 == 0 && n3 == -1)	{	  /* When gcc is used with -gstabs, but not -gstabs+, it will emit	         long long int:t6=r1;0;-1;		 long long unsigned int:t7=r1;0;-1;	     We hack here to handle this reasonably.  */	  if (typename != NULL)	    {	      if (strcmp (typename, "long long int") == 0)		return debug_make_int_type (dhandle, 8, false);	      else if (strcmp (typename, "long long unsigned int") == 0)		return debug_make_int_type (dhandle, 8, true);	    }	  /* FIXME: The size here really depends upon the target.  */	  return debug_make_int_type (dhandle, 4, true);	}      /* A range of 0 to 127 is char.  */      if (self_subrange && n2 == 0 && n3 == 127)	return debug_make_int_type (dhandle, 1, false);      /* FIXME: gdb checks for the language CHILL here.  */      if (n2 == 0)	{	  if (n3 < 0)	    return debug_make_int_type (dhandle, - n3, true);	  else if (n3 == 0xff)	    return debug_make_int_type (dhandle, 1, true);	  else if (n3 == 0xffff)	    return debug_make_int_type (dhandle, 2, true);	  else if (n3 == (bfd_signed_vma) 0xffffffff)	    return debug_make_int_type (dhandle, 4, true);#ifdef BFD64	  else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff))	    return debug_make_int_type (dhandle, 8, true);#endif	}      else if (n3 == 0	       && n2 < 0	       && (self_subrange || n2 == -8))	return debug_make_int_type (dhandle, - n2, true);      else if (n2 == - n3 - 1 || n2 == n3 + 1)	{	  if (n3 == 0x7f)	    return debug_make_int_type (dhandle, 1, false);	  else if (n3 == 0x7fff)	    return debug_make_int_type (dhandle, 2, false);	  else if (n3 == 0x7fffffff)	    return debug_make_int_type (dhandle, 4, false);#ifdef BFD64	  else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))	    return debug_make_int_type (dhandle, 8, false);#endif	}    }  /* At this point I don't have the faintest idea how to deal with a     self_subrange type; I'm going to assume that this is used as an     idiom, and that all of them are special cases.  So . . .  */  if (self_subrange)    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  index_type = stab_find_type (dhandle, info, rangenums);  if (index_type == DEBUG_TYPE_NULL)    {      /* Does this actually ever happen?  Is that why we are worrying         about dealing with it rather than just calling error_type?  */      warn_stab (orig, _("missing index type"));      index_type = debug_make_int_type (dhandle, 4, false);    }  return debug_make_range_type (dhandle, index_type, n2, n3);}/* Sun's ACC uses a somewhat saner method for specifying the builtin   typedefs in every file (for int, long, etc):	type = b <signed> <width>; <offset>; <nbits>	signed = u or s.  Possible c in addition to u or s (for char?).	offset = offset from high order bit to start bit of type.	width is # bytes in object of this type, nbits is # bits in type.   The width/offset stuff appears to be for small objects stored in   larger ones (e.g. `shorts' in `int' registers).  We ignore it for now,   FIXME.  */static debug_typeparse_stab_sun_builtin_type (dhandle, pp)     PTR dhandle;     const char **pp;{  const char *orig;  boolean unsignedp;  bfd_vma bits;  orig = *pp;  switch (**pp)    {    case 's':      unsignedp = false;      break;    case 'u':      unsignedp = true;      break;    default:      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  ++*pp;  /* For some odd reason, all forms of char put a c here.  This is strange     because no other type has this honor.  We can safely ignore this because     we actually determine 'char'acterness by the number of bits specified in     the descriptor.  */  if (**pp == 'c')    ++*pp;  /* The first number appears to be the number of bytes occupied     by this type, except that unsigned short is 4 instead of 2.     Since this information is redundant with the third number,     we will ignore it.  */  (void) parse_number (pp, (boolean *) NULL);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  ++*pp;  /* The second number is always 0, so ignore it too. */  (void) parse_number (pp, (boolean *) NULL);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  ++*pp;  /* The third number is the number of bits for this type. */  bits = parse_number (pp, (boolean *) NULL);  /* The type *should* end with a semicolon.  If it are embedded     in a larger type the semicolon may be the only way to know where     the type ends.  If this type is at the end of the stabstring we     can deal with the omitted semicolon (but we don't have to like     it).  Don't bother to complain(), Sun's compiler omits the semicolon     for "void".  */  if (**pp == ';')    ++*pp;  if (bits == 0)    return debug_make_void_type (dhandle);  return debug_make_int_type (dhandle, bits / 8, unsignedp);}/* Parse a builtin floating type generated by the Sun compiler.  */static debug_typeparse_stab_sun_floating_type (dhandle, pp)     PTR dhandle;     const char **pp;{  const char *orig;  bfd_vma details;  bfd_vma bytes;  orig = *pp;  /* The first number has more details about the type, for example     FN_COMPLEX.  */  details = parse_number (pp, (boolean *) NULL);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  /* The second number is the number of bytes occupied by this type */  bytes = parse_number (pp, (boolean *) NULL);  if (**pp != ';')    {      bad_stab (orig);      return DEBUG_TYPE_NULL;    }  if (details == NF_COMPLEX      || details == NF_COMPLEX16      || details == NF_COMPLEX32)    return debug_make_complex_type (dhandle, bytes);  return debug_make_float_type (dhandle, bytes);      }/* Handle an enum type.  */static debug_typeparse_stab_enum_type (dhandle, pp)     PTR dhandle;     const char **pp;{  const char *orig;  const char **names;  bfd_signed_vma *values;  unsigned int n;  unsigned int alloc;  orig = *pp;  /* FIXME: gdb checks os9k_stabs here.  */  /* The aix4 compiler emits an extra field before the enum members;     my guess is it's a type of some sort.  Just ignore it.  */  if (**pp == '-')    {      while (**pp != ':')	++*pp;      ++*pp;    }  /* Read the value-names and their values.     The input syntax is NAME:VALUE,NAME:VALUE, and so on.     A semicolon or comma instead of a NAME means the end.  */  alloc = 10;  names = (const char **) xmalloc (alloc * sizeof *names);  values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);  n = 0;  while (**pp != '\0' && **pp != ';' && **pp != ',')    {      const char *p;      char *name;      bfd_signed_vma val;      p = *pp;      while (*p != ':')	++p;      name = savestring (*pp, p - *pp);      *pp = p + 1;      val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);      if (**pp != ',')	{	  bad_stab (orig);	  return DEBUG_TYPE_NULL;	}      ++*pp;      if (n + 1 >= alloc)	{	  alloc += 10;	  names = ((const char **)		   xrealloc ((PTR) names, alloc * sizeof *names));	  values = ((bfd_signed_vma *)		    xrealloc ((PTR) values, alloc * sizeof *values));	}      names[n] = name;      values[n] = val;      ++n;    }  names[n] = NULL;

⌨️ 快捷键说明

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