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

📄 prdbg.c

📁 java 反射机制详解示例,实现类属性及方法修改
💻 C
📖 第 1 页 / 共 3 页
字号:
/* prdbg.c -- Print out generic debugging information.
   Copyright 1995, 1996 Free Software Foundation, Inc.
   Written by Ian Lance Taylor <ian@cygnus.com>.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

/* This file prints out the generic debugging information, by
   supplying a set of routines to debug_write.  */

#include <stdio.h>
#include <assert.h>

#include <bfd.h>
#include "bucomm.h"
#include <libiberty.h>
#include "debug.h"
#include "budbg.h"

/* This is the structure we use as a handle for these routines.  */

struct pr_handle
{
  /* File to print information to.  */
  FILE *f;
  /* Current indentation level.  */
  unsigned int indent;
  /* Type stack.  */
  struct pr_stack *stack;
  /* Parameter number we are about to output.  */
  int parameter;
};

/* The type stack.  */

struct pr_stack
{
  /* Next element on the stack.  */
  struct pr_stack *next;
  /* This element.  */
  char *type;
  /* Current visibility of fields if this is a class.  */
  enum debug_visibility visibility;
  /* Name of the current method we are handling.  */
  const char *method;
};

static void indent PARAMS ((struct pr_handle *));
static bfd_boolean push_type PARAMS ((struct pr_handle *, const char *));
static bfd_boolean prepend_type PARAMS ((struct pr_handle *, const char *));
static bfd_boolean append_type PARAMS ((struct pr_handle *, const char *));
static bfd_boolean substitute_type PARAMS ((struct pr_handle *, const char *));
static bfd_boolean indent_type PARAMS ((struct pr_handle *));
static char *pop_type PARAMS ((struct pr_handle *));
static void print_vma PARAMS ((bfd_vma, char *, bfd_boolean, bfd_boolean));
static bfd_boolean pr_fix_visibility
  PARAMS ((struct pr_handle *, enum debug_visibility));

static bfd_boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
static bfd_boolean pr_start_source PARAMS ((PTR, const char *));
static bfd_boolean pr_empty_type PARAMS ((PTR));
static bfd_boolean pr_void_type PARAMS ((PTR));
static bfd_boolean pr_int_type PARAMS ((PTR, unsigned int, bfd_boolean));
static bfd_boolean pr_float_type PARAMS ((PTR, unsigned int));
static bfd_boolean pr_complex_type PARAMS ((PTR, unsigned int));
static bfd_boolean pr_bool_type PARAMS ((PTR, unsigned int));
static bfd_boolean pr_enum_type
  PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
static bfd_boolean pr_pointer_type PARAMS ((PTR));
static bfd_boolean pr_function_type PARAMS ((PTR, int, bfd_boolean));
static bfd_boolean pr_reference_type PARAMS ((PTR));
static bfd_boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
static bfd_boolean pr_array_type
  PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean));
static bfd_boolean pr_set_type PARAMS ((PTR, bfd_boolean));
static bfd_boolean pr_offset_type PARAMS ((PTR));
static bfd_boolean pr_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean));
static bfd_boolean pr_const_type PARAMS ((PTR));
static bfd_boolean pr_volatile_type PARAMS ((PTR));
static bfd_boolean pr_start_struct_type
  PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int));
static bfd_boolean pr_struct_field
  PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
static bfd_boolean pr_end_struct_type PARAMS ((PTR));
static bfd_boolean pr_start_class_type
  PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean,
	   bfd_boolean));
static bfd_boolean pr_class_static_member
  PARAMS ((PTR, const char *, const char *, enum debug_visibility));
static bfd_boolean pr_class_baseclass
  PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility));
static bfd_boolean pr_class_start_method PARAMS ((PTR, const char *));
static bfd_boolean pr_class_method_variant
  PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
	   bfd_vma, bfd_boolean));
static bfd_boolean pr_class_static_method_variant
  PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean));
static bfd_boolean pr_class_end_method PARAMS ((PTR));
static bfd_boolean pr_end_class_type PARAMS ((PTR));
static bfd_boolean pr_typedef_type PARAMS ((PTR, const char *));
static bfd_boolean pr_tag_type
  PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
static bfd_boolean pr_typdef PARAMS ((PTR, const char *));
static bfd_boolean pr_tag PARAMS ((PTR, const char *));
static bfd_boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
static bfd_boolean pr_float_constant PARAMS ((PTR, const char *, double));
static bfd_boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
static bfd_boolean pr_variable
  PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
static bfd_boolean pr_start_function PARAMS ((PTR, const char *, bfd_boolean));
static bfd_boolean pr_function_parameter
  PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
static bfd_boolean pr_start_block PARAMS ((PTR, bfd_vma));
static bfd_boolean pr_end_block PARAMS ((PTR, bfd_vma));
static bfd_boolean pr_end_function PARAMS ((PTR));
static bfd_boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));

static const struct debug_write_fns pr_fns =
{
  pr_start_compilation_unit,
  pr_start_source,
  pr_empty_type,
  pr_void_type,
  pr_int_type,
  pr_float_type,
  pr_complex_type,
  pr_bool_type,
  pr_enum_type,
  pr_pointer_type,
  pr_function_type,
  pr_reference_type,
  pr_range_type,
  pr_array_type,
  pr_set_type,
  pr_offset_type,
  pr_method_type,
  pr_const_type,
  pr_volatile_type,
  pr_start_struct_type,
  pr_struct_field,
  pr_end_struct_type,
  pr_start_class_type,
  pr_class_static_member,
  pr_class_baseclass,
  pr_class_start_method,
  pr_class_method_variant,
  pr_class_static_method_variant,
  pr_class_end_method,
  pr_end_class_type,
  pr_typedef_type,
  pr_tag_type,
  pr_typdef,
  pr_tag,
  pr_int_constant,
  pr_float_constant,
  pr_typed_constant,
  pr_variable,
  pr_start_function,
  pr_function_parameter,
  pr_start_block,
  pr_end_block,
  pr_end_function,
  pr_lineno
};

/* Print out the generic debugging information recorded in dhandle.  */

bfd_boolean
print_debugging_info (f, dhandle)
     FILE *f;
     PTR dhandle;
{
  struct pr_handle info;

  info.f = f;
  info.indent = 0;
  info.stack = NULL;
  info.parameter = 0;

  return debug_write (dhandle, &pr_fns, (PTR) &info);
}

/* Indent to the current indentation level.  */

static void
indent (info)
     struct pr_handle *info;
{
  unsigned int i;

  for (i = 0; i < info->indent; i++)
    putc (' ', info->f);
}

/* Push a type on the type stack.  */

static bfd_boolean
push_type (info, type)
     struct pr_handle *info;
     const char *type;
{
  struct pr_stack *n;

  if (type == NULL)
    return false;

  n = (struct pr_stack *) xmalloc (sizeof *n);
  memset (n, 0, sizeof *n);

  n->type = xstrdup (type);
  n->visibility = DEBUG_VISIBILITY_IGNORE;
  n->method = NULL;
  n->next = info->stack;
  info->stack = n;

  return true;
}

/* Prepend a string onto the type on the top of the type stack.  */

static bfd_boolean
prepend_type (info, s)
     struct pr_handle *info;
     const char *s;
{
  char *n;

  assert (info->stack != NULL);

  n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
  sprintf (n, "%s%s", s, info->stack->type);
  free (info->stack->type);
  info->stack->type = n;

  return true;
}

/* Append a string to the type on the top of the type stack.  */

static bfd_boolean
append_type (info, s)
     struct pr_handle *info;
     const char *s;
{
  unsigned int len;

  if (s == NULL)
    return false;

  assert (info->stack != NULL);

  len = strlen (info->stack->type);
  info->stack->type = (char *) xrealloc (info->stack->type,
					 len + strlen (s) + 1);
  strcpy (info->stack->type + len, s);

  return true;
}

/* We use an underscore to indicate where the name should go in a type
   string.  This function substitutes a string for the underscore.  If
   there is no underscore, the name follows the type.  */

static bfd_boolean
substitute_type (info, s)
     struct pr_handle *info;
     const char *s;
{
  char *u;

  assert (info->stack != NULL);

  u = strchr (info->stack->type, '|');
  if (u != NULL)
    {
      char *n;

      n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));

      memcpy (n, info->stack->type, u - info->stack->type);
      strcpy (n + (u - info->stack->type), s);
      strcat (n, u + 1);

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

      return true;
    }

  if (strchr (s, '|') != NULL
      && (strchr (info->stack->type, '{') != NULL
	  || strchr (info->stack->type, '(') != NULL))
    {
      if (! prepend_type (info, "(")
	  || ! append_type (info, ")"))
	return false;
    }

  if (*s == '\0')
    return true;

  return (append_type (info, " ")
	  && append_type (info, s));
}

/* Indent the type at the top of the stack by appending spaces.  */

static bfd_boolean
indent_type (info)
     struct pr_handle *info;
{
  unsigned int i;

  for (i = 0; i < info->indent; i++)
    {
      if (! append_type (info, " "))
	return false;
    }

  return true;
}

/* Pop a type from the type stack.  */

static char *
pop_type (info)
     struct pr_handle *info;
{
  struct pr_stack *o;
  char *ret;

  assert (info->stack != NULL);

  o = info->stack;
  info->stack = o->next;
  ret = o->type;
  free (o);

  return ret;
}

/* Print a VMA value into a string.  */

static void
print_vma (vma, buf, unsignedp, hexp)
     bfd_vma vma;
     char *buf;
     bfd_boolean unsignedp;
     bfd_boolean hexp;
{
  if (sizeof (vma) <= sizeof (unsigned long))
    {
      if (hexp)
	sprintf (buf, "0x%lx", (unsigned long) vma);
      else if (unsignedp)
	sprintf (buf, "%lu", (unsigned long) vma);
      else
	sprintf (buf, "%ld", (long) vma);
    }
  else
    {
      buf[0] = '0';
      buf[1] = 'x';
      sprintf_vma (buf + 2, vma);
    }
}

/* Start a new compilation unit.  */

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

  assert (info->indent == 0);

  fprintf (info->f, "%s:\n", filename);

  return true;
}

/* Start a source file within a compilation unit.  */

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

  assert (info->indent == 0);

  fprintf (info->f, " %s:\n", filename);

  return true;
}

/* Push an empty type onto the type stack.  */

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

  return push_type (info, "<undefined>");
}

/* Push a void type onto the type stack.  */

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

  return push_type (info, "void");
}

/* Push an integer type onto the type stack.  */

static bfd_boolean
pr_int_type (p, size, unsignedp)
     PTR p;
     unsigned int size;
     bfd_boolean unsignedp;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[10];

  sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
  return push_type (info, ab);
}

/* Push a floating type onto the type stack.  */

static bfd_boolean
pr_float_type (p, size)
     PTR p;
     unsigned int size;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[10];

  if (size == 4)
    return push_type (info, "float");
  else if (size == 8)
    return push_type (info, "double");

  sprintf (ab, "float%d", size * 8);
  return push_type (info, ab);
}

/* Push a complex type onto the type stack.  */

static bfd_boolean
pr_complex_type (p, size)
     PTR p;
     unsigned int size;
{
  struct pr_handle *info = (struct pr_handle *) p;

  if (! pr_float_type (p, size))
    return false;

  return prepend_type (info, "complex ");
}

/* Push a bfd_boolean type onto the type stack.  */

static bfd_boolean
pr_bool_type (p, size)
     PTR p;
     unsigned int size;
{
  struct pr_handle *info = (struct pr_handle *) p;
  char ab[10];

  sprintf (ab, "bool%d", size * 8);

  return push_type (info, ab);
}

/* Push an enum type onto the type stack.  */

static bfd_boolean
pr_enum_type (p, tag, names, values)
     PTR p;
     const char *tag;
     const char **names;
     bfd_signed_vma *values;
{
  struct pr_handle *info = (struct pr_handle *) p;
  unsigned int i;
  bfd_signed_vma val;

  if (! push_type (info, "enum "))
    return false;
  if (tag != NULL)
    {
      if (! append_type (info, tag)
	  || ! append_type (info, " "))
	return false;
    }
  if (! append_type (info, "{ "))
    return false;

  if (names == NULL)
    {
      if (! append_type (info, "/* undefined */"))
	return false;
    }
  else
    {
      val = 0;
      for (i = 0; names[i] != NULL; i++)
	{
	  if (i > 0)
	    {
	      if (! append_type (info, ", "))
		return false;
	    }

	  if (! append_type (info, names[i]))
	    return false;

	  if (values[i] != val)
	    {
	      char ab[20];

	      print_vma (values[i], ab, false, false);
	      if (! append_type (info, " = ")
		  || ! append_type (info, ab))
		return false;
	      val = values[i];
	    }

	  ++val;
	}
    }

  return append_type (info, " }");
}

/* Turn the top type on the stack into a pointer.  */

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

  assert (info->stack != NULL);

  s = strchr (info->stack->type, '|');
  if (s != NULL && s[1] == '[')
    return substitute_type (info, "(*|)");
  return substitute_type (info, "*|");
}

/* Turn the top type on the stack into a function returning that type.  */

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

  assert (info->stack != NULL);

  len = 10;

  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);
  strcpy (s, "(|) (");

⌨️ 快捷键说明

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