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

📄 stabs.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 5 页
字号:
				     parse_stab_type (dhandle, info,
						      (const char *) NULL,
						      pp,
						      (debug_type **) NULL));
      break;

    case 'B':
      /* Volatile qual on some type (Sun).  */
      /* FIXME: gdb accepts 'i' here if os9k_stabs.  */
      dtype = (debug_make_volatile_type
	       (dhandle,
		parse_stab_type (dhandle, info, (const char *) NULL, pp,
				 (debug_type **) NULL)));
      break;

    case '@':
      /* Offset (class & variable) type.  This is used for a pointer
         relative to an object.  */
      {
	debug_type domain;
	debug_type memtype;

	/* Member type.  */

	domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
				  (debug_type **) NULL);
	if (domain == DEBUG_TYPE_NULL)
	  return DEBUG_TYPE_NULL;

	if (**pp != ',')
	  {
	    bad_stab (orig);
	    return DEBUG_TYPE_NULL;
	  }
	++*pp;

	memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
				   (debug_type **) NULL);
	if (memtype == DEBUG_TYPE_NULL)
	  return DEBUG_TYPE_NULL;

	dtype = debug_make_offset_type (dhandle, domain, memtype);
      }
      break;

    case '#':
      /* Method (class & fn) type.  */
      if (**pp == '#')
	{
	  debug_type return_type;

	  ++*pp;
	  return_type = parse_stab_type (dhandle, info, (const char *) NULL,
					 pp, (debug_type **) NULL);
	  if (return_type == DEBUG_TYPE_NULL)
	    return DEBUG_TYPE_NULL;
	  if (**pp != ';')
	    {
	      bad_stab (orig);
	      return DEBUG_TYPE_NULL;
	    }
	  ++*pp;
	  dtype = debug_make_method_type (dhandle, return_type,
					  DEBUG_TYPE_NULL,
					  (debug_type *) NULL, false);
	}
      else
	{
	  debug_type domain;
	  debug_type return_type;
	  debug_type *args;
	  unsigned int n;
	  unsigned int alloc;
	  bfd_boolean varargs;

	  domain = parse_stab_type (dhandle, info, (const char *) NULL,
				    pp, (debug_type **) NULL);
	  if (domain == DEBUG_TYPE_NULL)
	    return DEBUG_TYPE_NULL;

	  if (**pp != ',')
	    {
	      bad_stab (orig);
	      return DEBUG_TYPE_NULL;
	    }
	  ++*pp;

	  return_type = parse_stab_type (dhandle, info, (const char *) NULL,
					 pp, (debug_type **) NULL);
	  if (return_type == DEBUG_TYPE_NULL)
	    return DEBUG_TYPE_NULL;

	  alloc = 10;
	  args = (debug_type *) xmalloc (alloc * sizeof *args);
	  n = 0;
	  while (**pp != ';')
	    {
	      if (**pp != ',')
		{
		  bad_stab (orig);
		  return DEBUG_TYPE_NULL;
		}
	      ++*pp;

	      if (n + 1 >= alloc)
		{
		  alloc += 10;
		  args = ((debug_type *)
			  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 bfd_boolean
parse_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, (bfd_boolean *) NULL);
    }
  else
    {
      ++*pp;
      typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ',')
	{
	  bad_stab (orig);
	  return false;
	}
      ++*pp;
      typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ')')
	{
	  bad_stab (orig);
	  return false;
	}
      ++*pp;
    }

  return true;
}

/* Parse a range type.  */

static debug_type
parse_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];
  bfd_boolean self_subrange;
  debug_type index_type;
  const char *s2, *s3;
  bfd_signed_vma n2, n3;
  bfd_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_type
parse_stab_sun_builtin_type (dhandle, pp)
     PTR dhandle;
     const char **pp;
{
  const char *orig;
  bfd_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, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

⌨️ 快捷键说明

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