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

📄 stabs.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 5 页
字号:
						(debug_type *) NULL, false);
	      dtype = debug_make_pointer_type (dhandle, ftype);
	    }
	}
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
				    value))
	return false;

      /* FIXME: At this point gdb considers rearranging the parameter
	 address on a big endian machine if it is smaller than an int.
	 We have no way to do that, since we don't really know much
	 about the target.  */

      break;

    case 'P':
      if (stabtype == N_FUN)
	{
	  /* Prototype of a function referenced by this file.  */
	  while (*p == ';')
	    {
	      ++p;
	      if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
				   (debug_type **) NULL)
		  == DEBUG_TYPE_NULL)
		return false;
	    }
	  break;
	}
      /* Fall through.  */
    case 'R':
      /* Parameter which is in a register.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
				    value))
	return false;
      break;

    case 'r':
      /* Register variable (either global or local).  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
				  value))
	return false;

      /* FIXME: At this point gdb checks to combine pairs of 'p' and
	 'r' stabs into a single 'P' stab.  */

      break;

    case 'S':
      /* Static symbol at top level of file */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
				  value))
	return false;
      break;

    case 't':
      /* A typedef.  */
      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (name == NULL)
	{
	  /* A nameless type.  Nothing to do.  */
	  return true;
	}

      dtype = debug_name_type (dhandle, name, dtype);
      if (dtype == DEBUG_TYPE_NULL)
	return false;

      if (slot != NULL)
	*slot = dtype;

      break;

    case 'T':
      /* Struct, union, or enum tag.  For GNU C++, this can be be followed
	 by 't' which means we are typedef'ing it as well.  */
      if (*p != 't')
	{
	  synonym = false;
	  /* FIXME: gdb sets synonym to true if the current language
             is C++.  */
	}
      else
	{
	  synonym = true;
	  ++p;
	}

      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (name == NULL)
	return true;

      /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is
         a cross reference to itself.  These are generated by some
         versions of g++.  */
      self_crossref = info->self_crossref;

      dtype = debug_tag_type (dhandle, name, dtype);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (slot != NULL)
	*slot = dtype;

      /* See if we have a cross reference to this tag which we can now
         fill in.  Avoid filling in a cross reference to ourselves,
         because that would lead to circular debugging information.  */
      if (! self_crossref)
	{
	  register struct stab_tag **pst;

	  for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
	    {
	      if ((*pst)->name[0] == name[0]
		  && strcmp ((*pst)->name, name) == 0)
		{
		  (*pst)->slot = dtype;
		  *pst = (*pst)->next;
		  break;
		}
	    }
	}

      if (synonym)
	{
	  dtype = debug_name_type (dhandle, name, dtype);
	  if (dtype == DEBUG_TYPE_NULL)
	    return false;

	  if (slot != NULL)
	    *slot = dtype;
	}

      break;

    case 'V':
      /* Static symbol of local scope */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      /* FIXME: gdb checks os9k_stabs here.  */
      if (! stab_record_variable (dhandle, info, name, dtype,
				  DEBUG_LOCAL_STATIC, value))
	return false;
      break;

    case 'v':
      /* Reference parameter.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
				    value))
	return false;
      break;

    case 'a':
      /* Reference parameter which is in a register.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
				    value))
	return false;
      break;

    case 'X':
      /* This is used by Sun FORTRAN for "function result value".
	 Sun claims ("dbx and dbxtool interfaces", 2nd ed)
	 that Pascal uses it too, but when I tried it Pascal used
	 "x:3" (local symbol) instead.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
			       (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
	return false;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
				  value))
	return false;
      break;

    default:
      bad_stab (string);
      return false;
    }

  /* FIXME: gdb converts structure values to structure pointers in a
     couple of cases, depending upon the target.  */

  return true;
}

/* Parse a stabs type.  The typename argument is non-NULL if this is a
   typedef or a tag definition.  The pp argument points to the stab
   string, and is updated.  The slotp argument points to a place to
   store the slot used if the type is being defined.  */

static debug_type
parse_stab_type (dhandle, info, typename, pp, slotp)
     PTR dhandle;
     struct stab_handle *info;
     const char *typename;
     const char **pp;
     debug_type **slotp;
{
  const char *orig;
  int typenums[2];
  int size;
  bfd_boolean stringp;
  int descriptor;
  debug_type dtype;

  if (slotp != NULL)
    *slotp = NULL;

  orig = *pp;

  size = -1;
  stringp = false;

  info->self_crossref = false;

  /* Read type number if present.  The type number may be omitted.
     for instance in a two-dimensional array declared with type
     "ar1;1;10;ar1;1;10;4".  */
  if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
    {
      /* 'typenums=' not present, type is anonymous.  Read and return
	 the definition, but don't put it in the type vector.  */
      typenums[0] = typenums[1] = -1;
    }
  else
    {
      if (! parse_stab_type_number (pp, typenums))
	return DEBUG_TYPE_NULL;

      if (**pp != '=')
	{
	  /* Type is not being defined here.  Either it already
	     exists, or this is a forward reference to it.  */
	  return stab_find_type (dhandle, info, typenums);
	}

      /* Only set the slot if the type is being defined.  This means
         that the mapping from type numbers to types will only record
         the name of the typedef which defines a type.  If we don't do
         this, then something like
	     typedef int foo;
	     int i;
	 will record that i is of type foo.  Unfortunately, stabs
	 information is ambiguous about variable types.  For this code,
	     typedef int foo;
	     int i;
	     foo j;
	 the stabs information records both i and j as having the same
	 type.  This could be fixed by patching the compiler.  */
      if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
	*slotp = stab_find_slot (info, typenums);

      /* Type is being defined here.  */
      /* Skip the '='.  */
      ++*pp;

      while (**pp == '@')
	{
	  const char *p = *pp + 1;
	  const char *attr;

	  if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
	    {
	      /* Member type.  */
	      break;
	    }

	  /* Type attributes.  */
	  attr = p;

	  for (; *p != ';'; ++p)
	    {
	      if (*p == '\0')
		{
		  bad_stab (orig);
		  return DEBUG_TYPE_NULL;
		}
	    }
	  *pp = p + 1;

	  switch (*attr)
	    {
	    case 's':
	      size = atoi (attr + 1);
	      size /= 8;  /* Size is in bits.  We store it in bytes.  */
	      if (size <= 0)
		size = -1;
	      break;

	    case 'S':
	      stringp = true;
	      break;

	    default:
	      /* Ignore unrecognized type attributes, so future
		 compilers can invent new ones.  */
	      break;
	    }
	}
    }

  descriptor = **pp;
  ++*pp;

  switch (descriptor)
    {
    case 'x':
      {
	enum debug_type_kind code;
	const char *q1, *q2, *p;

	/* A cross reference to another type.  */

	switch (**pp)
	  {
	  case 's':
	    code = DEBUG_KIND_STRUCT;
	    break;
	  case 'u':
	    code = DEBUG_KIND_UNION;
	    break;
	  case 'e':
	    code = DEBUG_KIND_ENUM;
	    break;
	  default:
	    /* Complain and keep going, so compilers can invent new
	       cross-reference types.  */
	    warn_stab (orig, _("unrecognized cross reference type"));
	    code = DEBUG_KIND_STRUCT;
	    break;
	  }
	++*pp;

	q1 = strchr (*pp, '<');
	p = strchr (*pp, ':');
	if (p == NULL)
	  {
	    bad_stab (orig);
	    return DEBUG_TYPE_NULL;
	  }
	if (q1 != NULL && p > q1 && p[1] == ':')
	  {
	    int nest = 0;

	    for (q2 = q1; *q2 != '\0'; ++q2)
	      {
		if (*q2 == '<')
		  ++nest;
		else if (*q2 == '>')
		  --nest;
		else if (*q2 == ':' && nest == 0)
		  break;
	      }
	    p = q2;
	    if (*p != ':')
	      {
		bad_stab (orig);
		return DEBUG_TYPE_NULL;
	      }
	  }

	/* Some versions of g++ can emit stabs like
	       fleep:T20=xsfleep:
	   which define structures in terms of themselves.  We need to
	   tell the caller to avoid building a circular structure.  */
	if (typename != NULL
	    && strncmp (typename, *pp, p - *pp) == 0
	    && typename[p - *pp] == '\0')
	  info->self_crossref = true;

	dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);

	*pp = p + 1;
      }
      break;

    case '-':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '(':
      {
	const char *hold;
	int xtypenums[2];

	/* This type is defined as another type.  */

	(*pp)--;
	hold = *pp;

	/* Peek ahead at the number to detect void.  */
	if (! parse_stab_type_number (pp, xtypenums))
	  return DEBUG_TYPE_NULL;

	if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
	  {
	    /* This type is being defined as itself, which means that
               it is void.  */
	    dtype = debug_make_void_type (dhandle);
	  }
	else
	  {
	    *pp = hold;

	    /* Go back to the number and have parse_stab_type get it.
	       This means that we can deal with something like
	       t(1,2)=(3,4)=... which the Lucid compiler uses.  */
	    dtype = parse_stab_type (dhandle, info, (const char *) NULL,
				     pp, (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;
	  }

	break;
      }

    case '*':
      dtype = debug_make_pointer_type (dhandle,
				       parse_stab_type (dhandle, info,
							(const char *) NULL,
							pp,
							(debug_type **) NULL));
      break;

    case '&':
      /* Reference to another type.  */
      dtype = (debug_make_reference_type
	       (dhandle,
		parse_stab_type (dhandle, info, (const char *) NULL, pp,
				 (debug_type **) NULL)));
      break;

    case 'f':
      /* Function returning another type.  */
      /* FIXME: gdb checks os9k_stabs here.  */
      dtype = (debug_make_function_type
	       (dhandle,
		parse_stab_type (dhandle, info, (const char *) NULL, pp,
				 (debug_type **) NULL),
		(debug_type *) NULL, false));
      break;

    case 'k':
      /* Const qualifier on some type (Sun).  */
      /* FIXME: gdb accepts 'c' here if os9k_stabs.  */
      dtype = debug_make_const_type (dhandle,

⌨️ 快捷键说明

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