mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-30 09:09:16 +08:00
* debug.h (struct debug_write_fns): Add tag parameter to
enum_type, start_struct_type, and start_class_type. * debug.c (debug_write_type): Pass any tag name to start_struct_type, debug_write_class_type, and enum_type. If DEBUG_KIND_TAGGED, pass the name in the recursive call. (debug_write_class_type): Accept a new tag parameter, and pass it to start_class_type. * prdbg.c (pop_type): Don't remove '+' character. (pr_enum_type): Accept and use tag parameter. (pr_start_struct_type): Likewise. (pr_start_class_type): Likewise. (pr_class_baseclass): Adjust algorithm used to find where to put the baseclass name. (pr_tag): Don't bother to insert the tag name.
This commit is contained in:
111
binutils/debug.c
111
binutils/debug.c
@ -1,5 +1,5 @@
|
|||||||
/* debug.c -- Handle generic debugging information.
|
/* debug.c -- Handle generic debugging information.
|
||||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||||
|
|
||||||
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
||||||
@ -48,7 +48,7 @@ struct debug_handle
|
|||||||
struct debug_function *current_function;
|
struct debug_function *current_function;
|
||||||
/* The current block. */
|
/* The current block. */
|
||||||
struct debug_block *current_block;
|
struct debug_block *current_block;
|
||||||
/* The current line number information for the current block. */
|
/* The current line number information for the current unit. */
|
||||||
struct debug_lineno *current_lineno;
|
struct debug_lineno *current_lineno;
|
||||||
/* Mark. This is used by debug_write. */
|
/* Mark. This is used by debug_write. */
|
||||||
unsigned int mark;
|
unsigned int mark;
|
||||||
@ -66,6 +66,10 @@ struct debug_unit
|
|||||||
file is always the main one, and that is where the main file name
|
file is always the main one, and that is where the main file name
|
||||||
is stored. */
|
is stored. */
|
||||||
struct debug_file *files;
|
struct debug_file *files;
|
||||||
|
/* Line number information for this compilation unit. This is not
|
||||||
|
stored by function, because assembler code may have line number
|
||||||
|
information without function information. */
|
||||||
|
struct debug_lineno *linenos;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information kept for a single source file. */
|
/* Information kept for a single source file. */
|
||||||
@ -394,12 +398,11 @@ struct debug_block
|
|||||||
bfd_vma end;
|
bfd_vma end;
|
||||||
/* Local variables. */
|
/* Local variables. */
|
||||||
struct debug_namespace *locals;
|
struct debug_namespace *locals;
|
||||||
/* Line number information. */
|
|
||||||
struct debug_lineno *linenos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Line number information we keep for a function. FIXME: This
|
/* Line number information we keep for a compilation unit. FIXME:
|
||||||
structure is easy to create, but can be very space inefficient. */
|
This structure is easy to create, but can be very space
|
||||||
|
inefficient. */
|
||||||
|
|
||||||
struct debug_lineno
|
struct debug_lineno
|
||||||
{
|
{
|
||||||
@ -511,7 +514,7 @@ static boolean debug_write_type
|
|||||||
struct debug_type *, struct debug_name *));
|
struct debug_type *, struct debug_name *));
|
||||||
static boolean debug_write_class_type
|
static boolean debug_write_class_type
|
||||||
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
||||||
struct debug_type *));
|
struct debug_type *, const char *));
|
||||||
static boolean debug_write_function
|
static boolean debug_write_function
|
||||||
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
||||||
const char *, enum debug_object_linkage, struct debug_function *));
|
const char *, enum debug_object_linkage, struct debug_function *));
|
||||||
@ -769,7 +772,6 @@ debug_record_function (handle, name, return_type, global, addr)
|
|||||||
|
|
||||||
info->current_function = f;
|
info->current_function = f;
|
||||||
info->current_block = b;
|
info->current_block = b;
|
||||||
info->current_lineno = NULL;
|
|
||||||
|
|
||||||
/* FIXME: If we could handle nested functions, this would be the
|
/* FIXME: If we could handle nested functions, this would be the
|
||||||
place: we would want to use a different namespace. */
|
place: we would want to use a different namespace. */
|
||||||
@ -855,7 +857,6 @@ debug_end_function (handle, addr)
|
|||||||
|
|
||||||
info->current_function = NULL;
|
info->current_function = NULL;
|
||||||
info->current_block = NULL;
|
info->current_block = NULL;
|
||||||
info->current_lineno = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -897,7 +898,6 @@ debug_start_block (handle, addr)
|
|||||||
*pb = b;
|
*pb = b;
|
||||||
|
|
||||||
info->current_block = b;
|
info->current_block = b;
|
||||||
info->current_lineno = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -931,7 +931,6 @@ debug_end_block (handle, addr)
|
|||||||
info->current_block->end = addr;
|
info->current_block->end = addr;
|
||||||
|
|
||||||
info->current_block = parent;
|
info->current_block = parent;
|
||||||
info->current_lineno = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -949,10 +948,9 @@ debug_record_line (handle, lineno, addr)
|
|||||||
struct debug_lineno *l;
|
struct debug_lineno *l;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (info->current_unit == NULL
|
if (info->current_unit == NULL)
|
||||||
|| info->current_block == NULL)
|
|
||||||
{
|
{
|
||||||
debug_error ("debug_record_line: no current block");
|
debug_error ("debug_record_line: no current unit");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,11 +969,12 @@ debug_record_line (handle, lineno, addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, then either 1) there is no current_lineno
|
/* If we get here, then either 1) there is no current_lineno
|
||||||
structure, which means this is the first line number since we got
|
structure, which means this is the first line number in this
|
||||||
to this block, 2) the current_lineno structure is for a different
|
compilation unit, 2) the current_lineno structure is for a
|
||||||
file, or 3) the current_lineno structure is full. Regardless, we
|
different file, or 3) the current_lineno structure is full.
|
||||||
want to allocate a new debug_lineno structure, put it in the
|
Regardless, we want to allocate a new debug_lineno structure, put
|
||||||
right place, and make it the new current_lineno structure. */
|
it in the right place, and make it the new current_lineno
|
||||||
|
structure. */
|
||||||
|
|
||||||
l = (struct debug_lineno *) xmalloc (sizeof *l);
|
l = (struct debug_lineno *) xmalloc (sizeof *l);
|
||||||
memset (l, 0, sizeof *l);
|
memset (l, 0, sizeof *l);
|
||||||
@ -989,18 +988,7 @@ debug_record_line (handle, lineno, addr)
|
|||||||
if (info->current_lineno != NULL)
|
if (info->current_lineno != NULL)
|
||||||
info->current_lineno->next = l;
|
info->current_lineno->next = l;
|
||||||
else
|
else
|
||||||
{
|
info->current_unit->linenos = l;
|
||||||
struct debug_lineno **pl;
|
|
||||||
|
|
||||||
/* We may be back in this block after dealing with child blocks,
|
|
||||||
which means we may have some line number information for this
|
|
||||||
block even though current_lineno was NULL. */
|
|
||||||
for (pl = &info->current_block->linenos;
|
|
||||||
*pl != NULL;
|
|
||||||
pl = &(*pl)->next)
|
|
||||||
;
|
|
||||||
*pl = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->current_lineno = l;
|
info->current_lineno = l;
|
||||||
|
|
||||||
@ -2098,6 +2086,7 @@ debug_write (handle, fns, fhandle)
|
|||||||
{
|
{
|
||||||
struct debug_file *f;
|
struct debug_file *f;
|
||||||
boolean first_file;
|
boolean first_file;
|
||||||
|
struct debug_lineno *l;
|
||||||
|
|
||||||
if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
|
if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
|
||||||
return false;
|
return false;
|
||||||
@ -2124,6 +2113,20 @@ debug_write (handle, fns, fhandle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (l = u->linenos; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < DEBUG_LINENO_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (l->linenos[i] == (unsigned long) -1)
|
||||||
|
break;
|
||||||
|
if (! (*fns->lineno) (fhandle, l->file->filename, l->linenos[i],
|
||||||
|
l->addrs[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2179,7 +2182,11 @@ debug_write_name (info, fns, fhandle, n)
|
|||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out a type. */
|
/* Write out a type. If the type is DEBUG_KIND_NAMED or
|
||||||
|
DEBUG_KIND_TAGGED, then the name argument is the name for which we
|
||||||
|
are about to call typedef or tag. If the type is anything else,
|
||||||
|
then the name argument is a tag from a DEBUG_KIND_TAGGED type which
|
||||||
|
points to this one. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
debug_write_type (info, fns, fhandle, type, name)
|
debug_write_type (info, fns, fhandle, type, name)
|
||||||
@ -2190,6 +2197,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
struct debug_name *name;
|
struct debug_name *name;
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
const char *tag;
|
||||||
|
|
||||||
/* If we have a name for this type, just output it. We only output
|
/* If we have a name for this type, just output it. We only output
|
||||||
typedef names after they have been defined. We output type tags
|
typedef names after they have been defined. We output type tags
|
||||||
@ -2214,6 +2222,15 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
name->mark = info->mark;
|
name->mark = info->mark;
|
||||||
|
|
||||||
|
tag = NULL;
|
||||||
|
if (name != NULL
|
||||||
|
&& type->kind != DEBUG_KIND_NAMED
|
||||||
|
&& type->kind != DEBUG_KIND_TAGGED)
|
||||||
|
{
|
||||||
|
assert (name->kind == DEBUG_OBJECT_TAG);
|
||||||
|
tag = name->name;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type->kind)
|
switch (type->kind)
|
||||||
{
|
{
|
||||||
case DEBUG_KIND_INDIRECT:
|
case DEBUG_KIND_INDIRECT:
|
||||||
@ -2241,7 +2258,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
}
|
}
|
||||||
type->u.kclass->mark = info->class_mark;
|
type->u.kclass->mark = info->class_mark;
|
||||||
|
|
||||||
if (! (*fns->start_struct_type) (fhandle,
|
if (! (*fns->start_struct_type) (fhandle, tag,
|
||||||
type->kind == DEBUG_KIND_STRUCT,
|
type->kind == DEBUG_KIND_STRUCT,
|
||||||
type->size))
|
type->size))
|
||||||
return false;
|
return false;
|
||||||
@ -2262,9 +2279,9 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
return (*fns->end_struct_type) (fhandle);
|
return (*fns->end_struct_type) (fhandle);
|
||||||
case DEBUG_KIND_CLASS:
|
case DEBUG_KIND_CLASS:
|
||||||
case DEBUG_KIND_UNION_CLASS:
|
case DEBUG_KIND_UNION_CLASS:
|
||||||
return debug_write_class_type (info, fns, fhandle, type);
|
return debug_write_class_type (info, fns, fhandle, type, tag);
|
||||||
case DEBUG_KIND_ENUM:
|
case DEBUG_KIND_ENUM:
|
||||||
return (*fns->enum_type) (fhandle, type->u.kenum->names,
|
return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
|
||||||
type->u.kenum->values);
|
type->u.kenum->values);
|
||||||
case DEBUG_KIND_POINTER:
|
case DEBUG_KIND_POINTER:
|
||||||
if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
|
if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
|
||||||
@ -2349,9 +2366,11 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
return false;
|
return false;
|
||||||
return (*fns->volatile_type) (fhandle);
|
return (*fns->volatile_type) (fhandle);
|
||||||
case DEBUG_KIND_NAMED:
|
case DEBUG_KIND_NAMED:
|
||||||
case DEBUG_KIND_TAGGED:
|
|
||||||
return debug_write_type (info, fns, fhandle, type->u.knamed->type,
|
return debug_write_type (info, fns, fhandle, type->u.knamed->type,
|
||||||
(struct debug_name *) NULL);
|
(struct debug_name *) NULL);
|
||||||
|
case DEBUG_KIND_TAGGED:
|
||||||
|
return debug_write_type (info, fns, fhandle, type->u.knamed->type,
|
||||||
|
type->u.knamed->name);
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
return false;
|
return false;
|
||||||
@ -2361,11 +2380,12 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||||||
/* Write out a class type. */
|
/* Write out a class type. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
debug_write_class_type (info, fns, fhandle, type)
|
debug_write_class_type (info, fns, fhandle, type, tag)
|
||||||
struct debug_handle *info;
|
struct debug_handle *info;
|
||||||
const struct debug_write_fns *fns;
|
const struct debug_write_fns *fns;
|
||||||
PTR fhandle;
|
PTR fhandle;
|
||||||
struct debug_type *type;
|
struct debug_type *type;
|
||||||
|
const char *tag;
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -2385,7 +2405,7 @@ debug_write_class_type (info, fns, fhandle, type)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (*fns->start_class_type) (fhandle,
|
if (! (*fns->start_class_type) (fhandle, tag,
|
||||||
type->kind == DEBUG_KIND_CLASS,
|
type->kind == DEBUG_KIND_CLASS,
|
||||||
type->size,
|
type->size,
|
||||||
type->u.kclass->vptrbase != NULL,
|
type->u.kclass->vptrbase != NULL,
|
||||||
@ -2533,7 +2553,6 @@ debug_write_block (info, fns, fhandle, block)
|
|||||||
struct debug_block *block;
|
struct debug_block *block;
|
||||||
{
|
{
|
||||||
struct debug_name *n;
|
struct debug_name *n;
|
||||||
struct debug_lineno *l;
|
|
||||||
struct debug_block *b;
|
struct debug_block *b;
|
||||||
|
|
||||||
if (! (*fns->start_block) (fhandle, block->start))
|
if (! (*fns->start_block) (fhandle, block->start))
|
||||||
@ -2548,20 +2567,6 @@ debug_write_block (info, fns, fhandle, block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = block->linenos; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < DEBUG_LINENO_COUNT; i++)
|
|
||||||
{
|
|
||||||
if (l->linenos[i] == (unsigned long) -1)
|
|
||||||
break;
|
|
||||||
if (! (*fns->lineno) (fhandle, l->file->filename, l->linenos[i],
|
|
||||||
l->addrs[i]))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (b = block->children; b != NULL; b = b->next)
|
for (b = block->children; b != NULL; b = b->next)
|
||||||
{
|
{
|
||||||
if (! debug_write_block (info, fns, fhandle, b))
|
if (! debug_write_block (info, fns, fhandle, b))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* debug.h -- Describe generic debugging information.
|
/* debug.h -- Describe generic debugging information.
|
||||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||||
|
|
||||||
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
||||||
@ -192,9 +192,11 @@ struct debug_write_fns
|
|||||||
/* Push a boolean type onto the type stack, given the size. */
|
/* Push a boolean type onto the type stack, given the size. */
|
||||||
boolean (*bool_type) PARAMS ((PTR, unsigned int));
|
boolean (*bool_type) PARAMS ((PTR, unsigned int));
|
||||||
|
|
||||||
/* Push an enum type onto the type stack, given a NULL terminated
|
/* Push an enum type onto the type stack, given the tag, a NULL
|
||||||
array of names and the associated values. */
|
terminated array of names and the associated values. If there is
|
||||||
boolean (*enum_type) PARAMS ((PTR, const char **, bfd_signed_vma *));
|
no tag, the tag argument will be NULL. */
|
||||||
|
boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
|
||||||
|
bfd_signed_vma *));
|
||||||
|
|
||||||
/* Pop the top type on the type stack, and push a pointer to that
|
/* Pop the top type on the type stack, and push a pointer to that
|
||||||
type onto the type stack. */
|
type onto the type stack. */
|
||||||
@ -240,8 +242,8 @@ struct debug_write_fns
|
|||||||
method). An argument type of -1 means that no argument in
|
method). An argument type of -1 means that no argument in
|
||||||
formation is available. The next type on the type stack below
|
formation is available. The next type on the type stack below
|
||||||
the domain and the argument types is the return type of the
|
the domain and the argument types is the return type of the
|
||||||
method. All these types must be poppsed, and then the method
|
method. All these types must be popped, and then the method type
|
||||||
type must be pushed. */
|
must be pushed. */
|
||||||
boolean (*method_type) PARAMS ((PTR, boolean, int));
|
boolean (*method_type) PARAMS ((PTR, boolean, int));
|
||||||
|
|
||||||
/* Pop the top type off the type stack, and push a const qualified
|
/* Pop the top type off the type stack, and push a const qualified
|
||||||
@ -254,10 +256,12 @@ struct debug_write_fns
|
|||||||
|
|
||||||
/* Start building a struct. This is followed by calls to the
|
/* Start building a struct. This is followed by calls to the
|
||||||
struct_field function, and finished by a call to the
|
struct_field function, and finished by a call to the
|
||||||
end_struct_type function. The boolean argument is true for a
|
end_struct_type function. The second argument is the tag; this
|
||||||
struct, false for a union. The unsigned int argument is the
|
will be NULL if there isn't one. The boolean argument is true
|
||||||
size. */
|
for a struct, false for a union. The unsigned int argument is
|
||||||
boolean (*start_struct_type) PARAMS ((PTR, boolean, unsigned int));
|
the size. */
|
||||||
|
boolean (*start_struct_type) PARAMS ((PTR, const char *, boolean,
|
||||||
|
unsigned int));
|
||||||
|
|
||||||
/* Add a field to the struct type currently being built. The type
|
/* Add a field to the struct type currently being built. The type
|
||||||
of the field should be popped off the type stack. The arguments
|
of the field should be popped off the type stack. The arguments
|
||||||
@ -273,19 +277,20 @@ struct debug_write_fns
|
|||||||
functions: struct_field, class_static_member, class_baseclass,
|
functions: struct_field, class_static_member, class_baseclass,
|
||||||
class_start_method, class_method_variant,
|
class_start_method, class_method_variant,
|
||||||
class_static_method_variant, and class_end_method. The class is
|
class_static_method_variant, and class_end_method. The class is
|
||||||
finished by a call to end_class_type. The boolean argument is
|
finished by a call to end_class_type. The second argument is the
|
||||||
true for a struct, false for a union. The next argument is the
|
tag; this will be NULL if there isn't one. The boolean argument
|
||||||
size. The next argument is true if there is a virtual function
|
is true for a struct, false for a union. The next argument is
|
||||||
table; if there is, the next argument is true if the virtual
|
the size. The next argument is true if there is a virtual
|
||||||
function table can be found in the type itself, and is false if
|
function table; if there is, the next argument is true if the
|
||||||
the type of the object holding the virtual function table should
|
virtual function table can be found in the type itself, and is
|
||||||
be popped from the type stack. */
|
false if the type of the object holding the virtual function
|
||||||
boolean (*start_class_type) PARAMS ((PTR, boolean, unsigned int,
|
table should be popped from the type stack. */
|
||||||
boolean, boolean));
|
boolean (*start_class_type) PARAMS ((PTR, const char *, boolean,
|
||||||
|
unsigned int, boolean, boolean));
|
||||||
|
|
||||||
/* Add a static member to the class currently being built. The
|
/* Add a static member to the class currently being built. The
|
||||||
arguments are the field name, the physical name, and the
|
arguments are the field name, the physical name, and the
|
||||||
visibility. */
|
visibility. The type must be popped off the type stack. */
|
||||||
boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
|
boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
|
||||||
enum debug_visibility));
|
enum debug_visibility));
|
||||||
|
|
||||||
@ -319,7 +324,8 @@ struct debug_write_fns
|
|||||||
|
|
||||||
/* Describe a static variant to the class method currently being
|
/* Describe a static variant to the class method currently being
|
||||||
built. The arguments are the same as for class_method_variant,
|
built. The arguments are the same as for class_method_variant,
|
||||||
except that the last two arguments are omitted. */
|
except that the last two arguments are omitted. The type of the
|
||||||
|
variant must be popped off the type stack. */
|
||||||
boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
|
boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
|
||||||
enum debug_visibility,
|
enum debug_visibility,
|
||||||
boolean, boolean));
|
boolean, boolean));
|
||||||
@ -342,7 +348,9 @@ struct debug_write_fns
|
|||||||
boolean (*typdef) PARAMS ((PTR, const char *));
|
boolean (*typdef) PARAMS ((PTR, const char *));
|
||||||
|
|
||||||
/* Pop the type stack, and declare it as a tagged struct or union or
|
/* Pop the type stack, and declare it as a tagged struct or union or
|
||||||
enum or whatever. */
|
enum or whatever. The tag passed down here is redundant, since
|
||||||
|
was also passed when enum_type, start_struct_type, or
|
||||||
|
start_class_type was called. */
|
||||||
boolean (*tag) PARAMS ((PTR, const char *));
|
boolean (*tag) PARAMS ((PTR, const char *));
|
||||||
|
|
||||||
/* This is called to record a named integer constant. */
|
/* This is called to record a named integer constant. */
|
||||||
@ -376,15 +384,15 @@ struct debug_write_fns
|
|||||||
starting address of the block. */
|
starting address of the block. */
|
||||||
boolean (*start_block) PARAMS ((PTR, bfd_vma));
|
boolean (*start_block) PARAMS ((PTR, bfd_vma));
|
||||||
|
|
||||||
/* Record line number information for the current block. */
|
|
||||||
boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
|
||||||
|
|
||||||
/* Finish writing out a block. The argument is the ending address
|
/* Finish writing out a block. The argument is the ending address
|
||||||
of the block. */
|
of the block. */
|
||||||
boolean (*end_block) PARAMS ((PTR, bfd_vma));
|
boolean (*end_block) PARAMS ((PTR, bfd_vma));
|
||||||
|
|
||||||
/* Finish writing out a function. */
|
/* Finish writing out a function. */
|
||||||
boolean (*end_function) PARAMS ((PTR));
|
boolean (*end_function) PARAMS ((PTR));
|
||||||
|
|
||||||
|
/* Record line number information for the current compilation unit. */
|
||||||
|
boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Exported functions. */
|
/* Exported functions. */
|
||||||
@ -446,8 +454,8 @@ extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
|
|||||||
|
|
||||||
extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
|
extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
|
||||||
|
|
||||||
/* Associate a line number in the current source file and function
|
/* Associate a line number in the current source file with a given
|
||||||
with a given address. */
|
address. */
|
||||||
|
|
||||||
extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
|
extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
|
||||||
|
|
||||||
|
128
binutils/prdbg.c
128
binutils/prdbg.c
@ -1,5 +1,5 @@
|
|||||||
/* prdbg.c -- Print out generic debugging information.
|
/* prdbg.c -- Print out generic debugging information.
|
||||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||||
|
|
||||||
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
||||||
@ -78,7 +78,8 @@ static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
|
|||||||
static boolean pr_float_type PARAMS ((PTR, unsigned int));
|
static boolean pr_float_type PARAMS ((PTR, unsigned int));
|
||||||
static boolean pr_complex_type PARAMS ((PTR, unsigned int));
|
static boolean pr_complex_type PARAMS ((PTR, unsigned int));
|
||||||
static boolean pr_bool_type PARAMS ((PTR, unsigned int));
|
static boolean pr_bool_type PARAMS ((PTR, unsigned int));
|
||||||
static boolean pr_enum_type PARAMS ((PTR, const char **, bfd_signed_vma *));
|
static boolean pr_enum_type
|
||||||
|
PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
|
||||||
static boolean pr_pointer_type PARAMS ((PTR));
|
static boolean pr_pointer_type PARAMS ((PTR));
|
||||||
static boolean pr_function_type PARAMS ((PTR));
|
static boolean pr_function_type PARAMS ((PTR));
|
||||||
static boolean pr_reference_type PARAMS ((PTR));
|
static boolean pr_reference_type PARAMS ((PTR));
|
||||||
@ -90,12 +91,13 @@ static boolean pr_offset_type PARAMS ((PTR));
|
|||||||
static boolean pr_method_type PARAMS ((PTR, boolean, int));
|
static boolean pr_method_type PARAMS ((PTR, boolean, int));
|
||||||
static boolean pr_const_type PARAMS ((PTR));
|
static boolean pr_const_type PARAMS ((PTR));
|
||||||
static boolean pr_volatile_type PARAMS ((PTR));
|
static boolean pr_volatile_type PARAMS ((PTR));
|
||||||
static boolean pr_start_struct_type PARAMS ((PTR, boolean, unsigned int));
|
static boolean pr_start_struct_type
|
||||||
|
PARAMS ((PTR, const char *, boolean, unsigned int));
|
||||||
static boolean pr_struct_field
|
static boolean pr_struct_field
|
||||||
PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
|
PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
|
||||||
static boolean pr_end_struct_type PARAMS ((PTR));
|
static boolean pr_end_struct_type PARAMS ((PTR));
|
||||||
static boolean pr_start_class_type
|
static boolean pr_start_class_type
|
||||||
PARAMS ((PTR, boolean, unsigned int, boolean, boolean));
|
PARAMS ((PTR, const char *, boolean, unsigned int, boolean, boolean));
|
||||||
static boolean pr_class_static_member
|
static boolean pr_class_static_member
|
||||||
PARAMS ((PTR, const char *, const char *, enum debug_visibility));
|
PARAMS ((PTR, const char *, const char *, enum debug_visibility));
|
||||||
static boolean pr_class_baseclass
|
static boolean pr_class_baseclass
|
||||||
@ -121,9 +123,9 @@ static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
|
|||||||
static boolean pr_function_parameter
|
static boolean pr_function_parameter
|
||||||
PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
|
PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
|
||||||
static boolean pr_start_block PARAMS ((PTR, bfd_vma));
|
static boolean pr_start_block PARAMS ((PTR, bfd_vma));
|
||||||
static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
|
||||||
static boolean pr_end_block PARAMS ((PTR, bfd_vma));
|
static boolean pr_end_block PARAMS ((PTR, bfd_vma));
|
||||||
static boolean pr_end_function PARAMS ((PTR));
|
static boolean pr_end_function PARAMS ((PTR));
|
||||||
|
static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||||
|
|
||||||
static const struct debug_write_fns pr_fns =
|
static const struct debug_write_fns pr_fns =
|
||||||
{
|
{
|
||||||
@ -168,9 +170,9 @@ static const struct debug_write_fns pr_fns =
|
|||||||
pr_start_function,
|
pr_start_function,
|
||||||
pr_function_parameter,
|
pr_function_parameter,
|
||||||
pr_start_block,
|
pr_start_block,
|
||||||
pr_lineno,
|
|
||||||
pr_end_block,
|
pr_end_block,
|
||||||
pr_end_function
|
pr_end_function,
|
||||||
|
pr_lineno
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Print out the generic debugging information recorded in dhandle. */
|
/* Print out the generic debugging information recorded in dhandle. */
|
||||||
@ -337,7 +339,7 @@ pop_type (info)
|
|||||||
struct pr_handle *info;
|
struct pr_handle *info;
|
||||||
{
|
{
|
||||||
struct pr_stack *o;
|
struct pr_stack *o;
|
||||||
char *ret, *s;
|
char *ret;
|
||||||
|
|
||||||
assert (info->stack != NULL);
|
assert (info->stack != NULL);
|
||||||
|
|
||||||
@ -346,10 +348,6 @@ pop_type (info)
|
|||||||
ret = o->type;
|
ret = o->type;
|
||||||
free (o);
|
free (o);
|
||||||
|
|
||||||
s = strchr (ret, '+');
|
|
||||||
if (s != NULL)
|
|
||||||
memmove (s, s + 2, strlen (s + 2) + 1);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,8 +498,9 @@ pr_bool_type (p, size)
|
|||||||
/* Push an enum type onto the type stack. */
|
/* Push an enum type onto the type stack. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
pr_enum_type (p, names, values)
|
pr_enum_type (p, tag, names, values)
|
||||||
PTR p;
|
PTR p;
|
||||||
|
const char *tag;
|
||||||
const char **names;
|
const char **names;
|
||||||
bfd_signed_vma *values;
|
bfd_signed_vma *values;
|
||||||
{
|
{
|
||||||
@ -509,8 +508,15 @@ pr_enum_type (p, names, values)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
bfd_signed_vma val;
|
bfd_signed_vma val;
|
||||||
|
|
||||||
/* The + indicates where the tag goes, if there is one. */
|
if (! push_type (info, "enum "))
|
||||||
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;
|
return false;
|
||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
@ -824,26 +830,30 @@ pr_volatile_type (p)
|
|||||||
/* Start accumulating a struct type. */
|
/* Start accumulating a struct type. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
pr_start_struct_type (p, structp, size)
|
pr_start_struct_type (p, tag, structp, size)
|
||||||
PTR p;
|
PTR p;
|
||||||
|
const char *tag;
|
||||||
boolean structp;
|
boolean structp;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
{
|
{
|
||||||
struct pr_handle *info = (struct pr_handle *) p;
|
struct pr_handle *info = (struct pr_handle *) p;
|
||||||
const char *t;
|
|
||||||
char ab[30];
|
char ab[30];
|
||||||
|
|
||||||
info->indent += 2;
|
info->indent += 2;
|
||||||
|
|
||||||
if (structp)
|
if (! push_type (info, structp ? "struct " : "union "))
|
||||||
t = "struct";
|
return false;
|
||||||
else
|
if (tag != NULL)
|
||||||
t = "union";
|
{
|
||||||
|
if (! append_type (info, tag)
|
||||||
|
|| ! append_type (info, " "))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
sprintf (ab, "%s + { /* size %u */\n", t, size);
|
sprintf (ab, "{ /* size %u */\n", size);
|
||||||
else
|
else
|
||||||
sprintf (ab, "%s + {\n", t);
|
strcpy (ab, "{\n");
|
||||||
if (! push_type (info, ab))
|
if (! append_type (info, ab))
|
||||||
return false;
|
return false;
|
||||||
info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
|
info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
|
||||||
return indent_type (info);
|
return indent_type (info);
|
||||||
@ -977,8 +987,9 @@ pr_end_struct_type (p)
|
|||||||
/* Start a class type. */
|
/* Start a class type. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
pr_start_class_type (p, structp, size, vptr, ownvptr)
|
pr_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
||||||
PTR p;
|
PTR p;
|
||||||
|
const char *tag;
|
||||||
boolean structp;
|
boolean structp;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
boolean vptr;
|
boolean vptr;
|
||||||
@ -996,8 +1007,15 @@ pr_start_class_type (p, structp, size, vptr, ownvptr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! push_type (info, structp ? "class" : "union class")
|
if (! push_type (info, structp ? "class " : "union class "))
|
||||||
|| ! append_type (info, " + {"))
|
return false;
|
||||||
|
if (tag != NULL)
|
||||||
|
{
|
||||||
|
if (! append_type (info, tag)
|
||||||
|
|| ! append_type (info, " "))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! append_type (info, "{"))
|
||||||
return false;
|
return false;
|
||||||
if (size != 0 || vptr || ownvptr)
|
if (size != 0 || vptr || ownvptr)
|
||||||
{
|
{
|
||||||
@ -1079,7 +1097,7 @@ pr_class_baseclass (p, bitpos, virtual, visibility)
|
|||||||
char *t;
|
char *t;
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
char ab[20];
|
char ab[20];
|
||||||
char *s, *n;
|
char *s, *l, *n;
|
||||||
|
|
||||||
assert (info->stack != NULL && info->stack->next != NULL);
|
assert (info->stack != NULL && info->stack->next != NULL);
|
||||||
|
|
||||||
@ -1134,27 +1152,19 @@ pr_class_baseclass (p, bitpos, virtual, visibility)
|
|||||||
|
|
||||||
/* Now the top of the stack is something like "public A / * bitpos
|
/* Now the top of the stack is something like "public A / * bitpos
|
||||||
10 * /". The next element on the stack is something like "class
|
10 * /". The next element on the stack is something like "class
|
||||||
+ { / * size 8 * /\n...". We want to substitute the top of the
|
xx { / * size 8 * /\n...". We want to substitute the top of the
|
||||||
stack in after the +. */
|
stack in before the {. */
|
||||||
s = strchr (info->stack->next->type, '+');
|
s = strchr (info->stack->next->type, '{');
|
||||||
assert (s != NULL);
|
assert (s != NULL);
|
||||||
|
--s;
|
||||||
|
|
||||||
if (s[2] != ':')
|
/* If there is already a ':', then we already have a baseclass, and
|
||||||
{
|
we must append this one after a comma. */
|
||||||
++s;
|
for (l = info->stack->next->type; l != s; l++)
|
||||||
assert (s[1] == '{');
|
if (*l == ':')
|
||||||
if (! prepend_type (info, " : "))
|
break;
|
||||||
return false;
|
if (! prepend_type (info, l == s ? " : " : ", "))
|
||||||
}
|
return false;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We already have a baseclass. Append this one after a comma. */
|
|
||||||
s = strchr (s, '{');
|
|
||||||
assert (s != NULL);
|
|
||||||
--s;
|
|
||||||
if (! prepend_type (info, ", "))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = pop_type (info);
|
t = pop_type (info);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
@ -1426,31 +1436,17 @@ pr_typdef (p, name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output a tag. */
|
/* Output a tag. The tag should already be in the string on the
|
||||||
|
stack, so all we have to do here is print it out. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
pr_tag (p, name)
|
pr_tag (p, name)
|
||||||
PTR p;
|
PTR p;
|
||||||
const char *name;
|
const char *name;
|
||||||
{
|
{
|
||||||
struct pr_handle *info = (struct pr_handle *) p;
|
struct pr_handle *info = (struct pr_handle *) p;
|
||||||
char *t, *s, *n;
|
char *t;
|
||||||
|
|
||||||
assert (info->stack != NULL);
|
|
||||||
|
|
||||||
t = info->stack->type;
|
|
||||||
|
|
||||||
s = strchr (t, '+');
|
|
||||||
assert (s != NULL);
|
|
||||||
|
|
||||||
n = (char *) xmalloc (strlen (t) + strlen (name));
|
|
||||||
|
|
||||||
memcpy (n, t, s - t);
|
|
||||||
strcpy (n + (s - t), name);
|
|
||||||
strcat (n, s + 1);
|
|
||||||
|
|
||||||
free (t);
|
|
||||||
info->stack->type = n;
|
|
||||||
|
|
||||||
t = pop_type (info);
|
t = pop_type (info);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
@ -1459,7 +1455,7 @@ pr_tag (p, name)
|
|||||||
indent (info);
|
indent (info);
|
||||||
fprintf (info->f, "%s;\n", t);
|
fprintf (info->f, "%s;\n", t);
|
||||||
|
|
||||||
free (n);
|
free (t);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user