From 63840d265c1d65f4d4af7436b175ae12cf2d0a23 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 8 Jan 1996 23:18:51 +0000 Subject: [PATCH] * 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. --- binutils/debug.c | 111 ++++++++++++++++++++++++----------------------- binutils/debug.h | 62 +++++++++++++++------------ binutils/prdbg.c | 128 +++++++++++++++++++++++++++---------------------------- 3 files changed, 155 insertions(+), 146 deletions(-) diff --git a/binutils/debug.c b/binutils/debug.c index 18eb529..239abdb 100644 --- a/binutils/debug.c +++ b/binutils/debug.c @@ -1,5 +1,5 @@ /* 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 . This file is part of GNU Binutils. @@ -48,7 +48,7 @@ struct debug_handle struct debug_function *current_function; /* The 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; /* Mark. This is used by debug_write. */ unsigned int mark; @@ -66,6 +66,10 @@ struct debug_unit file is always the main one, and that is where the main file name is stored. */ 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. */ @@ -394,12 +398,11 @@ struct debug_block bfd_vma end; /* Local variables. */ struct debug_namespace *locals; - /* Line number information. */ - struct debug_lineno *linenos; }; -/* Line number information we keep for a function. FIXME: This - structure is easy to create, but can be very space inefficient. */ +/* Line number information we keep for a compilation unit. FIXME: + This structure is easy to create, but can be very space + inefficient. */ struct debug_lineno { @@ -511,7 +514,7 @@ static boolean debug_write_type struct debug_type *, struct debug_name *)); static boolean debug_write_class_type PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_type *)); + struct debug_type *, const char *)); static boolean debug_write_function PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, 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_block = b; - info->current_lineno = NULL; /* FIXME: If we could handle nested functions, this would be the place: we would want to use a different namespace. */ @@ -855,7 +857,6 @@ debug_end_function (handle, addr) info->current_function = NULL; info->current_block = NULL; - info->current_lineno = NULL; return true; } @@ -897,7 +898,6 @@ debug_start_block (handle, addr) *pb = b; info->current_block = b; - info->current_lineno = NULL; return true; } @@ -931,7 +931,6 @@ debug_end_block (handle, addr) info->current_block->end = addr; info->current_block = parent; - info->current_lineno = NULL; return true; } @@ -949,10 +948,9 @@ debug_record_line (handle, lineno, addr) struct debug_lineno *l; unsigned int i; - if (info->current_unit == NULL - || info->current_block == NULL) + if (info->current_unit == NULL) { - debug_error ("debug_record_line: no current block"); + debug_error ("debug_record_line: no current unit"); return false; } @@ -971,11 +969,12 @@ debug_record_line (handle, lineno, addr) } /* If we get here, then either 1) there is no current_lineno - structure, which means this is the first line number since we got - to this block, 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. */ + 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); @@ -989,18 +988,7 @@ debug_record_line (handle, lineno, addr) if (info->current_lineno != NULL) info->current_lineno->next = l; else - { - 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_unit->linenos = l; info->current_lineno = l; @@ -2098,6 +2086,7 @@ debug_write (handle, fns, fhandle) { struct debug_file *f; boolean first_file; + struct debug_lineno *l; if (! (*fns->start_compilation_unit) (fhandle, u->files->filename)) 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; @@ -2179,7 +2182,11 @@ debug_write_name (info, fns, fhandle, n) /*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 debug_write_type (info, fns, fhandle, type, name) @@ -2190,6 +2197,7 @@ debug_write_type (info, fns, fhandle, type, name) struct debug_name *name; { unsigned int i; + const char *tag; /* 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 @@ -2214,6 +2222,15 @@ debug_write_type (info, fns, fhandle, type, name) if (name != NULL) 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) { case DEBUG_KIND_INDIRECT: @@ -2241,7 +2258,7 @@ debug_write_type (info, fns, fhandle, type, name) } 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->size)) return false; @@ -2262,9 +2279,9 @@ debug_write_type (info, fns, fhandle, type, name) return (*fns->end_struct_type) (fhandle); case DEBUG_KIND_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: - return (*fns->enum_type) (fhandle, type->u.kenum->names, + return (*fns->enum_type) (fhandle, tag, type->u.kenum->names, type->u.kenum->values); case DEBUG_KIND_POINTER: 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 (*fns->volatile_type) (fhandle); case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: return debug_write_type (info, fns, fhandle, type->u.knamed->type, (struct debug_name *) NULL); + case DEBUG_KIND_TAGGED: + return debug_write_type (info, fns, fhandle, type->u.knamed->type, + type->u.knamed->name); default: abort (); return false; @@ -2361,11 +2380,12 @@ debug_write_type (info, fns, fhandle, type, name) /* Write out a class type. */ static boolean -debug_write_class_type (info, fns, fhandle, type) +debug_write_class_type (info, fns, fhandle, type, tag) struct debug_handle *info; const struct debug_write_fns *fns; PTR fhandle; struct debug_type *type; + const char *tag; { unsigned int i; @@ -2385,7 +2405,7 @@ debug_write_class_type (info, fns, fhandle, type) return false; } - if (! (*fns->start_class_type) (fhandle, + if (! (*fns->start_class_type) (fhandle, tag, type->kind == DEBUG_KIND_CLASS, type->size, type->u.kclass->vptrbase != NULL, @@ -2533,7 +2553,6 @@ debug_write_block (info, fns, fhandle, block) struct debug_block *block; { struct debug_name *n; - struct debug_lineno *l; struct debug_block *b; 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) { if (! debug_write_block (info, fns, fhandle, b)) diff --git a/binutils/debug.h b/binutils/debug.h index 6682e47..0fed153 100644 --- a/binutils/debug.h +++ b/binutils/debug.h @@ -1,5 +1,5 @@ /* 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 . 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. */ boolean (*bool_type) PARAMS ((PTR, unsigned int)); - /* Push an enum type onto the type stack, given a NULL terminated - array of names and the associated values. */ - boolean (*enum_type) PARAMS ((PTR, const char **, bfd_signed_vma *)); + /* Push an enum type onto the type stack, given the tag, a NULL + terminated array of names and the associated values. If there is + 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 type onto the type stack. */ @@ -240,8 +242,8 @@ struct debug_write_fns method). An argument type of -1 means that no argument in formation is available. The next type on the type stack below the domain and the argument types is the return type of the - method. All these types must be poppsed, and then the method - type must be pushed. */ + method. All these types must be popped, and then the method type + must be pushed. */ boolean (*method_type) PARAMS ((PTR, boolean, int)); /* 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 struct_field function, and finished by a call to the - end_struct_type function. The boolean argument is true for a - struct, false for a union. The unsigned int argument is the - size. */ - boolean (*start_struct_type) PARAMS ((PTR, boolean, unsigned int)); + end_struct_type function. The second argument is the tag; this + will be NULL if there isn't one. The boolean argument is true + for a struct, false for a union. The unsigned int argument is + 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 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, class_start_method, class_method_variant, class_static_method_variant, and class_end_method. The class is - finished by a call to end_class_type. The boolean argument is - true for a struct, false for a union. The next argument is the - size. The next argument is true if there is a virtual function - table; if there is, the next argument is true if the virtual - function table can be found in the type itself, and is false if - the type of the object holding the virtual function table should - be popped from the type stack. */ - boolean (*start_class_type) PARAMS ((PTR, boolean, unsigned int, - boolean, boolean)); + finished by a call to end_class_type. The second argument is the + tag; this will be NULL if there isn't one. The boolean argument + is true for a struct, false for a union. The next argument is + the size. The next argument is true if there is a virtual + function table; if there is, the next argument is true if the + virtual function table can be found in the type itself, and is + false if the type of the object holding the virtual function + table should be popped from the type stack. */ + boolean (*start_class_type) PARAMS ((PTR, const char *, boolean, + unsigned int, boolean, boolean)); /* Add a static member to the class currently being built. 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 *, enum debug_visibility)); @@ -319,7 +324,8 @@ struct debug_write_fns /* Describe a static variant to the class method currently being 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 *, enum debug_visibility, boolean, boolean)); @@ -342,7 +348,9 @@ struct debug_write_fns boolean (*typdef) PARAMS ((PTR, const char *)); /* 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 *)); /* This is called to record a named integer constant. */ @@ -376,15 +384,15 @@ struct debug_write_fns starting address of the block. */ 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 of the block. */ boolean (*end_block) PARAMS ((PTR, bfd_vma)); /* Finish writing out a function. */ 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. */ @@ -446,8 +454,8 @@ extern boolean debug_start_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 - with a given address. */ +/* Associate a line number in the current source file with a given + address. */ extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma)); diff --git a/binutils/prdbg.c b/binutils/prdbg.c index c8c2bab..c41d60c 100644 --- a/binutils/prdbg.c +++ b/binutils/prdbg.c @@ -1,5 +1,5 @@ /* 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 . 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_complex_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_function_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_const_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 PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); static boolean pr_end_struct_type PARAMS ((PTR)); 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 PARAMS ((PTR, const char *, const char *, enum debug_visibility)); static boolean pr_class_baseclass @@ -121,9 +123,9 @@ static boolean pr_start_function PARAMS ((PTR, const char *, boolean)); static boolean pr_function_parameter PARAMS ((PTR, const char *, enum debug_parm_kind, 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_function PARAMS ((PTR)); +static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma)); static const struct debug_write_fns pr_fns = { @@ -168,9 +170,9 @@ static const struct debug_write_fns pr_fns = pr_start_function, pr_function_parameter, pr_start_block, - pr_lineno, pr_end_block, - pr_end_function + pr_end_function, + pr_lineno }; /* Print out the generic debugging information recorded in dhandle. */ @@ -337,7 +339,7 @@ pop_type (info) struct pr_handle *info; { struct pr_stack *o; - char *ret, *s; + char *ret; assert (info->stack != NULL); @@ -346,10 +348,6 @@ pop_type (info) ret = o->type; free (o); - s = strchr (ret, '+'); - if (s != NULL) - memmove (s, s + 2, strlen (s + 2) + 1); - return ret; } @@ -500,8 +498,9 @@ pr_bool_type (p, size) /* Push an enum type onto the type stack. */ static boolean -pr_enum_type (p, names, values) +pr_enum_type (p, tag, names, values) PTR p; + const char *tag; const char **names; bfd_signed_vma *values; { @@ -509,8 +508,15 @@ pr_enum_type (p, names, values) unsigned int i; 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; val = 0; @@ -824,26 +830,30 @@ pr_volatile_type (p) /* Start accumulating a struct type. */ static boolean -pr_start_struct_type (p, structp, size) +pr_start_struct_type (p, tag, structp, size) PTR p; + const char *tag; boolean structp; unsigned int size; { struct pr_handle *info = (struct pr_handle *) p; - const char *t; char ab[30]; info->indent += 2; - if (structp) - t = "struct"; - else - t = "union"; + if (! push_type (info, structp ? "struct " : "union ")) + return false; + if (tag != NULL) + { + if (! append_type (info, tag) + || ! append_type (info, " ")) + return false; + } if (size != 0) - sprintf (ab, "%s + { /* size %u */\n", t, size); + sprintf (ab, "{ /* size %u */\n", size); else - sprintf (ab, "%s + {\n", t); - if (! push_type (info, ab)) + strcpy (ab, "{\n"); + if (! append_type (info, ab)) return false; info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; return indent_type (info); @@ -977,8 +987,9 @@ pr_end_struct_type (p) /* Start a class type. */ static boolean -pr_start_class_type (p, structp, size, vptr, ownvptr) +pr_start_class_type (p, tag, structp, size, vptr, ownvptr) PTR p; + const char *tag; boolean structp; unsigned int size; boolean vptr; @@ -996,8 +1007,15 @@ pr_start_class_type (p, structp, size, vptr, ownvptr) return false; } - if (! push_type (info, structp ? "class" : "union class") - || ! append_type (info, " + {")) + if (! push_type (info, structp ? "class " : "union class ")) + return false; + if (tag != NULL) + { + if (! append_type (info, tag) + || ! append_type (info, " ")) + return false; + } + if (! append_type (info, "{")) return false; if (size != 0 || vptr || ownvptr) { @@ -1079,7 +1097,7 @@ pr_class_baseclass (p, bitpos, virtual, visibility) char *t; const char *prefix; char ab[20]; - char *s, *n; + char *s, *l, *n; 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 10 * /". The next element on the stack is something like "class - + { / * size 8 * /\n...". We want to substitute the top of the - stack in after the +. */ - s = strchr (info->stack->next->type, '+'); + xx { / * size 8 * /\n...". We want to substitute the top of the + stack in before the {. */ + s = strchr (info->stack->next->type, '{'); assert (s != NULL); + --s; - if (s[2] != ':') - { - ++s; - assert (s[1] == '{'); - if (! prepend_type (info, " : ")) - 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; - } + /* If there is already a ':', then we already have a baseclass, and + we must append this one after a comma. */ + for (l = info->stack->next->type; l != s; l++) + if (*l == ':') + break; + if (! prepend_type (info, l == s ? " : " : ", ")) + return false; t = pop_type (info); if (t == NULL) @@ -1426,31 +1436,17 @@ pr_typdef (p, name) 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 pr_tag (p, name) PTR p; const char *name; { struct pr_handle *info = (struct pr_handle *) p; - char *t, *s, *n; - - 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; + char *t; t = pop_type (info); if (t == NULL) @@ -1459,7 +1455,7 @@ pr_tag (p, name) indent (info); fprintf (info->f, "%s;\n", t); - free (n); + free (t); return true; } -- 2.7.4