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

📄 prdbg.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 3 页
字号:

  if (argcount < 0)
    strcat (s, "/* unknown */");
  else
    {
      int i;

      for (i = 0; i < argcount; i++)
	{
	  if (i > 0)
	    strcat (s, ", ");
	  strcat (s, arg_types[i]);
	}
      if (varargs)
	{
	  if (i > 0)
	    strcat (s, ", ");
	  strcat (s, "...");
	}
      if (argcount > 0)
	free (arg_types);
    }

  strcat (s, ")");

  if (! substitute_type (info, s))
    return false;

  free (s);

  return true;
}

/* Turn the top type on the stack into a reference to that type.  */

static bfd_boolean
pr_reference_type (p)
     PTR p;
{
  struct pr_handle *info = (struct pr_handle *) p;

  assert (info->stack != NULL);

  return substitute_type (info, "&|");
}

/* Make a range type.  */

static bfd_boolean
pr_range_type (p, lower, upper)
     PTR p;
     bfd_signed_vma lower;
     bfd_signed_vma upper;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char abl[20], abu[20];

  assert (info->stack != NULL);

  if (! substitute_type (info, ""))
    return false;

  print_vma (lower, abl, false, false);
  print_vma (upper, abu, false, false);

  return (prepend_type (info, "range (")
	  && append_type (info, "):")
	  && append_type (info, abl)
	  && append_type (info, ":")
	  && append_type (info, abu));
}

/* Make an array type.  */

/*ARGSUSED*/
static bfd_boolean
pr_array_type (p, lower, upper, stringp)
     PTR p;
     bfd_signed_vma lower;
     bfd_signed_vma upper;
     bfd_boolean stringp;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *range_type;
  char abl[20], abu[20], ab[50];

  range_type = pop_type (info);
  if (range_type == NULL)
    return false;

  if (lower == 0)
    {
      if (upper == -1)
	sprintf (ab, "|[]");
      else
	{
	  print_vma (upper + 1, abu, false, false);
	  sprintf (ab, "|[%s]", abu);
	}
    }
  else
    {
      print_vma (lower, abl, false, false);
      print_vma (upper, abu, false, false);
      sprintf (ab, "|[%s:%s]", abl, abu);
    }

  if (! substitute_type (info, ab))
    return false;

  if (strcmp (range_type, "int") != 0)
    {
      if (! append_type (info, ":")
	  || ! append_type (info, range_type))
	return false;
    }

  if (stringp)
    {
      if (! append_type (info, " /* string */"))
	return false;
    }

  return true;
}

/* Make a set type.  */

/*ARGSUSED*/
static bfd_boolean
pr_set_type (p, bitstringp)
     PTR p;
     bfd_boolean bitstringp;
{
  struct pr_handle *info = (struct pr_handle *) p;

  if (! substitute_type (info, ""))
    return false;

  if (! prepend_type (info, "set { ")
      || ! append_type (info, " }"))
    return false;

  if (bitstringp)
    {
      if (! append_type (info, "/* bitstring */"))
	return false;
    }

  return true;
}

/* Make an offset type.  */

static bfd_boolean
pr_offset_type (p)
     PTR p;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;

  if (! substitute_type (info, ""))
    return false;

  t = pop_type (info);
  if (t == NULL)
    return false;

  return (substitute_type (info, "")
	  && prepend_type (info, " ")
	  && prepend_type (info, t)
	  && append_type (info, "::|"));
}

/* Make a method type.  */

static bfd_boolean
pr_method_type (p, domain, argcount, varargs)
     PTR p;
     bfd_boolean domain;
     int argcount;
     bfd_boolean varargs;
{
  struct pr_handle *info = (struct pr_handle *) p;
  unsigned int len;
  char *domain_type;
  char **arg_types;
  char *s;

  len = 10;

  if (! domain)
    domain_type = NULL;
  else
    {
      if (! substitute_type (info, ""))
	return false;
      domain_type = pop_type (info);
      if (domain_type == NULL)
	return false;
      if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
	  && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
	domain_type += sizeof "class " - 1;
      else if (strncmp (domain_type, "union class ",
			sizeof "union class ") == 0
	       && (strchr (domain_type + sizeof "union class " - 1, ' ')
		   == NULL))
	domain_type += sizeof "union class " - 1;
      len += strlen (domain_type);
    }

  if (argcount <= 0)
    {
      arg_types = NULL;
      len += 15;
    }
  else
    {
      int i;

      arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
      for (i = argcount - 1; i >= 0; i--)
	{
	  if (! substitute_type (info, ""))
	    return false;
	  arg_types[i] = pop_type (info);
	  if (arg_types[i] == NULL)
	    return false;
	  len += strlen (arg_types[i]) + 2;
	}
      if (varargs)
	len += 5;
    }

  /* Now the return type is on the top of the stack.  */

  s = (char *) xmalloc (len);
  if (! domain)
    *s = '\0';
  else
    strcpy (s, domain_type);
  strcat (s, "::| (");

  if (argcount < 0)
    strcat (s, "/* unknown */");
  else
    {
      int i;

      for (i = 0; i < argcount; i++)
	{
	  if (i > 0)
	    strcat (s, ", ");
	  strcat (s, arg_types[i]);
	}
      if (varargs)
	{
	  if (i > 0)
	    strcat (s, ", ");
	  strcat (s, "...");
	}
      if (argcount > 0)
	free (arg_types);
    }

  strcat (s, ")");

  if (! substitute_type (info, s))
    return false;

  free (s);

  return true;
}

/* Make a const qualified type.  */

static bfd_boolean
pr_const_type (p)
     PTR p;
{
  struct pr_handle *info = (struct pr_handle *) p;

  return substitute_type (info, "const |");
}

/* Make a volatile qualified type.  */

static bfd_boolean
pr_volatile_type (p)
     PTR p;
{
  struct pr_handle *info = (struct pr_handle *) p;

  return substitute_type (info, "volatile |");
}

/* Start accumulating a struct type.  */

static bfd_boolean
pr_start_struct_type (p, tag, id, structp, size)
     PTR p;
     const char *tag;
     unsigned int id;
     bfd_boolean structp;
     unsigned int size;
{
  struct pr_handle *info = (struct pr_handle *) p;

  info->indent += 2;

  if (! push_type (info, structp ? "struct " : "union "))
    return false;
  if (tag != NULL)
    {
      if (! append_type (info, tag))
	return false;
    }
  else
    {
      char idbuf[20];

      sprintf (idbuf, "%%anon%u", id);
      if (! append_type (info, idbuf))
	return false;
    }

  if (! append_type (info, " {"))
    return false;
  if (size != 0 || tag != NULL)
    {
      char ab[30];

      if (! append_type (info, " /*"))
	return false;

      if (size != 0)
	{
	  sprintf (ab, " size %u", size);
	  if (! append_type (info, ab))
	    return false;
	}
      if (tag != NULL)
	{
	  sprintf (ab, " id %u", id);
	  if (! append_type (info, ab))
	    return false;
	}
      if (! append_type (info, " */"))
	return false;
    }
  if (! append_type (info, "\n"))
    return false;

  info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;

  return indent_type (info);
}

/* Output the visibility of a field in a struct.  */

static bfd_boolean
pr_fix_visibility (info, visibility)
     struct pr_handle *info;
     enum debug_visibility visibility;
{
  const char *s = NULL;
  char *t;
  unsigned int len;

  assert (info->stack != NULL);

  if (info->stack->visibility == visibility)
    return true;

  assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);

  switch (visibility)
    {
    case DEBUG_VISIBILITY_PUBLIC:
      s = "public";
      break;
    case DEBUG_VISIBILITY_PRIVATE:
      s = "private";
      break;
    case DEBUG_VISIBILITY_PROTECTED:
      s = "protected";
      break;
    case DEBUG_VISIBILITY_IGNORE:
      s = "/* ignore */";
      break;
    default:
      abort ();
      return false;
    }

  /* Trim off a trailing space in the struct string, to make the
     output look a bit better, then stick on the visibility string.  */

  t = info->stack->type;
  len = strlen (t);
  assert (t[len - 1] == ' ');
  t[len - 1] = '\0';

  if (! append_type (info, s)
      || ! append_type (info, ":\n")
      || ! indent_type (info))
    return false;

  info->stack->visibility = visibility;

  return true;
}

/* Add a field to a struct type.  */

static bfd_boolean
pr_struct_field (p, name, bitpos, bitsize, visibility)
     PTR p;
     const char *name;
     bfd_vma bitpos;
     bfd_vma bitsize;
     enum debug_visibility visibility;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[20];
  char *t;

  if (! substitute_type (info, name))
    return false;

  if (! append_type (info, "; /* "))
    return false;

  if (bitsize != 0)
    {
      print_vma (bitsize, ab, true, false);
      if (! append_type (info, "bitsize ")
	  || ! append_type (info, ab)
	  || ! append_type (info, ", "))
	return false;
    }

  print_vma (bitpos, ab, true, false);
  if (! append_type (info, "bitpos ")
      || ! append_type (info, ab)
      || ! append_type (info, " */\n")
      || ! indent_type (info))
    return false;

  t = pop_type (info);
  if (t == NULL)
    return false;

  if (! pr_fix_visibility (info, visibility))
    return false;

  return append_type (info, t);
}

/* Finish a struct type.  */

static bfd_boolean
pr_end_struct_type (p)
     PTR p;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *s;

  assert (info->stack != NULL);
  assert (info->indent >= 2);

  info->indent -= 2;

  /* Change the trailing indentation to have a close brace.  */
  s = info->stack->type + strlen (info->stack->type) - 2;
  assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');

  *s++ = '}';
  *s = '\0';

  return true;
}

/* Start a class type.  */

static bfd_boolean
pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
     PTR p;
     const char *tag;
     unsigned int id;
     bfd_boolean structp;
     unsigned int size;
     bfd_boolean vptr;
     bfd_boolean ownvptr;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *tv = NULL;

  info->indent += 2;

  if (vptr && ! ownvptr)
    {
      tv = pop_type (info);
      if (tv == NULL)
	return false;
    }

  if (! push_type (info, structp ? "class " : "union class "))
    return false;
  if (tag != NULL)
    {
      if (! append_type (info, tag))
	return false;
    }
  else
    {
      char idbuf[20];

      sprintf (idbuf, "%%anon%u", id);
      if (! append_type (info, idbuf))
	return false;
    }

  if (! append_type (info, " {"))
    return false;
  if (size != 0 || vptr || ownvptr || tag != NULL)
    {
      if (! append_type (info, " /*"))
	return false;

      if (size != 0)
	{
	  char ab[20];

	  sprintf (ab, "%u", size);
	  if (! append_type (info, " size ")
	      || ! append_type (info, ab))
	    return false;
	}

      if (vptr)
	{
	  if (! append_type (info, " vtable "))
	    return false;
	  if (ownvptr)
	    {
	      if (! append_type (info, "self "))
		return false;
	    }
	  else
	    {
	      if (! append_type (info, tv)
		  || ! append_type (info, " "))
		return false;
	    }
	}

      if (tag != NULL)
	{
	  char ab[30];

	  sprintf (ab, " id %u", id);
	  if (! append_type (info, ab))
	    return false;
	}

      if (! append_type (info, " */"))
	return false;
    }

  info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;

  return (append_type (info, "\n")
	  && indent_type (info));
}

/* Add a static member to a class.  */

static bfd_boolean
pr_class_static_member (p, name, physname, visibility)
     PTR p;
     const char *name;
     const char *physname;
     enum debug_visibility visibility;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;

  if (! substitute_type (info, name))
    return false;

  if (! prepend_type (info, "static ")
      || ! append_type (info, "; /* ")
      || ! append_type (info, physname)
      || ! append_type (info, " */\n")
      || ! indent_type (info))
    return false;

  t = pop_type (info);
  if (t == NULL)
    return false;

  if (! pr_fix_visibility (info, visibility))
    return false;

  return append_type (info, t);
}

/* Add a base class to a class.  */

static bfd_boolean
pr_class_baseclass (p, bitpos, virtual, visibility)
     PTR p;
     bfd_vma bitpos;
     bfd_boolean virtual;
     enum debug_visibility visibility;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;
  const char *prefix;

⌨️ 快捷键说明

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