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