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

📄 prdbg.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 3 页
字号:
  char ab[20];
  char *s, *l, *n;

  assert (info->stack != NULL && info->stack->next != NULL);

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

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

  if (strncmp (t, "class ", sizeof "class " - 1) == 0)
    t += sizeof "class " - 1;

  /* Push it back on to take advantage of the prepend_type and
     append_type routines.  */
  if (! push_type (info, t))
    return false;

  if (virtual)
    {
      if (! prepend_type (info, "virtual "))
	return false;
    }

  switch (visibility)
    {
    case DEBUG_VISIBILITY_PUBLIC:
      prefix = "public ";
      break;
    case DEBUG_VISIBILITY_PROTECTED:
      prefix = "protected ";
      break;
    case DEBUG_VISIBILITY_PRIVATE:
      prefix = "private ";
      break;
    default:
      prefix = "/* unknown visibility */ ";
      break;
    }

  if (! prepend_type (info, prefix))
    return false;

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

  /* Now the top of the stack is something like "public A / * bitpos
     10 * /".  The next element on the stack is something like "class
     xx { / * size 8 * /\n...".  We want to substitute the top of the
     stack in before the {.  */
  s = strchr (info->stack->next->type, '{');
  assert (s != NULL);
  --s;

  /* If there is already a ':', then we already have a baseclass, and
     we must append this one after a comma.  */
  for (l = info->stack->next->type; l != s; l++)
    if (*l == ':')
      break;
  if (! prepend_type (info, l == s ? " : " : ", "))
    return false;

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

  n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
  memcpy (n, info->stack->type, s - info->stack->type);
  strcpy (n + (s - info->stack->type), t);
  strcat (n, s);

  free (info->stack->type);
  info->stack->type = n;

  free (t);

  return true;
}

/* Start adding a method to a class.  */

static bfd_boolean
pr_class_start_method (p, name)
     PTR p;
     const char *name;
{
  struct pr_handle *info = (struct pr_handle *) p;

  assert (info->stack != NULL);
  info->stack->method = name;
  return true;
}

/* Add a variant to a method.  */

static bfd_boolean
pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
			 context)
     PTR p;
     const char *physname;
     enum debug_visibility visibility;
     bfd_boolean constp;
     bfd_boolean volatilep;
     bfd_vma voffset;
     bfd_boolean context;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *method_type;
  char *context_type;

  assert (info->stack != NULL);
  assert (info->stack->next != NULL);

  /* Put the const and volatile qualifiers on the type.  */
  if (volatilep)
    {
      if (! append_type (info, " volatile"))
	return false;
    }
  if (constp)
    {
      if (! append_type (info, " const"))
	return false;
    }

  /* Stick the name of the method into its type.  */
  if (! substitute_type (info,
			 (context
			  ? info->stack->next->next->method
			  : info->stack->next->method)))
    return false;

  /* Get the type.  */
  method_type = pop_type (info);
  if (method_type == NULL)
    return false;

  /* Pull off the context type if there is one.  */
  if (! context)
    context_type = NULL;
  else
    {
      context_type = pop_type (info);
      if (context_type == NULL)
	return false;
    }

  /* Now the top of the stack is the class.  */

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

  if (! append_type (info, method_type)
      || ! append_type (info, " /* ")
      || ! append_type (info, physname)
      || ! append_type (info, " "))
    return false;
  if (context || voffset != 0)
    {
      char ab[20];

      if (context)
	{
	  if (! append_type (info, "context ")
	      || ! append_type (info, context_type)
	      || ! append_type (info, " "))
	    return false;
	}
      print_vma (voffset, ab, true, false);
      if (! append_type (info, "voffset ")
	  || ! append_type (info, ab))
	return false;
    }

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

/* Add a static variant to a method.  */

static bfd_boolean
pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
     PTR p;
     const char *physname;
     enum debug_visibility visibility;
     bfd_boolean constp;
     bfd_boolean volatilep;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *method_type;

  assert (info->stack != NULL);
  assert (info->stack->next != NULL);
  assert (info->stack->next->method != NULL);

  /* Put the const and volatile qualifiers on the type.  */
  if (volatilep)
    {
      if (! append_type (info, " volatile"))
	return false;
    }
  if (constp)
    {
      if (! append_type (info, " const"))
	return false;
    }

  /* Mark it as static.  */
  if (! prepend_type (info, "static "))
    return false;

  /* Stick the name of the method into its type.  */
  if (! substitute_type (info, info->stack->next->method))
    return false;

  /* Get the type.  */
  method_type = pop_type (info);
  if (method_type == NULL)
    return false;

  /* Now the top of the stack is the class.  */

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

  return (append_type (info, method_type)
	  && append_type (info, " /* ")
	  && append_type (info, physname)
	  && append_type (info, " */;\n")
	  && indent_type (info));
}

/* Finish up a method.  */

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

  info->stack->method = NULL;
  return true;
}

/* Finish up a class.  */

static bfd_boolean
pr_end_class_type (p)
     PTR p;
{
  return pr_end_struct_type (p);
}

/* Push a type on the stack using a typedef name.  */

static bfd_boolean
pr_typedef_type (p, name)
     PTR p;
     const char *name;
{
  struct pr_handle *info = (struct pr_handle *) p;

  return push_type (info, name);
}

/* Push a type on the stack using a tag name.  */

static bfd_boolean
pr_tag_type (p, name, id, kind)
     PTR p;
     const char *name;
     unsigned int id;
     enum debug_type_kind kind;
{
  struct pr_handle *info = (struct pr_handle *) p;
  const char *t, *tag;
  char idbuf[20];

  switch (kind)
    {
    case DEBUG_KIND_STRUCT:
      t = "struct ";
      break;
    case DEBUG_KIND_UNION:
      t = "union ";
      break;
    case DEBUG_KIND_ENUM:
      t = "enum ";
      break;
    case DEBUG_KIND_CLASS:
      t = "class ";
      break;
    case DEBUG_KIND_UNION_CLASS:
      t = "union class ";
      break;
    default:
      abort ();
      return false;
    }

  if (! push_type (info, t))
    return false;
  if (name != NULL)
    tag = name;
  else
    {
      sprintf (idbuf, "%%anon%u", id);
      tag = idbuf;
    }

  if (! append_type (info, tag))
    return false;
  if (name != NULL && kind != DEBUG_KIND_ENUM)
    {
      sprintf (idbuf, " /* id %u */", id);
      if (! append_type (info, idbuf))
	return false;
    }

  return true;
}

/* Output a typedef.  */

static bfd_boolean
pr_typdef (p, name)
     PTR p;
     const char *name;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *s;

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

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

  indent (info);
  fprintf (info->f, "typedef %s;\n", s);

  free (s);

  return true;
}

/* Output a tag.  The tag should already be in the string on the
   stack, so all we have to do here is print it out.  */

/*ARGSUSED*/
static bfd_boolean
pr_tag (p, name)
     PTR p;
     const char *name ATTRIBUTE_UNUSED;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;

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

  indent (info);
  fprintf (info->f, "%s;\n", t);

  free (t);

  return true;
}

/* Output an integer constant.  */

static bfd_boolean
pr_int_constant (p, name, val)
     PTR p;
     const char *name;
     bfd_vma val;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[20];

  indent (info);
  print_vma (val, ab, false, false);
  fprintf (info->f, "const int %s = %s;\n", name, ab);
  return true;
}

/* Output a floating point constant.  */

static bfd_boolean
pr_float_constant (p, name, val)
     PTR p;
     const char *name;
     double val;
{
  struct pr_handle *info = (struct pr_handle *) p;

  indent (info);
  fprintf (info->f, "const double %s = %g;\n", name, val);
  return true;
}

/* Output a typed constant.  */

static bfd_boolean
pr_typed_constant (p, name, val)
     PTR p;
     const char *name;
     bfd_vma val;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;
  char ab[20];

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

  indent (info);
  print_vma (val, ab, false, false);
  fprintf (info->f, "const %s %s = %s;\n", t, name, ab);

  free (t);

  return true;
}

/* Output a variable.  */

static bfd_boolean
pr_variable (p, name, kind, val)
     PTR p;
     const char *name;
     enum debug_var_kind kind;
     bfd_vma val;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;
  char ab[20];

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

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

  indent (info);
  switch (kind)
    {
    case DEBUG_STATIC:
    case DEBUG_LOCAL_STATIC:
      fprintf (info->f, "static ");
      break;
    case DEBUG_REGISTER:
      fprintf (info->f, "register ");
      break;
    default:
      break;
    }
  print_vma (val, ab, true, true);
  fprintf (info->f, "%s /* %s */;\n", t, ab);

  free (t);

  return true;
}

/* Start outputting a function.  */

static bfd_boolean
pr_start_function (p, name, global)
     PTR p;
     const char *name;
     bfd_boolean global;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;

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

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

  indent (info);
  if (! global)
    fprintf (info->f, "static ");
  fprintf (info->f, "%s (", t);

  info->parameter = 1;

  return true;
}

/* Output a function parameter.  */

static bfd_boolean
pr_function_parameter (p, name, kind, val)
     PTR p;
     const char *name;
     enum debug_parm_kind kind;
     bfd_vma val;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char *t;
  char ab[20];

  if (kind == DEBUG_PARM_REFERENCE
      || kind == DEBUG_PARM_REF_REG)
    {
      if (! pr_reference_type (p))
	return false;
    }

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

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

  if (info->parameter != 1)
    fprintf (info->f, ", ");

  if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
    fprintf (info->f, "register ");

  print_vma (val, ab, true, true);
  fprintf (info->f, "%s /* %s */", t, ab);

  free (t);

  ++info->parameter;

  return true;
}

/* Start writing out a block.  */

static bfd_boolean
pr_start_block (p, addr)
     PTR p;
     bfd_vma addr;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[20];

  if (info->parameter > 0)
    {
      fprintf (info->f, ")\n");
      info->parameter = 0;
    }

  indent (info);
  print_vma (addr, ab, true, true);
  fprintf (info->f, "{ /* %s */\n", ab);

  info->indent += 2;

  return true;
}

/* Write out line number information.  */

static bfd_boolean
pr_lineno (p, filename, lineno, addr)
     PTR p;
     const char *filename;
     unsigned long lineno;
     bfd_vma addr;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[20];

  indent (info);
  print_vma (addr, ab, true, true);
  fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);

  return true;
}

/* Finish writing out a block.  */

static bfd_boolean
pr_end_block (p, addr)
     PTR p;
     bfd_vma addr;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[20];

  info->indent -= 2;

  indent (info);
  print_vma (addr, ab, true, true);
  fprintf (info->f, "} /* %s */\n", ab);

  return true;
}

/* Finish writing out a function.  */

/*ARGSUSED*/
static bfd_boolean
pr_end_function (p)
     PTR p ATTRIBUTE_UNUSED;
{
  return true;
}

⌨️ 快捷键说明

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