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

📄 debug.c

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

  m = (struct debug_method_variant *) xmalloc (sizeof *m);
  memset (m, 0, sizeof *m);

  m->physname = physname;
  m->type = type;
  m->visibility = visibility;
  m->constp = constp;
  m->volatilep = volatilep;
  m->voffset = VOFFSET_STATIC_METHOD;
  m->address = address;

  return m;
}

/* Name a type.  */

debug_type
debug_name_type (handle, name, type)
     PTR handle;
     const char *name;
     debug_type type;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_named_type *n;
  struct debug_name *nm;

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

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

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

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

  n->type = type;

  t->u.knamed = n;

  /* We always add the name to the global namespace.  This is probably
     wrong in some cases, but it seems to be right for stabs.  FIXME.  */

  nm = debug_add_to_namespace (info, &info->current_file->globals, name,
			       DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
  if (nm == NULL)
    return DEBUG_TYPE_NULL;

  nm->u.type = t;

  n->name = nm;

  return t;
}

/* Tag a type.  */

debug_type
debug_tag_type (handle, name, type)
     PTR handle;
     const char *name;
     debug_type type;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_type *t;
  struct debug_named_type *n;
  struct debug_name *nm;

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

  if (info->current_file == NULL)
    {
      debug_error ("debug_tag_type: no current file");
      return DEBUG_TYPE_NULL;
    }

  if (type->kind == DEBUG_KIND_TAGGED)
    {
      if (strcmp (type->u.knamed->name->name, name) == 0)
	return type;
      debug_error ("debug_tag_type: extra tag attempted");
      return DEBUG_TYPE_NULL;
    }

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

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

  n->type = type;

  t->u.knamed = n;

  /* We keep a global namespace of tags for each compilation unit.  I
     don't know if that is the right thing to do.  */

  nm = debug_add_to_namespace (info, &info->current_file->globals, name,
			       DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
  if (nm == NULL)
    return DEBUG_TYPE_NULL;

  nm->u.tag = t;

  n->name = nm;

  return t;
}

/* Record the size of a given type.  */

/*ARGSUSED*/
bfd_boolean
debug_record_type_size (handle, type, size)
     PTR handle ATTRIBUTE_UNUSED;
     debug_type type;
     unsigned int size;
{
  if (type->size != 0 && type->size != size)
    fprintf (stderr, "Warning: changing type size from %d to %d\n",
	     type->size, size);

  type->size = size;

  return true;
}

/* Find a named type.  */

debug_type
debug_find_named_type (handle, name)
     PTR handle;
     const char *name;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_block *b;
  struct debug_file *f;

  /* We only search the current compilation unit.  I don't know if
     this is right or not.  */

  if (info->current_unit == NULL)
    {
      debug_error ("debug_find_named_type: no current compilation unit");
      return DEBUG_TYPE_NULL;
    }

  for (b = info->current_block; b != NULL; b = b->parent)
    {
      if (b->locals != NULL)
	{
	  struct debug_name *n;

	  for (n = b->locals->list; n != NULL; n = n->next)
	    {
	      if (n->kind == DEBUG_OBJECT_TYPE
		  && n->name[0] == name[0]
		  && strcmp (n->name, name) == 0)
		return n->u.type;
	    }
	}
    }

  for (f = info->current_unit->files; f != NULL; f = f->next)
    {
      if (f->globals != NULL)
	{
	  struct debug_name *n;

	  for (n = f->globals->list; n != NULL; n = n->next)
	    {
	      if (n->kind == DEBUG_OBJECT_TYPE
		  && n->name[0] == name[0]
		  && strcmp (n->name, name) == 0)
		return n->u.type;
	    }
	}
    }

  return DEBUG_TYPE_NULL;	  
}

/* Find a tagged type.  */

debug_type
debug_find_tagged_type (handle, name, kind)
     PTR handle;
     const char *name;
     enum debug_type_kind kind;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_unit *u;

  /* We search the globals of all the compilation units.  I don't know
     if this is correct or not.  It would be easy to change.  */

  for (u = info->units; u != NULL; u = u->next)
    {
      struct debug_file *f;

      for (f = u->files; f != NULL; f = f->next)
	{
	  struct debug_name *n;

	  if (f->globals != NULL)
	    {
	      for (n = f->globals->list; n != NULL; n = n->next)
		{
                  if (n->kind == DEBUG_OBJECT_TAG
                      && (kind == DEBUG_KIND_ILLEGAL
                          || n->u.tag->kind == kind)
                      && n->name[0] == name[0]
                      && strcmp (n->name, name) == 0)
                    return n->u.tag;
                }
	    }
	}
    }

  return DEBUG_TYPE_NULL;
}


debug_type*
debug_get_all_classes (handle)
     PTR handle;
{
  struct debug_handle *info = (struct debug_handle *) handle;
  struct debug_unit *u;
  struct debug_type_compare_list *list;
  debug_type *classes;
  int size = 0;
  list = NULL;
  /* We search the globals of all the compilation units.  I don't know
     if this is correct or not.  It would be easy to change.  */

  for (u = info->units; u != NULL; u = u->next)
    {
      struct debug_file *f;

      for (f = u->files; f != NULL; f = f->next)
	{
	  struct debug_name *n;

	  if (f->globals != NULL)
	    {
	      for (n = f->globals->list; n != NULL; n = n->next)
		{
                  if (n->kind == DEBUG_OBJECT_TAG) {
                    debug_type real = debug_get_real_type(handle, n->u.tag, NULL);
                    if (real->kind == DEBUG_KIND_CLASS ||
                        real->kind == DEBUG_KIND_STRUCT) {
                      struct debug_type_compare_list *item;
                      item = (struct debug_type_compare_list *) xmalloc(sizeof *item);
                      memset (item, 0, sizeof *item);
                      item->next = list;
                      item->t1 = n->u.tag;
                      size++;
                      list = item;
                    }
                  }
                }
            }
        }
    }
  classes = (debug_type*) xmalloc((size+1) * sizeof *classes);
  classes[size--] = NULL;
  while (list != NULL) {
    struct debug_type_compare_list *item;
    classes[size--] = list->t1;
    list->t1 = NULL;
    item = list;
    list = list->next;
    item->next = NULL;
    free(item);
  }
      
  return classes;
}


/* Get a base type.  We build a linked list on the stack to avoid
   crashing if the type is defined circularly.  */

struct debug_type *
debug_get_real_type (handle, type, list)
     PTR handle;
     debug_type type;
     struct debug_type_real_list *list;
{
  struct debug_type_real_list *l;
  struct debug_type_real_list rl;

  switch (type->kind)
    {
    default:
      return type;

    case DEBUG_KIND_INDIRECT:
    case DEBUG_KIND_NAMED:
    case DEBUG_KIND_TAGGED:
      break;
    }

  for (l = list; l != NULL; l = l->next)
    {
      if (l->t == type)
	{
	  fprintf (stderr,
		   "debug_get_real_type: circular debug information for %s\n",
		   debug_get_type_name (handle, type));
	  return NULL;
	}
    }

  rl.next = list;
  rl.t = type;

  switch (type->kind)
    {
      /* The default case is just here to avoid warnings.  */
    default:
    case DEBUG_KIND_INDIRECT:
      if (*type->u.kindirect->slot != NULL)
	return debug_get_real_type (handle, *type->u.kindirect->slot, &rl);
      return type;
    case DEBUG_KIND_NAMED:
    case DEBUG_KIND_TAGGED:
      return debug_get_real_type (handle, type->u.knamed->type, &rl);
    }
  /*NOTREACHED*/
}

/* Get the kind of a type.  */

enum debug_type_kind
debug_get_type_kind (handle, type)
     PTR handle;
     debug_type type;
{
  if (type == NULL)
    return DEBUG_KIND_ILLEGAL;
  type = debug_get_real_type (handle, type, NULL);
  if (type == NULL)
    return DEBUG_KIND_ILLEGAL;
  return type->kind;
}

/* Get the name of a type.  */

const char *
debug_get_type_name (handle, type)
     PTR handle;
     debug_type type;
{
  if (type->kind == DEBUG_KIND_INDIRECT)
    {
      if (*type->u.kindirect->slot != NULL)
	return debug_get_type_name (handle, *type->u.kindirect->slot);
      return type->u.kindirect->tag;
    }
  if (type->kind == DEBUG_KIND_NAMED
      || type->kind == DEBUG_KIND_TAGGED)
    return type->u.knamed->name->name;
  return NULL;
}

/* Get the size of a type.  */

bfd_vma
debug_get_type_size (handle, type)
     PTR handle;
     debug_type type;
{
  if (type == NULL)
    return 0;

  /* We don't call debug_get_real_type, because somebody might have
     called debug_record_type_size on a named or indirect type.  */

  if (type->size != 0)
    return type->size;

  switch (type->kind)
    {
    default:
      return 0;
    case DEBUG_KIND_INDIRECT:
      if (*type->u.kindirect->slot != NULL)
	return debug_get_type_size (handle, *type->u.kindirect->slot);
      return 0;
    case DEBUG_KIND_NAMED:
    case DEBUG_KIND_TAGGED:
      return debug_get_type_size (handle, type->u.knamed->type);
    }
  /*NOTREACHED*/
}

/* Get the return type of a function or method type.  */

debug_type
debug_get_return_type (handle, type)
     PTR handle;
     debug_type type;
{
  if (type == NULL)
    return DEBUG_TYPE_NULL;
  type = debug_get_real_type (handle, type, NULL);
  if (type == NULL)
    return DEBUG_TYPE_NULL;
  switch (type->kind)
    {
    default:
      return DEBUG_TYPE_NULL;
    case DEBUG_KIND_FUNCTION:
      return type->u.kfunction->return_type;
    case DEBUG_KIND_METHOD:
      return type->u.kmethod->return_type;
    }
  /*NOTREACHED*/      
}

/* Get the parameter types of a function or method type (except that
   we don't currently store the parameter types of a function).  */

const debug_type *
debug_get_parameter_types (handle, type, pvarargs)
     PTR handle;
     debug_type type;
     bfd_boolean *pvarargs;
{
  if (type == NULL)
    return NULL;
  type = debug_get_real_type (handle, type, NULL);
  if (type == NULL)
    return NULL;
  switch (type->kind)
    {
    default:
      return NULL;
    case DEBUG_KIND_FUNCTION:
      *pvarargs = type->u.kfunction->varargs;
      return type->u.kfunction->arg_types;
    case DEBUG_KIND_METHOD:
      *pvarargs = type->u.kmethod->varargs;
      return type->u.kmethod->arg_types;
    }
  /*NOTREACHED*/
}

/* Get the target type of a type.  */

debug_type
debug_get_target_type (handle, type)
     PTR handle;
     debug_type type;
{
  if (type == NULL)
    return NULL;
  type = debug_get_real_type (handle, type, NULL);
  if (type == NULL)
    return NULL;
  switch (type->kind)
    {
    default:
      return NULL;
    case DEBUG_KIND_POINTER:
      return type->u.kpointer;
    case DEBUG_KIND_REFERENCE:
      return type->u.kreference;
    case DEBUG_KIND_CONST:
      return type->u.kconst;
    case DEBUG_KIND_VOLATILE:
      return type->u.kvolatile;
    }
  /*NOTREACHED*/
}

/* Get the NULL terminated array of fields for a struct, union, or
   class.  */

const debug_field *
debug_get_fields (handle, type)
     PTR handle;
     debug_type type;
{

⌨️ 快捷键说明

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