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

📄 debug.c

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

/* Finish a block in a function.  This matches the call to
   debug_start_block.  The argument is the address at which this block
   ends.  */

bfd_boolean
debug_end_block (handle, addr)
     PTR handle;
     bfd_vma addr;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_block *parent;

  if (info->current_unit == NULL
      || info->current_block == NULL)
    {
      debug_error ("debug_end_block: no current block");
      return false;
    }

  parent = info->current_block->parent;
  if (parent == NULL)
    {
      debug_error ("debug_end_block: attempt to close top level block");
      return false;
    }

  info->current_block->end = addr;

  info->current_block = parent;

  return true;
}

/* Associate a line number in the current source file and function
   with a given address.  */

bfd_boolean
debug_record_line (handle, lineno, addr)
     PTR handle;
     unsigned long lineno;
     bfd_vma addr;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_lineno *l;
  unsigned int i;

  if (info->current_unit == NULL)
    {
      debug_error ("debug_record_line: no current unit");
      return false;
    }

  l = info->current_lineno;
  if (l != NULL && l->file == info->current_file)
    {
      for (i = 0; i < DEBUG_LINENO_COUNT; i++)
	{
	  if (l->linenos[i] == (unsigned long) -1)
	    {
	      l->linenos[i] = lineno;
	      l->addrs[i] = addr;
	      return true;
	    }
	}
    }

  /* If we get here, then either 1) there is no current_lineno
     structure, which means this is the first line number in this
     compilation unit, 2) the current_lineno structure is for a
     different file, or 3) the current_lineno structure is full.
     Regardless, we want to allocate a new debug_lineno structure, put
     it in the right place, and make it the new current_lineno
     structure.  */

  l = (struct debug_lineno *) xmalloc (sizeof *l);
  memset (l, 0, sizeof *l);

  l->file = info->current_file;
  l->linenos[0] = lineno;
  l->addrs[0] = addr;
  for (i = 1; i < DEBUG_LINENO_COUNT; i++)
    l->linenos[i] = (unsigned long) -1;

  if (info->current_lineno != NULL)
    info->current_lineno->next = l;
  else
    info->current_unit->linenos = l;

  info->current_lineno = l;

  return true;
}

/* Start a named common block.  This is a block of variables that may
   move in memory.  */

bfd_boolean
debug_start_common_block (handle, name)
     PTR handle ATTRIBUTE_UNUSED;
     const char *name ATTRIBUTE_UNUSED;
{
  /* FIXME */
  debug_error ("debug_start_common_block: not implemented");
  return false;
}

/* End a named common block.  */

bfd_boolean
debug_end_common_block (handle, name)
     PTR handle ATTRIBUTE_UNUSED;
     const char *name ATTRIBUTE_UNUSED;
{
  /* FIXME */
  debug_error ("debug_end_common_block: not implemented");
  return false;
}

/* Record a named integer constant.  */

bfd_boolean
debug_record_int_const (handle, name, val)
     PTR handle;
     const char *name;
     bfd_vma val;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_name *n;

  if (name == NULL)
    return false;

  n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
				      DEBUG_LINKAGE_NONE);
  if (n == NULL)
    return false;

  n->u.int_constant = val;

  return true;
}

/* Record a named floating point constant.  */

bfd_boolean
debug_record_float_const (handle, name, val)
     PTR handle;
     const char *name;
     double val;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_name *n;

  if (name == NULL)
    return false;

  n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
				      DEBUG_LINKAGE_NONE);
  if (n == NULL)
    return false;

  n->u.float_constant = val;

  return true;
}

/* Record a typed constant with an integral value.  */

bfd_boolean
debug_record_typed_const (handle, name, type, val)
     PTR handle;
     const char *name;
     debug_type type;
     bfd_vma val;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_name *n;
  struct debug_typed_constant *tc;

  if (name == NULL || type == NULL)
    return false;

  n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
				      DEBUG_LINKAGE_NONE);
  if (n == NULL)
    return false;

  tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
  memset (tc, 0, sizeof *tc);

  tc->type = type;
  tc->val = val;

  n->u.typed_constant = tc;

  return true;
}

/* Record a label.  */

bfd_boolean
debug_record_label (handle, name, type, addr)
     PTR handle ATTRIBUTE_UNUSED;
     const char *name ATTRIBUTE_UNUSED;
     debug_type type ATTRIBUTE_UNUSED;
     bfd_vma addr ATTRIBUTE_UNUSED;
{
  /* FIXME.  */
  debug_error ("debug_record_label not implemented");
  return false;
}

/* Record a variable.  */

bfd_boolean
debug_record_variable (handle, name, type, kind, val)
     PTR handle;
     const char *name;
     debug_type type;
     enum debug_var_kind kind;
     bfd_vma val;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_namespace **nsp;
  enum debug_object_linkage linkage;
  struct debug_name *n;
  struct debug_variable *v;

  if (name == NULL || type == NULL)
    return false;

  if (info->current_unit == NULL
      || info->current_file == NULL)
    {
      debug_error ("debug_record_variable: no current file");
      return false;
    }

  if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
    {
      nsp = &info->current_file->globals;
      if (kind == DEBUG_GLOBAL)
	linkage = DEBUG_LINKAGE_GLOBAL;
      else
	linkage = DEBUG_LINKAGE_STATIC;
    }
  else
    {
      if (info->current_block == NULL)
	{
	  debug_error ("debug_record_variable: no current block");
	  return false;
	}
      nsp = &info->current_block->locals;
      linkage = DEBUG_LINKAGE_AUTOMATIC;
    }

  n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
  if (n == NULL)
    return false;

  v = (struct debug_variable *) xmalloc (sizeof *v);
  memset (v, 0, sizeof *v);

  v->kind = kind;
  v->type = type;
  v->val = val;

  n->u.variable = v;

  return true;  
}

/* Make a type with a given kind and size.  */

/*ARGSUSED*/
static struct debug_type *
debug_make_type (info, kind, size)
     struct debug_handle *info ATTRIBUTE_UNUSED;
     enum debug_type_kind kind;
     unsigned int size;
{
  struct debug_type *t;

  t = (struct debug_type *) xmalloc (sizeof *t);
  memset (t, 0, sizeof *t);

  t->kind = kind;
  t->size = size;

  return t;
}

/* Make an indirect type which may be used as a placeholder for a type
   which is referenced before it is defined.  */

debug_type
debug_make_indirect_type (handle, slot, tag)
     PTR handle;
     debug_type *slot;
     const char *tag;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_indirect_type *i;

  t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
  if (t == NULL)
    return DEBUG_TYPE_NULL;

  i = (struct debug_indirect_type *) xmalloc (sizeof *i);
  memset (i, 0, sizeof *i);

  i->slot = slot;
  i->tag = tag;

  t->u.kindirect = i;

  return t;
}

/* Make a void type.  There is only one of these.  */

debug_type
debug_make_void_type (handle)
     PTR handle;
{
  struct debug_handle *info = (struct debug_handle *) handle;

  return debug_make_type (info, DEBUG_KIND_VOID, 0);
}

/* Make an integer type of a given size.  The bfd_boolean argument is true
   if the integer is unsigned.  */

debug_type
debug_make_int_type (handle, size, unsignedp)
     PTR handle;
     unsigned int size;
     bfd_boolean unsignedp;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;

  t = debug_make_type (info, DEBUG_KIND_INT, size);
  if (t == NULL)
    return DEBUG_TYPE_NULL;

  t->u.kint = unsignedp;

  return t;
}

/* Make a floating point type of a given size.  FIXME: On some
   platforms, like an Alpha, you probably need to be able to specify
   the format.  */

debug_type
debug_make_float_type (handle, size)
     PTR handle;
     unsigned int size;
{
  struct debug_handle *info = (struct debug_handle *) handle;

  return debug_make_type (info, DEBUG_KIND_FLOAT, size);
}

/* Make a bfd_boolean type of a given size.  */

debug_type
debug_make_bool_type (handle, size)
     PTR handle;
     unsigned int size;
{
  struct debug_handle *info = (struct debug_handle *) handle;

  return debug_make_type (info, DEBUG_KIND_BOOL, size);
}

/* Make a complex type of a given size.  */

debug_type
debug_make_complex_type (handle, size)
     PTR handle;
     unsigned int size;
{
  struct debug_handle *info = (struct debug_handle *) handle;

  return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
}

/* Make a structure type.  The second argument is true for a struct,
   false for a union.  The third argument is the size of the struct.
   The fourth argument is a NULL terminated array of fields.  */

debug_type
debug_make_struct_type (handle, structp, size, fields)
     PTR handle;
     bfd_boolean structp;
     bfd_vma size;
     debug_field *fields;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_class_type *c;

  t = debug_make_type (info,
		       structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
		       size);
  if (t == NULL)
    return DEBUG_TYPE_NULL;

  c = (struct debug_class_type *) xmalloc (sizeof *c);
  memset (c, 0, sizeof *c);

  c->fields = fields;

  t->u.kclass = c;

  return t;
}

/* Make an object type.  The first three arguments after the handle
   are the same as for debug_make_struct_type.  The next arguments are
   a NULL terminated array of base classes, a NULL terminated array of
   methods, the type of the object holding the virtual function table
   if it is not this object, and a bfd_boolean which is true if this
   object has its own virtual function table.  */

debug_type
debug_make_object_type (handle, structp, size, fields, baseclasses,
			methods, vptrbase, ownvptr)
     PTR handle;
     bfd_boolean structp;
     bfd_vma size;
     debug_field *fields;
     debug_baseclass *baseclasses;
     debug_method *methods;
     debug_type vptrbase;
     bfd_boolean ownvptr;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_class_type *c;

  t = debug_make_type (info,
		       structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
		       size);
  if (t == NULL)
    return DEBUG_TYPE_NULL;

  c = (struct debug_class_type *) xmalloc (sizeof *c);
  memset (c, 0, sizeof *c);

  c->fields = fields;
  c->baseclasses = baseclasses;
  c->methods = methods;
  if (ownvptr)
    c->vptrbase = t;
  else
    c->vptrbase = vptrbase;

  t->u.kclass = c;

  return t;
}

/* Make an enumeration type.  The arguments are a null terminated
   array of strings, and an array of corresponding values.  */

debug_type
debug_make_enum_type (handle, names, values)
     PTR handle;
     const char **names;
     bfd_signed_vma *values;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_enum_type *e;

  t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
  if (t == NULL)
    return DEBUG_TYPE_NULL;

  e = (struct debug_enum_type *) xmalloc (sizeof *e);
  memset (e, 0, sizeof *e);

  e->names = names;
  e->values = values;

  t->u.kenum = e;

  return t;
}

/* Make a pointer to a given type.  */

⌨️ 快捷键说明

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