From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12213 invoked by alias); 21 Jul 2003 19:32:32 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 12201 invoked from network); 21 Jul 2003 19:32:28 -0000 Received: from unknown (HELO violeta.inti.gov.ar) (200.10.161.35) by sources.redhat.com with SMTP; 21 Jul 2003 19:32:28 -0000 Received: from nav.inti.gov.ar ([200.10.161.45]) by violeta.inti.gov.ar with smtp (Exim 4.12) id 19egOZ-0001l6-01 for binutils@sources.redhat.com; Mon, 21 Jul 2003 16:32:27 -0300 Received: from inti.gov.ar ([200.10.161.86]) by nav.inti.gov.ar (NAVGW 2.5.1.16) with SMTP id M2003072116345917569 ; Mon, 21 Jul 2003 16:34:59 -0300 Message-ID: <3F1C3FC9.5010701@inti.gov.ar> Date: Mon, 21 Jul 2003 19:32:00 -0000 From: Salvador Eduardo Tropea User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: es-ar, es, en MIME-Version: 1.0 To: Nick Clifton CC: binutils@sources.redhat.com Subject: Re: RFC objdump new feature to generate debug info using ctags style References: <3EB293A4.30103@inti.gov.ar> In-Reply-To: Content-Type: multipart/mixed; boundary="------------090403030008050308010708" X-SW-Source: 2003-07/txt/msg00393.txt.bz2 This is a multi-part message in MIME format. --------------090403030008050308010708 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 2031 This is from a couple of months ago: On 12/05/03 08:17 Nick Clifton wrote: >>I managed to modify prdbg.c to print the information in a format >>compatible with Exuberant Ctags (plus some fields not available in >>E.Ctags). >> >> > >Thanks very much for submitting this patch. > >Since this patch adds a new feature to objdump it definitely needs a >copyright assignment before it can be accepted. > Ok, I think this is done. I received the papers, signed them, sent it back to FSF and got an e-mail confirmation (no regular letter, just e-mail). Can you check if all is ok? >If you are willing >to make such an assignment please fill out the email form attached >below and send it off the FSF. The process will take a while but it >should be worth it as they we can consider accepting your patches. > >As for the patch itself, there are a couple of issues: > > * It needs a ChangeLog entry. > Added. > * Since you are adding a new feature it needs to be documented. > Please extend the patch to include changes to > binutils/doc/binutils.texi and binutils/NEWS. > Also added. > * Please try to follow the GNU coding standard. (In the patch there > are several comments that ought to be reformatted to include a > terminating period followed by two spaces. Also there are places > where there is no space between a function name and its opening > parenthesis). > Ok, I checked manually and with a diff between the file and the "indent" output. I followed indent suggestions for all but things that the original author did in a different way. The most important differences is between: if (! condition) and if (!condition) Attached is the output of cvs diff -u. Regards, SET -- Salvador Eduardo Tropea (SET). (Electronics Engineer) Visit my home page: http://welcome.to/SetSoft or http://www.geocities.com/SiliconValley/Vista/6552/ Alternative e-mail: set@computer.org set@ieee.org Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013 --------------090403030008050308010708 Content-Type: text/plain; name="debug-as-tags.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="debug-as-tags.diff" Content-length: 37776 Index: ChangeLog =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/ChangeLog,v retrieving revision 1.670 diff -u -r1.670 ChangeLog --- ChangeLog 18 Jul 2003 11:34:41 -0000 1.670 +++ ChangeLog 21 Jul 2003 19:31:51 -0000 @@ -1,3 +1,12 @@ +2003-07-21 Salvador Eduardo Tropea + + * objdump.c: New command line option --debugging-tags. + * doc/binutils.texi: Document new command line option. + * prdbg.c: Code to print the debug info as tags compatible=20 + with ctags. + * budbg.h: Adjust prototype. + * NEWS: Mention new switch +=20=20=20=20=20=20=20=20 2003-07-18 Nick Clifton =20 * objdump.c (main) :Accept multiple -M switch. Index: budbg.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/budbg.h,v retrieving revision 1.3 diff -u -r1.3 budbg.h --- budbg.h 30 Nov 2002 08:39:41 -0000 1.3 +++ budbg.h 21 Jul 2003 19:31:51 -0000 @@ -32,8 +32,8 @@ /* Routine used to print generic debugging information. */ =20 extern bfd_boolean print_debugging_info - PARAMS ((FILE *, PTR)); - + PARAMS ((FILE *, PTR, bfd *, asymbol **, PTR, bfd_boolean)); +=20=20 /* Routines used to read and write stabs information. */ =20 extern PTR start_stab Index: objdump.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/objdump.c,v retrieving revision 1.69 diff -u -r1.69 objdump.c --- objdump.c 18 Jul 2003 11:34:41 -0000 1.69 +++ objdump.c 21 Jul 2003 19:31:51 -0000 @@ -74,6 +74,7 @@ static bfd_vma start_address =3D (bfd_vma) -1; /* --start-address */ static bfd_vma stop_address =3D (bfd_vma) -1; /* --stop-address */ static int dump_debugging; /* --debugging */ +static int dump_debugging_tags; /* --debugging-tags */ static bfd_vma adjust_section_vma =3D 0; /* --adjust-vma */ static int file_start_context =3D 0; /* --file-start-context */ =20 @@ -208,6 +209,7 @@ -S, --source Intermix source code with disassembly\n\ -s, --full-contents Display the full contents of all sections reque= sted\n\ -g, --debugging Display debug information in object file\n\ + -e, --debugging-tags Display debug information using ctags style\n\ -G, --stabs Display (in raw form) any STABS info in the fil= e\n\ -t, --syms Display the contents of the symbol table(s)\n\ -T, --dynamic-syms Display the contents of the dynamic symbol tabl= e\n\ @@ -266,6 +268,7 @@ {"architecture", required_argument, NULL, 'm'}, {"archive-headers", no_argument, NULL, 'a'}, {"debugging", no_argument, NULL, 'g'}, + {"debugging-tags", no_argument, NULL, 'e'}, {"demangle", optional_argument, NULL, 'C'}, {"disassemble", no_argument, NULL, 'd'}, {"disassemble-all", no_argument, NULL, 'D'}, @@ -2068,15 +2071,17 @@ } } =20 - printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), - abfd->xvec->name); + if (! dump_debugging_tags) + printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), + abfd->xvec->name); if (dump_ar_hdrs) print_arelt_descr (stdout, abfd, TRUE); if (dump_file_header) dump_bfd_header (abfd); if (dump_private_headers) dump_bfd_private_header (abfd); - putchar ('\n'); + if (! dump_debugging_tags) + putchar ('\n'); if (dump_section_headers) dump_headers (abfd); =20 @@ -2106,7 +2111,8 @@ dhandle =3D read_debugging_info (abfd, syms, symcount); if (dhandle !=3D NULL) { - if (! print_debugging_info (stdout, dhandle)) + if (! print_debugging_info (stdout, dhandle, abfd, syms, demangle, + dump_debugging_tags ? TRUE : FALSE)) { non_fatal (_("%s: printing debugging information failed"), bfd_get_filename (abfd)); @@ -2648,7 +2654,7 @@ bfd_init (); set_default_bfd_target (); =20 - while ((c =3D getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zg= G", + while ((c =3D getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zg= eG", long_options, (int *) 0)) !=3D EOF) { @@ -2783,6 +2789,12 @@ break; case 'g': dump_debugging =3D 1; + seenflag =3D TRUE; + break; + case 'e': + dump_debugging =3D 1; + dump_debugging_tags =3D 1; + do_demangle =3D TRUE; seenflag =3D TRUE; break; case 'G': Index: prdbg.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/prdbg.c,v retrieving revision 1.6 diff -u -r1.6 prdbg.c --- prdbg.c 30 Nov 2002 08:39:41 -0000 1.6 +++ prdbg.c 21 Jul 2003 19:31:52 -0000 @@ -1,6 +1,7 @@ /* prdbg.c -- Print out generic debugging information. - Copyright 1995, 1996, 2002 Free Software Foundation, Inc. + Copyright 1995, 1996, 2002, 2003 Free Software Foundation, Inc. Written by Ian Lance Taylor . + Tags style generation written by Salvador E. Tropea . =20 This file is part of GNU Binutils. =20 @@ -43,6 +44,15 @@ struct pr_stack *stack; /* Parameter number we are about to output. */ int parameter; + /* The following are used only by the tags code (tg_). */ + /* Name of the file we are using. */ + char *filename; + /* The BFD. */ + bfd *abfd; + /* The symbols table for this BFD. */ + asymbol **syms; + /* Pointer to a function to demangle symbols. */ + char *(*demangler) PARAMS ((bfd *, const char *)); }; =20 /* The type stack. */ @@ -57,6 +67,13 @@ enum debug_visibility visibility; /* Name of the current method we are handling. */ const char *method; + /* The following are used only by the tags code (tg_). */ + /* Type for the container (struct, union, class, union class). */ + const char *flavor; + /* A comma separated list of parent classes. */ + char *parents; + /* How many parents contains parents. */ + int num_parents; }; =20 static void indent @@ -67,6 +84,8 @@ PARAMS ((struct pr_handle *, const char *)); static bfd_boolean append_type PARAMS ((struct pr_handle *, const char *)); +static bfd_boolean append_parent + PARAMS ((struct pr_handle *, const char *)); static bfd_boolean substitute_type PARAMS ((struct pr_handle *, const char *)); static bfd_boolean indent_type @@ -77,6 +96,16 @@ PARAMS ((bfd_vma, char *, bfd_boolean, bfd_boolean)); static bfd_boolean pr_fix_visibility PARAMS ((struct pr_handle *, enum debug_visibility)); +/* Only used by tg_ code. */ +static bfd_boolean tg_fix_visibility + PARAMS ((struct pr_handle *, enum debug_visibility)); +static void find_address_in_section + PARAMS ((bfd *abfd, asection *section, PTR data)); +static void translate_addresses + PARAMS ((bfd *abfd, char *addr_hex, FILE *f, asymbol **syms)); +static const char *visibility_name + PARAMS ((enum debug_visibility visibility)); + static bfd_boolean pr_start_compilation_unit PARAMS ((PTR, const char *)); static bfd_boolean pr_start_source @@ -169,6 +198,63 @@ static bfd_boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma)); =20 +/* Tags style replacements. */ +static bfd_boolean tg_start_compilation_unit + PARAMS ((PTR, const char *)); +static bfd_boolean tg_start_source + PARAMS ((PTR, const char *)); +static bfd_boolean tg_enum_type + PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); +static bfd_boolean tg_start_struct_type + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int)); +static bfd_boolean pr_struct_field + PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); +static bfd_boolean tg_struct_field + PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); +static bfd_boolean tg_struct_field + PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); +static bfd_boolean tg_end_struct_type + PARAMS ((PTR)); +static bfd_boolean tg_start_class_type + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, + bfd_boolean, bfd_boolean)); +static bfd_boolean tg_class_static_member + PARAMS ((PTR, const char *, const char *, enum debug_visibility)); +static bfd_boolean tg_class_baseclass + PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility)); +static bfd_boolean tg_class_method_variant + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_bool= ean, + bfd_vma, bfd_boolean)); +static bfd_boolean tg_class_static_method_variant + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, + bfd_boolean)); +static bfd_boolean tg_end_class_type + PARAMS ((PTR)); +static bfd_boolean tg_tag_type + PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); +static bfd_boolean tg_typdef + PARAMS ((PTR, const char *)); +static bfd_boolean tg_tag + PARAMS ((PTR, const char *)); +static bfd_boolean tg_int_constant + PARAMS ((PTR, const char *, bfd_vma)); +static bfd_boolean tg_float_constant + PARAMS ((PTR, const char *, double)); +static bfd_boolean tg_typed_constant + PARAMS ((PTR, const char *, bfd_vma)); +static bfd_boolean tg_variable + PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); +static bfd_boolean tg_start_function + PARAMS ((PTR, const char *, bfd_boolean)); +static bfd_boolean tg_function_parameter + PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); +static bfd_boolean tg_start_block + PARAMS ((PTR, bfd_vma)); +static bfd_boolean tg_end_block + PARAMS ((PTR, bfd_vma)); +static bfd_boolean tg_lineno + PARAMS ((PTR, const char *, unsigned long, bfd_vma)); +=0C static const struct debug_write_fns pr_fns =3D { pr_start_compilation_unit, @@ -217,12 +303,64 @@ pr_lineno }; =0C +static const struct debug_write_fns tg_fns =3D +{ + tg_start_compilation_unit, + tg_start_source, + pr_empty_type, /* Same, push_type. */ + pr_void_type, /* Same, push_type. */ + pr_int_type, /* Same, push_type. */ + pr_float_type, /* Same, push_type. */ + pr_complex_type, /* Same, push_type. */ + pr_bool_type, /* Same, push_type. */ + tg_enum_type, + pr_pointer_type, /* Same, changes to pointer. */ + pr_function_type, /* Same, push_type. */ + pr_reference_type, /* Same, changes to reference. */ + pr_range_type, /* FIXME: What's that?. */ + pr_array_type, /* Same, push_type. */ + pr_set_type, /* FIXME: What's that?. */ + pr_offset_type, /* FIXME: What's that?. */ + pr_method_type, /* Same. */ + pr_const_type, /* Same, changes to const. */ + pr_volatile_type, /* Same, changes to volatile. */ + tg_start_struct_type, + tg_struct_field, + tg_end_struct_type, + tg_start_class_type, + tg_class_static_member, + tg_class_baseclass, + pr_class_start_method, /* Same, remmembers that's a method. */ + tg_class_method_variant, + tg_class_static_method_variant, + pr_class_end_method, /* Same, forgets that's a method. */ + tg_end_class_type, + pr_typedef_type, /* Same, just push type. */ + tg_tag_type, + tg_typdef, + tg_tag, + tg_int_constant, /* Untested. */ + tg_float_constant, /* Untested. */ + tg_typed_constant, /* Untested. */ + tg_variable, + tg_start_function, + tg_function_parameter, + tg_start_block, + tg_end_block, + pr_end_function, /* Same, does nothing. */ + tg_lineno +}; +=0C /* Print out the generic debugging information recorded in dhandle. */ =20 bfd_boolean -print_debugging_info (f, dhandle) +print_debugging_info (f, dhandle, abfd, syms, demangler, as_tags) FILE *f; PTR dhandle; + bfd *abfd; + asymbol **syms; + PTR demangler; + bfd_boolean as_tags; { struct pr_handle info; =20 @@ -230,8 +368,23 @@ info.indent =3D 0; info.stack =3D NULL; info.parameter =3D 0; + info.filename =3D NULL; + info.abfd =3D abfd; + info.syms =3D syms; + info.demangler =3D demangler; + + if (as_tags) + { + fputs("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f); + fputs("!_TAG_FILE_SORTED\t0\t/0=3Dunsorted, 1=3Dsorted/\n", f); + fputs + ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t= //\n", + f); + fputs("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f); + } =20 - return debug_write (dhandle, &pr_fns, (PTR) &info); + return as_tags ? debug_write (dhandle, &tg_fns, (PTR) & info) + : debug_write (dhandle, &pr_fns, (PTR) & info); } =0C /* Indent to the current indentation level. */ @@ -311,6 +464,28 @@ return TRUE; } =20 +/* Append a string to the parents on the top of the type stack. */ + +static bfd_boolean +append_parent (info, s) + struct pr_handle *info; + const char *s; +{ + unsigned int len; + + if (s =3D=3D NULL) + return FALSE; + + assert (info->stack !=3D NULL); + + len =3D info->stack->parents ? strlen (info->stack->parents) : 0; + info->stack->parents =3D (char *) xrealloc (info->stack->parents, + len + strlen (s) + 1); + strcpy (info->stack->parents + len, s); + + return TRUE; +} + /* We use an underscore to indicate where the name should go in a type string. This function substitutes a string for the underscore. If there is no underscore, the name follows the type. */ @@ -1893,4 +2068,997 @@ PTR p ATTRIBUTE_UNUSED; { return TRUE; +} +=0C +/* Tags style generation functions start here. */ + +/* Variables for address to line translation. */ +static bfd_vma pc; +static const char *filename; +static const char *functionname; +static unsigned int line; +static bfd_boolean found; + +/* Look for an address in a section. This is called via + bfd_map_over_sections. */ + +static void +find_address_in_section (abfd, section, data) + bfd *abfd; + asection *section; + PTR data; +{ + bfd_vma vma; + bfd_size_type size; + asymbol **syms =3D (asymbol **) data; + + if (found) + return; + + if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) =3D=3D 0) + return; + + vma =3D bfd_get_section_vma (abfd, section); + if (pc < vma) + return; + + size =3D bfd_get_section_size_before_reloc (section); + if (pc >=3D vma + size) + return; + + found =3D bfd_find_nearest_line (abfd, section, syms, pc - vma, + &filename, &functionname, &line); +} + +static void +translate_addresses (abfd, addr_hex, f, syms) + bfd *abfd; + char *addr_hex; + FILE *f; + asymbol **syms; +{ + pc =3D bfd_scan_vma (addr_hex, NULL, 16); + found =3D FALSE; + bfd_map_over_sections (abfd, find_address_in_section, syms); + + if (! found) + fprintf (f, "??"); + else + fprintf (f, "%u", line); +} + +/* Start a new compilation unit. */ + +static bfd_boolean +tg_start_compilation_unit (p, filename) + PTR p; + const char *filename ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + + fprintf (stderr, "New compilation unit: %s\n", filename); + + free (info->filename); + /* Should it be relative? best way to do it here?. */ + info->filename =3D strdup (filename); + + return TRUE; +} + +/* Start a source file within a compilation unit. */ + +static bfd_boolean +tg_start_source (p, filename) + PTR p; + const char *filename; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + + free (info->filename); + /* Should it be relative? best way to do it here?. */ + info->filename =3D strdup (filename); + + return TRUE; +} + +/* Push an enum type onto the type stack. */ + +static bfd_boolean +tg_enum_type (p, tag, names, values) + PTR p; + const char *tag; + const char **names; + bfd_signed_vma *values; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + unsigned int i; + const char *name; + char ab[20]; + + if (! pr_enum_type (p, tag, names, values)) + return FALSE; + + name =3D tag ? tag : "unknown"; + /* Generate an entry for the enum. */ + if (tag) + { + fprintf(info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag, + info->filename, info->stack->type); + } + /* Generate entries for the values. */ + if (names !=3D NULL) + { + for (i =3D 0; names[i] !=3D NULL; i++) + { + print_vma (values[i], ab, FALSE, FALSE); + fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n", + names[i], info->filename, name, ab); + } + } + + return TRUE; +} + +/* Start accumulating a struct type. */ + +static bfd_boolean +tg_start_struct_type (p, tag, id, structp, size) + PTR p; + const char *tag; + unsigned int id; + bfd_boolean structp; + unsigned int size ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + const char *name; + char idbuf[20]; + + if (tag !=3D NULL) + { + name =3D tag; + } + else + { + name =3D idbuf; + sprintf (idbuf, "%%anon%u", id); + } + if (! push_type (info, name)) + return FALSE; + info->stack->flavor =3D structp ? "struct" : "union"; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename, + info->stack->flavor[0]); + + info->stack->visibility =3D DEBUG_VISIBILITY_PUBLIC; + + return indent_type (info); +} + +/* Output the visibility of a field in a struct. */ + +static bfd_boolean +tg_fix_visibility (info, visibility) + struct pr_handle *info; + enum debug_visibility visibility; +{ + assert (info->stack !=3D NULL); + + if (info->stack->visibility =3D=3D visibility) + return TRUE; + + assert (info->stack->visibility !=3D DEBUG_VISIBILITY_IGNORE); + + info->stack->visibility =3D visibility; + + return TRUE; +} + +/* Add a field to a struct type. */ + +static bfd_boolean +tg_struct_field (p, name, bitpos, bitsize, visibility) + PTR p; + const char *name; + bfd_vma bitpos ATTRIBUTE_UNUSED; + bfd_vma bitsize ATTRIBUTE_UNUSED; + enum debug_visibility visibility; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + if (! tg_fix_visibility (info, visibility)) + return FALSE; + + /* It happends, a bug? */ + if (! name[0]) + return TRUE; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n", + name, info->filename, t, info->stack->flavor, info->stack->type, + visibility_name (visibility)); + + return TRUE; +} + +/* Finish a struct type. */ + +static bfd_boolean +tg_end_struct_type (p) + PTR p ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + assert (info->stack !=3D NULL); + + return TRUE; +} + +/* Start a class type. */ + +static bfd_boolean +tg_start_class_type (p, tag, id, structp, size, vptr, ownvptr) + PTR p; + const char *tag; + unsigned int id; + bfd_boolean structp; + unsigned int size; + bfd_boolean vptr; + bfd_boolean ownvptr; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *tv =3D NULL; + const char *name; + + info->indent +=3D 2; + + if (vptr && ! ownvptr) + { + tv =3D pop_type (info); + if (tv =3D=3D NULL) + return FALSE; + } + + if (tag !=3D NULL) + { + name =3D tag; + } + else + { + char idbuf[20]; + + sprintf (idbuf, "%%anon%u", id); + name =3D idbuf; + } + if (! push_type (info, name)) + return FALSE; + info->stack->flavor =3D structp ? "class" : "union class"; + info->stack->parents =3D NULL; + info->stack->num_parents =3D 0; + + if (size !=3D 0 || vptr || ownvptr || tag !=3D NULL) + { + if (vptr) + { + if (! append_type (info, " vtable ")) + return FALSE; + if (ownvptr) + { + if (! append_type (info, "self ")) + return FALSE; + } + else + { + if (! append_type (info, tv) + || ! append_type (info, " ")) + return FALSE; + } + } + } + + info->stack->visibility =3D DEBUG_VISIBILITY_PRIVATE; + + return TRUE; +} + +/* Add a static member to a class. */ + +static bfd_boolean +tg_class_static_member (p, name, physname, visibility) + PTR p; + const char *name; + const char *physname ATTRIBUTE_UNUSED; + enum debug_visibility visibility; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + int len_var, len_class; + char *full_name; + + len_var =3D strlen (name); + len_class =3D strlen (info->stack->next->type); + full_name =3D (char *) xmalloc (len_var + len_class + 3); + if (! full_name) + return FALSE; + memcpy (full_name, info->stack->next->type, len_class); + memcpy (full_name + len_class, "::", 2); + memcpy (full_name + len_class + 2, name, len_var + 1); + + if (! substitute_type (info, full_name)) + return FALSE; + + if (! prepend_type (info, "static ")) + return FALSE; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + if (! tg_fix_visibility (info, visibility)) + return FALSE; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n", + name, info->filename, t, info->stack->type, + visibility_name (visibility)); + free (t); + free (full_name); + + return TRUE; +} + +/* Add a base class to a class. */ + +static bfd_boolean +tg_class_baseclass (p, bitpos, virtual, visibility) + PTR p; + bfd_vma bitpos ATTRIBUTE_UNUSED; + bfd_boolean virtual; + enum debug_visibility visibility; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + const char *prefix; + + assert (info->stack !=3D NULL && info->stack->next !=3D NULL); + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + if (strncmp (t, "class ", sizeof "class " - 1) =3D=3D 0) + t +=3D sizeof "class " - 1; + + /* Push it back on to take advantage of the prepend_type and + append_type routines. */ + if (! push_type (info, t)) + return FALSE; + + if (virtual) + { + if (! prepend_type (info, "virtual ")) + return FALSE; + } + + switch (visibility) + { + case DEBUG_VISIBILITY_PUBLIC: + prefix =3D "public "; + break; + case DEBUG_VISIBILITY_PROTECTED: + prefix =3D "protected "; + break; + case DEBUG_VISIBILITY_PRIVATE: + prefix =3D "private "; + break; + default: + prefix =3D "/* unknown visibility */ "; + break; + } + + if (! prepend_type (info, prefix)) + return FALSE; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + if (info->stack->num_parents && ! append_parent (info, ", ")) + return FALSE; + + if (! append_parent (info, t)) + return FALSE; + info->stack->num_parents++; + + free (t); + + return TRUE; +} + +/* Add a variant to a method. */ + +static bfd_boolean +tg_class_method_variant (p, physname, visibility, constp, volatilep, voffs= et, + context) + PTR p; + const char *physname ATTRIBUTE_UNUSED; + enum debug_visibility visibility; + bfd_boolean constp; + bfd_boolean volatilep; + bfd_vma voffset ATTRIBUTE_UNUSED; + bfd_boolean context; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *method_type; + char *context_type; + char *method_name; + + assert (info->stack !=3D NULL); + assert (info->stack->next !=3D NULL); + + /* Put the const and volatile qualifiers on the type. */ + if (volatilep) + { + if (! append_type (info, " volatile")) + return FALSE; + } + if (constp) + { + if (! append_type (info, " const")) + return FALSE; + } + + method_name =3D strdup (context ? info->stack->next->next->method + : info->stack->next->method); +=20=20 + /* Stick the name of the method into its type. */ + if (! substitute_type (info, method_name)) + return FALSE; + + /* Get the type. */ + method_type =3D pop_type (info); + if (method_type =3D=3D NULL) + return FALSE; + + /* Pull off the context type if there is one. */ + if (! context) + context_type =3D NULL; + else + { + context_type =3D pop_type (info); + if (context_type =3D=3D NULL) + return FALSE; + } + + /* Now the top of the stack is the class. */ + + if (! tg_fix_visibility (info, visibility)) + return FALSE; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n", + method_name, info->filename, method_type, info->stack->type); + free (method_type); + free (method_name); + free (context_type); +=20=20 + return TRUE; +} + +/* Add a static variant to a method. */ + +static bfd_boolean +tg_class_static_method_variant (p, physname, visibility, constp, volatilep) + PTR p; + const char *physname ATTRIBUTE_UNUSED; + enum debug_visibility visibility; + bfd_boolean constp; + bfd_boolean volatilep; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *method_type; + char *method_name; + + assert (info->stack !=3D NULL); + assert (info->stack->next !=3D NULL); + assert (info->stack->next->method !=3D NULL); + + /* Put the const and volatile qualifiers on the type. */ + if (volatilep) + { + if (! append_type (info, " volatile")) + return FALSE; + } + if (constp) + { + if (! append_type (info, " const")) + return FALSE; + } + + /* Mark it as static. */ + if (! prepend_type (info, "static ")) + return FALSE; + + method_name =3D strdup (info->stack->next->method); + /* Stick the name of the method into its type. */ + if (! substitute_type (info, info->stack->next->method)) + return FALSE; + + /* Get the type. */ + method_type =3D pop_type (info); + if (method_type =3D=3D NULL) + return FALSE; + + /* Now the top of the stack is the class. */ + + if (! tg_fix_visibility (info, visibility)) + return FALSE; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n", + method_name, info->filename, method_type, info->stack->type, + visibility_name (visibility)); + free (method_type); + free (method_name); + + return TRUE; +} + +/* Finish up a class. */ + +static bfd_boolean +tg_end_class_type (p) + PTR p; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type, + info->filename, info->stack->flavor); + if (info->stack->num_parents) + { + fprintf (info->f, "\tinherits:%s", info->stack->parents); + free (info->stack->parents); + } + fputc ('\n', info->f); + + return tg_end_struct_type (p); +} + +/* Push a type on the stack using a tag name. */ + +static bfd_boolean +tg_tag_type (p, name, id, kind) + PTR p; + const char *name; + unsigned int id; + enum debug_type_kind kind; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + const char *t, *tag; + char idbuf[20]; + + switch (kind) + { + case DEBUG_KIND_STRUCT: + t =3D "struct "; + break; + case DEBUG_KIND_UNION: + t =3D "union "; + break; + case DEBUG_KIND_ENUM: + t =3D "enum "; + break; + case DEBUG_KIND_CLASS: + t =3D "class "; + break; + case DEBUG_KIND_UNION_CLASS: + t =3D "union class "; + break; + default: + abort (); + return FALSE; + } + + if (! push_type (info, t)) + return FALSE; + if (name !=3D NULL) + tag =3D name; + else + { + sprintf (idbuf, "%%anon%u", id); + tag =3D idbuf; + } + + if (! append_type (info, tag)) + return FALSE; + + return TRUE; +} + +/* Output a typedef. */ + +static bfd_boolean +tg_typdef (p, name) + PTR p; + const char *name; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *s; + + s =3D pop_type (info); + if (s =3D=3D NULL) + return FALSE; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name, + info->filename, s); + + free (s); + + return TRUE; +} + +/* 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. */ + +static bfd_boolean +tg_tag (p, name) + PTR p ATTRIBUTE_UNUSED; + const char *name ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + free (t); + + return TRUE; +} + +/* Output an integer constant. */ + +static bfd_boolean +tg_int_constant (p, name, val) + PTR p; + const char *name; + bfd_vma val; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char ab[20]; + + indent (info); + print_vma (val, ab, FALSE, FALSE); + fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n", + name, info->filename, ab); + return TRUE; +} + +/* Output a floating point constant. */ + +static bfd_boolean +tg_float_constant (p, name, val) + PTR p; + const char *name; + double val; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + + indent (info); + fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n", + name, info->filename, val); + return TRUE; +} + +/* Output a typed constant. */ + +static bfd_boolean +tg_typed_constant (p, name, val) + PTR p; + const char *name; + bfd_vma val; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + char ab[20]; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + indent (info); + print_vma (val, ab, FALSE, FALSE); + fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n", + name, info->filename, t, ab); + + free (t); + + return TRUE; +} + +/* Output a variable. */ + +static bfd_boolean +tg_variable (p, name, kind, val) + PTR p; + const char *name; + enum debug_var_kind kind; + bfd_vma val ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + const char *dname, *from_class; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + dname =3D name; + if (info->demangler) + { + dname =3D info->demangler (info->abfd, name); + if (strcmp (name, dname) =3D=3D 0) + { + free ((char *) dname); + dname =3D name; + } + } + + if (dname !=3D name) + { + char *sep; + sep =3D strstr (dname, "::"); + if (sep) + { + *sep =3D 0; + name =3D sep + 2; + from_class =3D dname; + } + else + { + /* Obscure types as vts and type_info nodes. */ + name =3D dname; + from_class =3D NULL; + } + } + else + from_class =3D NULL; + + fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename,= t); + + switch (kind) + { + case DEBUG_STATIC: + case DEBUG_LOCAL_STATIC: + fprintf (info->f, "\tfile:"); + break; + case DEBUG_REGISTER: + fprintf (info->f, "\tregister:"); + break; + default: + break; + } + + if (from_class) + { + fprintf (info->f, "\tclass:%s",from_class); + free ((char *) dname); + } + + fprintf (info->f, "\n"); + + free (t); + + return TRUE; +} + +/* Start outputting a function. */ + +static bfd_boolean +tg_start_function (p, name, global) + PTR p; + const char *name; + bfd_boolean global; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + const char *dname; + + if (! global) + info->stack->flavor =3D "static"; + else + info->stack->flavor =3D NULL; + + dname =3D name; + if (info->demangler) + { + dname =3D info->demangler (info->abfd, name); + if (strcmp (name, dname) =3D=3D 0) + { + free ((char *) dname); + dname =3D name; + } + } + + if (! substitute_type (info, dname)) + return FALSE; +=20=20=20=20 + if (dname !=3D name) + { + char *sep; + sep =3D strstr (dname, "::"); + if (sep) + { + info->stack->method =3D dname; + *sep =3D 0; + name =3D sep + 2; + } + else + { + info->stack->method =3D ""; + name =3D dname; + } + sep =3D strchr (name, '('); + if (sep) + *sep =3D 0; + /* Obscure functions as type_info function. */ + } + else + info->stack->method =3D NULL; + + info->stack->parents =3D strdup (name); + + if (! info->stack->method && ! append_type (info, "(")) + return FALSE; + + info->parameter =3D 1; + + return TRUE; +} + +/* Output a function parameter. */ + +static bfd_boolean +tg_function_parameter (p, name, kind, val) + PTR p; + const char *name; + enum debug_parm_kind kind; + bfd_vma val ATTRIBUTE_UNUSED; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char *t; + + if (kind =3D=3D DEBUG_PARM_REFERENCE + || kind =3D=3D DEBUG_PARM_REF_REG) + { + if (! pr_reference_type (p)) + return FALSE; + } + + if (! substitute_type (info, name)) + return FALSE; + + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + + if (! info->stack->method) + { + if (info->parameter !=3D 1 && ! append_type (info, ", ")) + return FALSE; +=20=20=20=20 + if (kind =3D=3D DEBUG_PARM_REG || kind =3D=3D DEBUG_PARM_REF_REG) + if (! append_type (info, "register ")) + return FALSE; +=20=20=20=20=20=20=20=20=20=20 + if (! append_type (info, t)) + return FALSE; + } + + free (t); + + ++info->parameter; + + return TRUE; +} + +/* Start writing out a block. */ + +static bfd_boolean +tg_start_block (p, addr) + PTR p; + bfd_vma addr; +{ + struct pr_handle *info =3D (struct pr_handle *) p; + char ab[20], kind, *partof; + char *t; + bfd_boolean local; + + if (info->parameter > 0) + { + info->parameter =3D 0; + + /* Delayed name. */ + fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename); + free (info->stack->parents); + + print_vma (addr, ab, TRUE, TRUE); + translate_addresses (info->abfd, ab, info->f, info->syms); + local =3D info->stack->flavor !=3D NULL; + if (info->stack->method && *info->stack->method) + { + kind =3D 'm'; + partof =3D (char *) info->stack->method; + } + else + { + kind =3D 'f'; + partof =3D NULL; + if (! info->stack->method && ! append_type (info, ")")) + return FALSE; + } + t =3D pop_type (info); + if (t =3D=3D NULL) + return FALSE; + fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t); + if (local) + fputs ("\tfile:", info->f); + if (partof) + { + fprintf (info->f, "\tclass:%s", partof); + free (partof); + } + fputc ('\n', info->f); + } + + return TRUE; +} + +/* Write out line number information. */ + +static bfd_boolean +tg_lineno (p, filename, lineno, addr) + PTR p ATTRIBUTE_UNUSED; + const char *filename ATTRIBUTE_UNUSED; + unsigned long lineno ATTRIBUTE_UNUSED; + bfd_vma addr ATTRIBUTE_UNUSED; +{ + return TRUE; +} + +/* Finish writing out a block. */ + +static bfd_boolean +tg_end_block (p, addr) + PTR p ATTRIBUTE_UNUSED; + bfd_vma addr ATTRIBUTE_UNUSED; +{ + return TRUE; +} + +/* Convert the visibility value into a human readable name. */ + +static const char * +visibility_name (visibility) + enum debug_visibility visibility; +{ + const char *s; + + switch (visibility) + { + case DEBUG_VISIBILITY_PUBLIC: + s =3D "public"; + break; + case DEBUG_VISIBILITY_PRIVATE: + s =3D "private"; + break; + case DEBUG_VISIBILITY_PROTECTED: + s =3D "protected"; + break; + case DEBUG_VISIBILITY_IGNORE: + s =3D "/* ignore */"; + break; + default: + abort (); + return FALSE; + } + return s; } Index: NEWS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/NEWS,v retrieving revision 1.37 diff -u -r1.37 NEWS --- NEWS 26 Jun 2003 08:14:10 -0000 1.37 +++ NEWS 21 Jul 2003 19:31:52 -0000 @@ -1,5 +1,8 @@ -*- text -*- =20 +* objdump now accepts --debugging-tags to print the debug information in a + format compatible with ctags tool. + * objcopy and strip now accept --only-keep-debug to create a file containi= ng those sections that would be stripped out by --strip-debug. The idea is= that this can be used in conjunction with the --add-gnu-debuglink switch to c= reate Index: doc/binutils.texi =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/binutils/doc/binutils.texi,v retrieving revision 1.44 diff -u -r1.44 binutils.texi --- doc/binutils.texi 18 Jul 2003 11:34:41 -0000 1.44 +++ doc/binutils.texi 21 Jul 2003 19:31:53 -0000 @@ -1435,6 +1435,7 @@ [@option{-f}|@option{--file-headers}] [@option{--file-start-context}] [@option{-g}|@option{--debugging}] + [@option{-e}|@option{--debugging-tags}] [@option{-h}|@option{--section-headers}|@option{--headers}] [@option{-i}|@option{--info}] [@option{-j} @var{section}|@option{--section=3D}@var{section}] @@ -1480,7 +1481,7 @@ =20 The long and short forms of options, shown here as alternatives, are equivalent. At least one option from the list -@option{-a,-d,-D,-f,-g,-G,-h,-H,-p,-r,-R,-S,-t,-T,-V,-x} must be given.=20 +@option{-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-r,-R,-S,-t,-T,-V,-x} must be given. =20 @table @env @item -a @@ -1535,6 +1536,11 @@ Only certain types of debugging information have been implemented. Some other types are supported by @command{readelf -w}. @xref{readelf}. + +@item -e +@itemx --debugging-tags +Like @option{-g}, but the information is generated in a format compatible +with ctags tool. =20 @item -d @itemx --disassemble --------------090403030008050308010708--