📄 debug.c
字号:
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 + -