diff options
Diffstat (limited to 'gprof')
84 files changed, 28798 insertions, 36 deletions
diff --git a/gprof/.gdbinit b/gprof/.gdbinit new file mode 100644 index 000000000000..e519472ebcd7 --- /dev/null +++ b/gprof/.gdbinit @@ -0,0 +1 @@ +dir .. diff --git a/gprof/ChangeLog b/gprof/ChangeLog new file mode 100644 index 000000000000..965c8112e4af --- /dev/null +++ b/gprof/ChangeLog @@ -0,0 +1,19 @@ +2004-05-13 Nick Clifton <nickc@redhat.com> + + * po/fr.po: Updated French translation. + +2004-04-09 Daniel Jacobowitz <drow@mvista.com> + + Merge from mainline: + 2004-03-19 Alan Modra <amodra@bigpond.net.au> + * po/sv.po: Updated. + + +For older changes see ChangeLog-9203 + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/gprof/ChangeLog-9203 b/gprof/ChangeLog-9203 new file mode 100644 index 000000000000..463c2a68dca1 --- /dev/null +++ b/gprof/ChangeLog-9203 @@ -0,0 +1,2138 @@ +2003-11-06 Bruno Rohee <bruno@rohee.com> + + * gprof.texi: Fix "the the" typo. + +2003-10-30 Nick Clifton <nickc@redhat.com> + + * gprof.texi (Compiling): Describe how to use gprof when source + files are not compiled with -pg. Mention other profiling options + supported by gcc. + (How do I?): Mention the function call overhead introduced by -pg. + +2003-10-29 Nick Clifton <nickc@redhat.com> + + * gprof.texi: Apply patch supplied by Eric S Raymond via RMS: + (Compiling): Mention that -pg must be passed to both the compiler + and the linker. + Mention that -a is now deprecated. + (How do I?): Add an entry describing how to get more information + about program hotspots. + +2003-10-11 Alan Modra <amodra@bigpond.net.au> + + * corefile.c (core_create_function_syms): Don't refer directly to + _cooked_size and vma; Use bfd_section_size and bfd_get_section_vma. + +2003-08-26 Nick Clifton <nickc@redhat.com> + + * po/de.po: New German translation. + * configure.in (ALL_LINGUAS): Add de. + * configure: Regenerate. + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * gconfig.in: Regenerate. + +2003-08-21 Nick Clifton <nickc@redhat.com> + + * po/tr.po: Updated Turkish translation. + +2003-08-14 Alan Modra <amodra@bigpond.net.au> + + * dep-in.sed: Remove libintl.h. + * Makefile.am (POTFILES.in): Unset LC_COLLATE. + * Makefile.in: Regenerate. + +2003-07-24 Nick Clifton <nickc@redhat.com> + + * po/fr.po: Updated French translation. + +2003-07-20 H.J. Lu <hongjiu.lu@intel.com> + + * po/Make-in (.po.gmo): Do check if the .gmo file is writable + before generating it. + +2003-07-17 Nick Clifton <nickc@redhat.com> + + * po/es.po: New Spanish translation. + +2003-07-11 Alan Modra <amodra@bigpond.net.au> + + * po/gprof.pot: Regenerate. + +2003-06-11 H.J. Lu <hongjiu.lu@intel.com> + + * po/Make-in (DESTDIR): New. + (install-data-yes): Support $(DESTDIR). + (uninstall): Likewise. + +2003-03-27 Chris Demetriou <cgd@broadcom.com> + + * gmon_io.c (enum gmon_ptr_size, enum gmon_ptr_signedness): New. + (gmon_get_ptr_size, gmon_get_ptr_signedness): New. + (gmon_io_read_vma, gmon_io_write_vma, gmon_read_raw_arc) + (gmon_write_raw_arc, gmon_out_read, gmon_out_write): Adjust to + use new functions and enums. + +2003-02-21 K Schutte <schutte@fel.tno.nl> + + * corefile.c (core_create_line_syms): Check for a NULL sentinel + value before using it. + +2002-12-02 Nick Clifton <nickc@redhat.com> + + * configure.in (LINGUAS): Add pt_BR. + * configure: Regenerate. + * po/pt_BR: New Brazillian Portugese translation. + +2002-11-30 Alan Modra <amodra@bigpond.net.au> + + * basic_blocks.c, basic_blocks.h, cg_arcs.c, cg_dfn.c, cg_print.c, + corefile.c, gmon_io.c, gprof.c, gprof.h, hist.c, mips.c, source.c, + source.h, sym_ids.c, sym_ids.h, symtab.h, tahoe.c, vax.c: Replace + boolean with bfd_boolean, true with TRUE, false with FALSE. + Formatting. + +2002-11-12 Nick Clifton <nickc@redhat.com> + + * configure.in (ALL_LINGUAS): Add da. + * configure: Regenerate. + * po/da.po: New Danish translation. + +2002-08-22 Nick Clifton <nickc@redhat.com> + + * gprof.c (main): Turn off default excluded functions in FLAT + profile. + +2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca> + + * gmon_io.c (gmon_io_read_64, gmon_io_write_64): Define only if + BFD_HOST_U_64_BIT is defined. + (gmon_io_read_vma, gmon_io_write_vma): Add ifdefs. + +2002-07-30 Nick Clifton <nickc@redhat.com> + + * po/tr.po: Updated Turkish translation. + +2002-07-30 Nick Clifton <nickc@redhat.com> + + * alpha.c, cg_arcs.c, cg_dfn.c, gmon.h, gprof.c, gprof.h, hertz.c, + i386.c, mips.c, sparc.c, tahoe.c, utils.c, vax.c: Update Copyright + notice so that it applies even if the sources are modified. + +2002-07-29 Ulrich Drepper <drepper@redhat.com> + + * gprof.texi (Executing the Program): Add documentation on how to use + bbconv.pl. Patch by Eric Hanchrow. + +2002-07-25 Nick Clifton <nickc@redhat.com> + + * po/es.po: Updated Spanish translation. + * po/fr.po: Updated French translation. + +2002-07-24 Dave Brolley <brolley@redhat.com> + + * corefile.c (core_create_function_syms): Use the end of the section + containing the symbol to compute max_vma. + +2002-07-24 Nick Clifton <nickc@redhat.com> + + * po/sv.po: Updated Swedish translation. + * po/es.po: Updated Spanish translation. + +2002-07-23 Nick Clifton <nickc@redhat.com> + + * po/fr.po: Updated French translation. + * po/id.po: New Indonesian translation. + * configure.in (LINGUAS): Add id. + * configure: Regenerate. + +2002-05-02 Nick Clifton <nickc@cambridge.redhat.com> + + * po/Make-in (.po.gmo): Do not attempt to create a .gmo file if + the sources are read-only. + +2002-04-04 Alan Modra <amodra@bigpond.net.au> + + * dep-in.sed: Cope with absolute paths. + * Makefile.am (dep.sed): Subst TOPDIR. + Run "make dep-am". + * Makefile.in: Regenerate. + +2002-03-21 Alan Modra <amodra@bigpond.net.au> + + * Makefile.am: Run "make dep-am". + * Makefile.in: Regenerate. + +2002-03-18 Nick Clifton <nickc@cambridge.redhat.com> + + * po/fr.po: Updated version. + +2002-03-13 Nick Clifton <nickc@cambridge.redhat.com> + + * po/fr.po: Updated version. + +2002-03-07 Daniel Jacobowitz <drow@mvista.com> + + * gprof.texi: Wrap @menu in @ifnottex, not @ifinfo. + +2002-02-19 Frank Ch. Eigler <fche@redhat.com> + + * hist.c (hist_print): Rewrite log_scale calculation loop. + +2002-02-11 Alan Modra <amodra@bigpond.net.au> + + * Makefile.am: "make dep-am". + * Makefile.in: Regenerate. + +2002-02-10 Daniel Jacobowitz <drow@mvista.com> + + * gprof.c: Include "getopt.h" after other includes, so that + the proper macros are defined. + * gen-c-prog.awk: Emit a prototype for the generated function. + +2002-02-01 Alan Modra <amodra@bigpond.net.au> + + * configure.in (build_warnings): Add -Wstrict-prototypes + -Wmissing-prototypes. + * aclocal.m4: Regenerate. + * gconfig.in: Regenerate. + * configure: Regenerate. + * Makefile.am: Run "make dep-am". + * Makefile.in: Regenerate. + + * alpha.c (alpha_find_call): Warning fixes. + * mips.c (mips_find_call): Likewise. + * sparc.c (sparc_find_call): Likewise. + * basic_blocks.c: Warning fixes. Eliminate DEFUN. + * call_graph.c: Likewise. + * cg_arcs.c: Likewise. + * cg_dfn.cp: Likewise. + * gprof.c: Likewise. + * gprof.h: Likewise. + * hist.c: Likewise. + * search_list.c: Likewise. + * source.c: Likewise. + * source.h: Likewise. + * sym_ids.c: Likewise. + * symtab.c: Likewise. + * symtab.h: Likewise. + * utils.c: Likewise. + * cg_print.c: Likewise. + (struct function_map, symbol_map, symbol_map_count): Move + declaration to.. + * corefile: ..here. + * corefile.c: Warning fixes. Eliminate DEFUN. + (struct function_map): Remove declaration. + * gmon_io.c: Warning fixes. Eliminate DEFUN. + (gmon_io_read_64): Make static. + (gmon_io_write_64): Likewise. + (gmon_read_raw_arc): Likewise. + (gmon_write_raw_arc): Likewise. + (gmon_io_write_8): Don't pass char, pass int param. + * gmon_io.h (gmon_io_write_8): Likewise. + + * Makefile.am: Run "make dep-am" + * Makefile.in: Regenerate. + + * basic_blocks.c: Replace bool with boolean, TRUE with true and + FALSE with false throughout. + * basic_blocks.h: Likewise. + * cg_arcs.c: Likewise. + * cg_dfn.c: Likewise. + * cg_print.c: Likewise. + * corefile.c: Likewise. + * gmon_io.c: Likewise. + * gprof.c: Likewise. + * hist.c: Likewise. + * mips.c: Likewise. + * source.c: Likewise. + * source.h: Likewise. + * sym_ids.c: Likewise. + * sym_ids.h: Likewise. + * symtab.h: Likewise. + * tahoe.c: Likewise. + * vax.c: Likewise. + * gprof.h: Likewise. + (TRUE): Don't define. + (FALSE): Don't define. + +2002-01-31 Jason R Thorpe <thorpej@wasabisystems.com> + + * TODO: Remove "host architecture pointer size" item. + * acconfig.h: Remove. + * gconfig.in: Regenerate. + * configure.in: Remove check for gmon pointer size. + * configure: Regenerate. + * gmon.h (GMON_HDRSIZE_BSD44_32): Define. + (GMON_HDRSIZE_BSD44_64): Ditto. + (GMON_HDRSIZE_OLDBSD_32): Ditto. + (GMON_HDRSIZE_OLDBSD_64): Ditto. + (struct raw_phdr): Wrap in #if 0, keeping it for + documentation purposes only. + (struct old_raw_phdr): Likewise. + (struct raw_arc): Likewise. Change type/size of + "count" member to long match 4.4BSD. + * gmon_io: Update copyright years. + (gmon_io_read_64): New function. + (gmon_io_read_vma): Use bfd_arch_bits_per_address to + determine target pointer size. Use gmon_io_read_32 + and gmon_io_read_64. + (gmon_io_write_64): New function. + (gmon_io_write_vma): Use bfd_arch_bits_per_address to + determine target pointer size. Use gmon_io_write_32 + and gmon_io_write_64. + (get_vma): Remove. + (put_vma): Ditto. + (gmon_read_raw_arc): New function. + (gmon_write_raw_arc): New function. + (gmon_out_read): Do not use struct raw_phdr or + struct old_raw_phdr to read the gmon header. Use + gmon_read_raw_arc to read call graph records. + (gmon_out_write): Do not use struct raw_phdr or + struct old_raw_phdr to write the gmon header. Use + gmon_write_raw_arc to write call graph records. + * po/gprof.pot: Regenerate. + * Makefile.in: Regenerate. + +2002-01-31 Alan Modra <amodra@bigpond.net.au> + + * alpha.c (alpha_Instruction): Don't use. + (alpha_find_call): Avoid use of bitfields and casts between + pointers and integers of different sizes. Avoid endian problems + when cross-compiling. + * vax.c (vax_find_call): Likewise. + (struct modebyte): Don't use. + (vax_operandmode): Pass in an unsigned char *. + (vax_operandlength): Likewise. + (vax_reladdr): Rename to vax_offset and return relative offset + rather than address. + * i386.c (i386_find_call): Avoid casts between pointers and + integers of different sizes. + * sparc.c (sparc_find_call): Likewise. Avoid endian problems. + * tahoe.c (tahoe_find_call): Likewise. + (tahoe_reladdr): Rename to tahoe_offset and return relative offset + rather than address. + + * basic_blocks.h: Don't include headers here. + * call_graph.h: Likewise. + * cg_arcs.h: Likewise. + * cg_print.h: Likewise. + * corefile.h: Likewise. + * gmon_io.h: Likewise. + * gmon_out.h: Likewise. + * hertz.h: Likewise. + * hist.h: Likewise. + * source.h: Likewise. + * sym_ids.h: Likewise. + * symtab.h: Likewise. + * gprof.h: Don't include ansidecl.h, do include bfd.h. + (bool): Don't typedef. + * alpha.c: Adjust #include's for above header changes. + * basic_blocks.c: Likewise. + * call_graph.c: Likewise. + * cg_arcs.c: Likewise. + * cg_dfn.c: Likewise. + * cg_print.c: Likewise. + * corefile.c: Likewise. + * gmon_io.c: Likewise. + * gprof.c: Likewise. + * hertz.c: Likewise. + * hist.c: Likewise. + * i386.c: Likewise. + * mips.c: Likewise. + * sparc.c: Likewise. + * sym_ids.c: Likewise. + * symtab.c: Likewise. + * tahoe.c: Likewise. + * utils.c: Likewise. + * vax.c: Likewise. + + * po/POTFILES.in: Regenerate. + +2002-01-27 Daniel Jacobowitz <drow@mvista.com> + + * configure: Regenerated. + +2002-01-26 Richard Henderson <rth@redhat.com> + + * i386.c (i386_iscall): Static. + * tahoe.c (indirectchild, tahoe_operandmode): Static. + (tahoe_operandlength, tahoe_reladdr): Static. + * vax.c (indirectchild): Static. + +2002-01-26 Hans-Peter Nilsson <hp@bitrange.com> + + * Makefile.am (install): Depend on install-info. + * Makefile.in: Regenerate. + +2002-01-26 Jason Thorpe <thorpej@wasabisystems.com> + + * mips.c: New file. + * Makefile.am (sources): Add mips.c. + (mips.o): New rule. + * Makefile.in: Regenerate. + * corefile.c: Update copyright years. + (find_call): Call mips_find_call for bfd_arch_mips. + +2002-01-26 Nick Clifton <nickc@cambridge.redhat.com> + + * po/fr.po: Updated version. + +2002-01-25 Nick Clifton <nickc@cambridge.redhat.com> + + * po/es.po: Updated version. + +2002-01-17 Nick Clifton <nickc@cambridge.redhat.com> + + * po/gprof.pot: Regenerate. + +2002-01-07 Nick Clifton <nickc@cambridge.redhat.com> + + * po/es.po: New file: Spanish translation. + * configure.in (ALL_LINGUAS): Add es. + * configure: Regenerate. + +2002-01-03 Nick Clifton <nickc@cambridge.redhat.com> + + * gmon_io.c (gmon_out_read): Remove use of ngettext(). It is not + present under AIX. + +2002-01-02 Nick Clifton <nickc@cambridge.redhat.com> + + * cg_print.c (print_header): Fix spelling typo. + + * gmon_io.c (gmon_out_read): Fix formatting of text messages to + allow easier translation into other languages. + +2001-12-21 Nick Clifton <nickc@cambridge.redhat.com> + + * configure.in (ALL_LINGUAS): Add sv. + * configure: Regenerate. + * po/sv.po: Import from translation project web site. + +2001-12-03 Nick Clifton <nickc@cambridge.redhat.com> + + * configure.in (LINGUAS): Add tr. + * configure: Regenerate. + * po/tr.po: Import from translation project's web site. + +2001-11-02 Nick Clifton <nickc@cambridge.redhat.com> + + * configure.in (ALL_LINGUAS): Add 'fr'. + * configure: Regernate. + * po/fr.po: New file. + +2001-10-03 Alan Modra <amodra@bigpond.net.au> + + * configure: Regenerate. + +2001-10-02 Alan Modra <amodra@bigpond.net.au> + + * Makefile.am (Makefile): Depend on bfd/configure.in. + Run "make dep-am". + * Makefile.in: Regenerate. + +2001-09-18 Bruno Haible <haible@clisp.cons.org> + + * gprof.c (main): For gettext, also set the LC_CTYPE locate facet. + * sym_ids.c: Include "safe-ctype.h" instead of <ctype.h>. + (parse_spec): Use ISDIGIT instead of isdigit. + +2001-09-18 Alan Modra <amodra@bigpond.net.au> + + * sparc.c (sparc_find_call): Warning fix. + * alpha.c (alpha_find_call): Likewise. + +2001-08-09 Alan Modra <amodra@bigpond.net.au> + + * alpha.c: Add missing prototypes. + * sparc.c: Likewise. + * tahoe.c: Likewise. + * vax.c: Likewise. + * i386.c: Likewise. + (i386_iscall): Don't use DEFUN. + +2001-07-19 Nick Clifton <nickc@cambridge.redhat.com> + + * NOTES: Rename to README for consistency with other binutils. + +2001-06-18 H.J. Lu <hjl@gnu.org> + + * Makefile.am (diststuff): Add $(MANS). + (gprof.1): Remove the prefix `$(srcdir)/'. + * Makefile.in: Regenerated. + + * gprof.1: Removed. + +2001-06-12 Ben Elliston <bje@redhat.com> + + * gprof.texi (File Format): Profile data files are stored in + target byte order, not host byte order. + +2001-05-16 Alexandre Oliva <aoliva@redhat.com> + + * gmon_io.c (gmon_io_read, gmon_io_write_vma, + gmon_io_write_32, gmon_io_write_8, gmon_io_write): Adjust + argument list for K&R C. + +2001-04-06 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * gprof.texi: Put @c man begin and @c man end indications + to generate man page using texi2pod and pod2man. Added SEEALSO, + SYNOPSIS, BUGS, FILES and DESCRIPTION from original gprof.1 + enclosed in @ifset man condition. + * Makefile.am (MANCONF, TEXI2POD, POD2MAN): New variable. + Generate gprof.1 from gprof.texi. + * gprof.1: Generate from gprof.texi. + * Makefile.in: Regenerate. + +2001-03-13 David Mosberger <davidm@hpl.hp.com> + + * hist.c (hist_dimension): Declare as an array of 16 characters. + (hist_read_rec): If SAMPLEDEBUG, print each histogram bin count. + + * basic_blocks.c: Whitespace and formatting changes. + * bb_exit_func.c: Ditto. + * call_graph.c: Ditto. + * call_graph.h: Ditto. + * cg_arcs.c: Ditto. + * cg_print.c: Ditto. + * cg_print.h: Ditto. + * corefile.c: Ditto. + * corefile.h: Ditto. + * gmon_io.c: Ditto. + * gmon_io.h: Ditto. + * gmon_out.h: Ditto. + * gprof.c: Ditto. + * hist.c: Ditto. + * hist.h: Ditto. + * i386.c: Ditto. + * search_list.c: Ditto. + * search_list.h: Ditto. + * source.c: Ditto. + * source.h: Ditto. + * sym_ids.c: Ditto. + * sym_ids.h: Ditto. + * symtab.c: Ditto. + * symtab.h: Ditto. + * tahoe.c: Ditto. + * utils.c: Ditto. + * vax.c: Ditto. + + * gmon_out.h (gmon_hist_hdr): Delete. + (gmon_cg_arc_record): Delete. + + * gmon_io.c (put_vma): Declare "static". + (get_vma): Ditto. + (gmon_io_write): New function. + (gmon_io_write_8): Ditto. + (gmon_io_write_32): Ditto. + (gmon_io_write_vma): Ditto. + (gmon_io_read): Ditto. + (gmon_io_read_32): Ditto. + (gmon_io_read_vma): Ditto. + * basic_blocks.c (bb_read_rec): Use gmon_io_read* / gmon_io_write* + to read/write data file in a more portable fashion. + (bb_write_blocks): Ditto. + * call_graph.c (cg_read_rec): Ditto. + (cg_write_arcs): Ditto. + * hist.c (hist_read_rec): Ditto. + (hist_write_hist): Ditto. + + From Jes Sorensen <jes@linuxcare.com> + * gmon_out.h: Use GMON_PTR_SIZE instead of sizeof(char*). + * gmon.h: Ditto. + * configure.in: Get GMON_PTR_SIZE from existing <sys/gmon_out.h> + if it exists. + * acconfig.h: New file. Mention and document GMON_PTR_SIZE. + * gconfig.h: Regenerate. + * configure: Regenerate. + * Makefile.in: Regenerate. + +2001-02-27 Alan Modra <alan@linuxcare.com.au> + + * configure.in (BFD_VERSION): New. + (AM_INIT_AUTOMAKE): Use $BFD_VERSION. + * configure: Regenerate. + * gconfig.in: Regenerate. + * Makefile.am: Run "make dep-am" + * Makefile.in: Regenerate. + +2001-01-27 Michael Sokolov <msokolov@ivan.Harhan.ORG> + + * basic_blocks.c: #include <unistd.h> only if it exists. + +2000-11-06 Nick Clifton <nickc@redhat.com> + + * gprof.texi: Add GNU Free Documentation License. + +2000-09-07 H.J. Lu <hjl@gnu.org> + + * configure.in (AC_ISC_POSIX): Put after AC_CANONICAL_SYSTEM. + * configure: Rebuild. + +2000-09-06 Alexandre Oliva <aoliva@redhat.com> + + * aclocal.m4, configure: Rebuilt with new libtool.m4. + +2000-09-02 Nick Clifton <nickc@redhat.com> + + * configure.in: Increase version number to 2.10.91. + * configure: Regenerate. + * aclocal.m4: Regenerate. + * config.in: Regenerate. + +2000-08-31 Alexandre Oliva <aoliva@redhat.com> + + * acinclude.m4: Include libtool and gettext macros from the + top level. + * aclocal.m4, configure: Rebuilt. + +2000-07-26 Nick Clifton <nickc@cygnus.com> + + * bb_exit_func.c: Assign copyright to FSF. Note that David + Mosberger-Tang <David.Mosberger@acm.org> continuted this code. + +2000-07-24 Nick Clifton <nickc@cygnus.com> + + * basic_blocks.c: Add copyright notice. + * basic_blocks.h: Add copyright notice. + * call_graph.c: Add copyright notice. + * call_graph.h: Add copyright notice. + * cg_print.c: Add copyright notice. + * cg_print.h: Add copyright notice. + * corefile.c: Add copyright notice. + * corefile.h: Add copyright notice. + * gmon_io.c: Add copyright notice. + * gmon_io.h: Add copyright notice. + * gmon_out.h: Add copyright notice. + * hist.c: Add copyright notice. + * hist.h: Add copyright notice. + * search_list.c: Add copyright notice. + * search_list.h: Add copyright notice. + * source.c: Add copyright notice. + * source.h: Add copyright notice. + * sym_ids.c: Add copyright notice. + * sym_ids.h: Add copyright notice. + * symtab.c: Add copyright notice. + * symtab.h: Add copyright notice. + +2000-07-05 Kenneth Block <krblock@computer.org> + + * gprof.c: Add optional style to demangle switch + * gprof.texi: Document optional style to demangle switch. + +2000-06-05 DJ Delorie <dj@redhat.com> + + * MAINTAINERS: new + +2000-07-01 Alan Modra <alan@linuxcare.com.au> + + * Makefile.am (DEP): Fix 2000-06-22. grep after running dep.sed + (CLEANFILES): Add DEPA. + * Makefile.in: Regenerate. + +2000-06-22 Alan Modra <alan@linuxcare.com.au> + + * Makefile.am (DEP): grep for leading `/' in DEP1, and fail if we + find one. + * Makefile.in: Regenerate. + +2000-06-20 Alan Modra <alan@linuxcare.com.au> + + * source.c (annotate_source): Correct pointer comparison when + checking for backslashes. + +2000-06-13 H.J. Lu <hjl@gnu.org> + + * configure: Regenerate. + +2000-06-08 David O'Brien <obrien@FreeBSD.org> + + * configure.in (VERSION): Update to show this is the CVS mainline. + +2000-06-07 Philippe De Muyter <phdm@macqel.be> + + * source.c: Remove direct inclusion of sys/stat.h. + +2000-05-31 Nick Clifton <nickc@cygnus.com> + + * gprof.h (_): Revert previous delta. We want to use gettext, + not dgettext in the _ macro. + +2000-05-29 Alan Modra <alan@linuxcare.com.au> + + * gprof.h (_): Use BFD version. + +2000-05-26 Nick Clifton <nickc@cygnus.com> + + * gprof.c (main): When calling getopt_long indicate that the 'd' + switch takes an optional argument, whereas the 'D' switch takes no + argument at all. + +2000-05-26 Alan Modra <alan@linuxcare.com.au> + + * dep-in.sed: Copy from ../binutils. + * Makefile.am: Update dependencies with "make dep-am" + * Makefile.in: Regenerate. + + * gprof.h: Remove most nls defines. They are pulled in by + bfd/sysdep.h. #include "ansidecl.h" not <ansidecl.h> + +2000-05-26 Eli Zaretskii <eliz@is.elta.co.il> + + * gprof.texi: Fix numerous typos. Mention some DOS/Windows related + issues. + + * configure.in: Check for setmode function. + * configure: Regenerate. + + * gmon_io.h (SET_BINARY) [HAVE_SETMODE]: Define. + + * gmon_io.c (gmon_out_read) [SET_BINARY]: Switch stdin into binary + mode. + + * source.c: Include filenames.h and sys/stat.h. + (source_file_lookup_path, source_file_lookup_name): Use + FILENAME_CMP to compare file names. + (annotate_source) [__MSDOS__]: If "filename-ann" would overwrite + "filename", replace the extension with ".ann". + [HAVE_DOS_BASED_FILE_SYSTEM]: Support file names with + backslashes and drive letters. + Use IS_ABSOLUTE_PATH. + + * search_list.h (PATH_SEP_CHAR): Define. + + * search_list.c (search_list_append): Use PATH_SEP_CHAR. + + * hertz.c (HERTZ) [__MSDOS__]: Don't define unless they have + neither HAVE_SETITIMER nor HAVE_SYSCONF. + [HAVE_SETITIMER]: If they define both HAVE_SETITIMER and + HAVE_SYSCONF, try setitimer and fall back on sysconf. + +2000-04-07 Andrew Cagney <cagney@b1.cygnus.com> + + * configure.in (WARN_CFLAGS): Set to -W -Wall by default. Add + --enable-build-warnings option. + * Makefile.am (AM_CFLAGS, WARN_CFLAGS): Add definitions. + * Makefile.in, configure, aclocal.m4: Re-generate. + +2000-04-05 Alexandre Oliva <oliva@lsd.ic.unicamp.br> + + * gprof.c (copyright): Do not use N_ in array initializer. + +2000-04-04 Alan Modra <alan@linuxcare.com.au> + + * po/gprof.pot: Regenerate. + + * gprof.c (usage): Restore translated part of bug string. + + * Makefile.am (BASEDIR): Define. + (BFDDIR): Define. + (INCDIR): Define. + (MKDEP): Define. + (INCLUDES): Add "-I." + (DEP, DEP1, dep.sed, dep, dep-in, dep-am): New targets. + (CLEANFILES): Define. + Update dependencies. + * Makefile.in: Regenerate. + +2000-04-03 Alan Modra <alan@linuxcare.com.au> + + * gprof.h: #include "bin-bugs.h". + * gprof.c (usage): Use REPORT_BUGS_TO. + +2000-03-31 Alan Modra <alan@linuxcare.com.au> + + * symtab.c (symtab_finalize): Don't use post-increment on + structure copy, to work around a ppc gcc bug. + +1999-09-29 Mark Kettenis <kettenis@gnu.org> + + * hertz.h [MACH] (hertz): Remove macro. The + <machine/mach_param.h> include doesn't exist on al Mach based + systems, and the definition of hertz breaks compilation of hertz.c + anyway. + +2000-02-22 Ian Lance Taylor <ian@zembu.com> + + From Brad Lucier <lucier@math.purdue.edu>: + * i386.c (i386_find_call): Add cast to ensure that printf argument + matches format. + * tahoe.c (tahoe_find_call): Likewise. + * vax.c (vax_find_call): Likewise. + +2000-01-27 Alan Modra <alan@spri.levels.unisa.edu.au> + + * utils.c (print_name_only): Don't pass error strings to + printf as format arg. + +1999-09-24 Nick Clifton <nickc@cygnus.com> + + * gmon_io.c (gmon_out_read): Make sure that sensible values + are extracted from a raw header. + +1999-08-06 Ian Lance Taylor <ian@zembu.com> + + From Brad Lucier <lucier@math.purdue.edu>: + * corefile.c (core_create_line_syms): Add cast for printf. + +1999-07-21 Ian Lance Taylor <ian@zembu.com> + + From Mark Elbrecht: + * configure.bat: Remove; obsolete. + +1999-07-15 Ian Lance Taylor <ian@zembu.com> + + * configure.in: Bump version number to 2.9.5. + * configure: Rebuild. + +1999-07-11 Ian Lance Taylor <ian@zembu.com> + + * corefile.c (core_create_function_syms): Add ATTRIBUTED_UNUSED. + * sym-ids.c (non_existent_file): Fully initialize structure. + +1999-07-01 Ian Lance Taylor <ian@zembu.com> + + * Many files: Add casts in many print statements to cast bfd_vma + values to unsigned long when calling printf. + * Makefile.am ($(OBJECTS)): Add gmon.h. + * Makefile.in: Rebuild. + +1999-06-14 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * gprof.texi: Fix typo. + +1999-06-13 Ian Lance Taylor <ian@zembu.com> + + From Bob Byrnes <byrnes@curl.com>: + * cg_dfn.c: Include "libiberty.h" + (DFN_INCR_DEPTH): Define instead of DFN_DEPTH. + (dfn_stack): Define as pointer rather than array. + (pre_visit): Reallocate dfn_stack as needed. + +1999-04-26 Tom Tromey <tromey@cygnus.com> + + * aclocal.m4, configure: Updated for new version of libtool. + +1999-04-06 Ian Lance Taylor <ian@zembu.com> + + * gprof.h (LC_MESSAGES): Never define. + * gprof.c (main): Don't pass LC_MESSAGES to setlocale if the + system does not define it. + +1999-04-05 H.J. Lu <hjl@gnu.org> + + * corefile.c (core_create_line_syms): Don't use fixed size array + for prev_name and prev_filename. + +1999-04-04 Michael Hohmuth <hohmuth@innocent.com> + + * gprof.h (FF_BSD44): Define. + * gmon.h (struct raw_phdr): Add version, profrate, and spare + fields unconditionally. + (struct old_raw_phdr): New struct. + * gprof.c (main): Handle -O 4.4bsd. + * gmon_io.c (gmon_out_read): Handle BSD 4.4 format, either + automatically or by user specification. + (gmon_out_write): Handle BSD 4.4 format. + * configure.in: Don't set BSD44_FORMAT. + * gprof.texi (Miscellaneous Options): Document -O 4.4bsd. + * configure, gconfig.in: Rebuild. + +Tue Feb 16 17:01:33 1999 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Change AC_PREREQ to 2.13. Change AM_PROG_INSTALL + to AC_PROG_INSTALL. Remove AM_CYGWIN32. Change AM_EXEEXT to + AC_EXEEXT. Add comment to AC_DEFINE. + * acconfig.h: Remove. + * aclocal.m4: Rebuild. + * configure: Rebuild. + * Makefile.in: Rebuild. + * gconfig.in: Rebuild. + +1998-12-06 Ian Lance Taylor <ian@cygnus.com> + + * gprof.texi (Symspecs): Mention that you have to add any + underscore yourself when naming a symbol. + +1998-11-02 Geoffrey Noer <noer@cygnus.com> + + * configure.in: detect cygwin* instead of cygwin32* + * configure: regenerate + +Wed Aug 12 14:59:06 1998 Ian Lance Taylor <ian@cygnus.com> + + Avoid some overflow cases: + * basic_blocks.h (bb_min_calls): Change to unsigned long. + * call_graph.h (cg_tally): Change count parameter to unsigned + long. + * cg_arcs.h (Arc): Change count field to unsigned long. + (arc_add): Change count parameter to unsigned long. + * source.h (Source_File): Change ncalls field to unsigned long. + * symtab.h (Sym): Change fields ncalls, bb_calls, and + cg.self_calls to unsigned long. + * Many files: Update accordingly. + + * configure, Makefile.in, aclocal.m4: Rebuild with current tools. + +Fri Jul 10 17:29:49 1998 Stan Cox <scox@equinox.cygnus.com> + + * configure.in (BSD44_FORMAT): Define for cygwin32, win32, mingw32 + * configure: Rebuild. + +Fri Jun 12 13:40:05 1998 Tom Tromey <tromey@cygnus.com> + + * po/Make-in (all-yes): If maintainer mode, depend on .pot file. + ($(PACKAGE).pot): Unconditionally depend on POTFILES. + +Sun May 10 22:35:33 1998 Jeffrey A Law (law@cygnus.com) + + * po/Make-in (install-info): New target. + +Tue May 5 18:28:40 1998 Tom Tromey <tromey@cygnus.com> + + * gprof.h (_): Undefine BFD's version. + +Tue Apr 28 19:17:33 1998 Tom Tromey <tromey@cygnus.com> + + * gprof.c (main): Conditionally call setlocale. + * gprof.h: Include <locale.h> if HAVE_LOCALE_H. + (LC_MESSAGES): Now can be defined even when ENABLE_NLS. + +Tue Apr 28 19:50:09 1998 Ian Lance Taylor <ian@cygnus.com> + + * corefile.c: Rename from core.c. + * corefile.h: Rename from core.h. + * Many .c files: Include corefile.h rather than core.h. + * Makefile.am (sources): Change core.c to corefile.c. + (noinst_HEADERS): Change core.h to corefile.h. + ($(OBJECTS)): Depend upon corefile.h rather than core.h. + (corefile.o): Rename target from core.o, depend upon corefile.c. + * Makefile.in, po/POTFILES.in: Rebuild. + +Mon Apr 27 16:50:40 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Change version number to 2.9.4 + * configure: Rebuild. + +Wed Apr 22 16:01:17 1998 Tom Tromey <tromey@cygnus.com> + + * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir). + +Wed Apr 22 00:00:22 1998 Tom Tromey <tromey@scribbles.cygnus.com> + + * gprof.h: Added includes and defines for gettext. + * configure.in (ALL_LINGUAS): New macro. + Call CY_GNU_GETTEXT. Create po/Makefile.in and po/Makefile. + * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY, + HAVE_LC_MESSAGES): Define. + * gprof.c (main): Call setlocale, bindtextdomain, textdomain. + * Makefile.am (SUBDIRS): New macro. + (INCLUDES): Look in intl dirs for headers. Define LOCALEDIR. + (gprof_DEPENDENCIES): Added INTLDEPS. + (gprof_LDADD): Added INTLLLIBS. + (POTFILES): New macro. + (po/POTFILES.in): New target. + * Many files: Wrap user-visible strings with gettext invocation. + +Tue Apr 7 12:43:37 1998 Ian Lance Taylor <ian@cygnus.com> + + From hjl@lucon.org <H.J. Lu>: + * Makefile.am (diststuff): New target. + * Makefile.in: Rebuild. + +Mon Mar 30 12:47:48 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Set version to 2.9.1. + * configure: Rebuild. + + * Branched binutils 2.9. + +Sat Mar 28 23:09:08 1998 Ian Lance Taylor <ian@cygnus.com> + + Fix some gcc -Wall warnings: + * cg_arcs.c (num_cycles): Change to unsigned int. + (numarcs): Likewise. + (arc_add): Change maxarcs to unsigned int. + (cg_assemble): Change index to unsigned int. + * cg_arcs.h (num_cycles, numarcs): Update declarations. + * cg_print.c (cg_print): Change index to unsigned int. + (cg_print_index): Change index, nnames, todo, i, and j to unsigned + int. + (cg_print_file_ordering): Change symbol_count and index2 to + unsigned int. + * core.c (symbol_map_count): Change to unsigned int. + (core_create_function_syms): Change j to unsigned int. + (core_create_line_syms): Add cast to avoid warning. + * hist.c (hist_assign_samples): Change j to unsigned int. + (hist_print): Change index to unsigned i nt. Add cast to avoid + warning. + * sym_ids.c (parse_spec): Add casts to avoid warning. + * symtab.c (symtab_finalize): Change j to unsigned int. + (sym_lookup): Update printf format strings. + * symtab.h (Sym_Table): Change len to unsigned int. + * tahoe.c (tahoe_reladdr): Add casts to avoid warnings. + +Tue Mar 24 19:00:11 1998 Ian Lance Taylor <ian@cygnus.com> + + Add --demangle and --no-demangle options: + * gprof.h (demangle): Declare. + * gprof.c (demangle): New global variable. + (OPTION_DEMANGLE, OPTION_NO_DEMANGLE): Define. + (long_options): Add "demangle" and "no-demangle". + (usage): Mention --demangle and --no-demangle. + (main): Handle OPTION_DEMANGLE and OPTION_NO_DEMANGLE. + * utils.c (print_name_only): Only demangle symbol name if demangle + is true. + * gprof.texi (Output Options): Document new options. + +Fri Mar 20 19:21:56 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in: Rebuild with automake 1.2e. + * aclocal.m4, configure: Rebuild with libtool 1.2. + +Thu Feb 12 14:36:05 1998 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (usage): Update bug-gnu-utils address. + +Sat Feb 7 15:43:12 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure, aclocal.m4: Rebuild with new libtool. + +Fri Feb 6 12:02:28 1998 Ian Lance Taylor <ian@cygnus.com> + + * alpha.c (alpha_Instruction): Use int, not signed. + +Fri Feb 6 02:00:19 1998 Jeffrey A Law (law@cygnus.com) + + * core.c (core_init): Adding missing "break". + +Thu Feb 5 12:49:37 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure, Makefile.in, aclocal.m4: Rebuild with new libtool. + +Tue Feb 3 14:25:25 1998 Brent Baccala <baccala@freesoft.org> + + * bbconv.pl: New file. + * Makefile.am (EXTRA_DIST): Add bbconv.pl. + * Makefile.in: Rebuild. + + * gprof.texi: Extensive additions to document all arguments and + output formats. + + * symtab.c (symtab_finalize): Prefer function symbols over line + symbols. + (dbg_sym_lookup): Correct debugging messages. + + * gprof.c (main): --sum implies --line. + + * cg_print.c (cg_print): When doing line by line profiling, don't + use a non-function as a main listing item. + + * call_graph.c (cg_tally): When using line by line profiling, use + the function symbol as the child. + + * symtab.h (NBBS): Define. + (Sym): Add bb_addr and bb_calls fields. + * basic_blocks.c (bb_read_rec): Save multiple basic blocks per + symbol. + (bb_write_blocks): Adjust for multiple basic blocks per symbol. + (print_exec_counts): Don't check whether a symbol is the start of + a basic block. Print all basic blocks for a symbol. + (annotate_with_count): Rewrite to print all basic block counts and + to pay attention to width argument. + (print_annotated_source): Don't check whether symbol is the start + of a basic block. + + Make it possible to build a cross gprof, although a few cases are + still not handled: + * configure.in: Don't set MY_TARGET. + * gprof.h: Don't include MACHINE_H. Don't define FOPEN_RB or + FOPEN_WB; just get them from sysdep.h. + * core.h (min_insn_size, offset_to_code): Declare. + * core.c (MIN_INSN_SIZE): Don't define. + (min_insn_size, offset_to_code): New variables. + (core_init): Initialize min_insn_size and offset_to_code. + (find_call): New function. + (core_create_line_syms): Don't use min_dist. Set is_static in + pass 2. + * hist.c (UNITS_TO_CODE): Define. + * gprof.c (default_excluded_list): Add "__mcount_internal". + * gmon.h: Change TARGET_alpha to __alpha__. + * hertz.h: Ifdef MACH, define hertz as HZ. + * alpha.c (alpha_Instruction): Rename from Instruction. Change + all references. + (alpha_find_call): Rename from find_call. + * alpha.h: Remove. + * dummy.c, dummy.h: Remove. + * i386.c (i386_iscall): Rename from iscall. Change all + references. Check for call instruction, not jump or lcall. + (i386_find_call): Rename from find_call. Correct for VMA. + Correct call destination computation. Don't dereference symbol if + it is NULL. + * i386.h: Remove. + * ns532.c, ns532.h: Remove. + * sparc.c (CALL): Define. + (sparc_find_call): Rename from find_call. + * sparc.h: Remove. + * tahoe.c: Include cg_arcs.h, core.h, hist.h, and symtab.h. Don't + include time_host.h. + (CALLF, PC): Define. + (enum tahoe_opermodes, tahoe_operandenum): Define. Rename all + references to opermodes or operandenum to these. + (tahoe_operandmode): Rename from operandmode. Call abort if + switch does not return. + (tahoe_operandname): Rename from operandname. Call abort if + switch does not return. + (tahoe_operandlength): Rename from operandlength. Call abort if + switch does not return. + (tahoe_reladdr): Rename from reladdr. + (tahoe_find_call): Rename from find_call. Use core_text_space + rather than textspace. + * tahoe.h: Remove. + * vax.c (CALLS, PC): Define. + (enum opermodes, operandenum, struct modebyte): Define. + (vax_operandmode): Rename from operandmode. Call abort if switch + does not return. + (vax_operandname): Rename from operandname. Call abort if switch + does not return. + (vax_operandlength): Rename from operandlength. Call abort if + switch does not return. + (vax_reladdr): Rename from reladdr. + (vax_find_call): Rename from find_call. + * vax.h: Remove. + * Makefile.am (AUTOMAKE_OPTIONS): Set to cygnus. + (MY_TARGET): Remove. + (INCLUDES): Remove -DTARGET_$(MY_TARGET) and -DMACHINE_H= + \"$(MY_TARGET).h\". + (gprof_SOURCES): Add i386.c, alpha.c, vax.c, tahoe.c, sparc.c. + (gprof_DEPENDENCIES): Remove $(MY_TARGET).o. + (gprof_LDADD): Likewise. + (noinst_HEADERS): Remove alpha.h, i386.h, ns532.h, sparc.h, + tahoe.h, vax.h, dummy.h. + (EXTRA_DIST): Remove alpha.c, i386.c, ns532.c, sparc.c, tahoe.c, + vax.c, dummy.c. + ($(OBJECTS)): Don't depend upon $(MY_TARGET).h. + ($(MY_TARGET).o): Remove target. + (i386.o, alpha.o, vax.o, tahoe.o, sparc.o): New targets. + * configure, Makefile.in, aclocal.m4: Rebuild. + +Mon Dec 29 14:17:08 1997 Ian Lance Taylor <ian@cygnus.com> + + * core.c (core_sym_class): Treat weak symbols as text symbols. + From Dean Gaudet <dgaudet@arctic.org>. + +Wed Sep 24 11:35:43 1997 Ian Lance Taylor <ian@cygnus.com> + + * aclocal.m4: Rebuild with new libtool. + * Makefile.in: Rebuild with current automake. + * configure: Rebuild. + +Sat Aug 9 16:25:01 1997 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Change version number to 2.8.2. Call + AM_PROG_LIBTOOL. Remove shared library handling; now handled by + libtool. Add AM_CONFIG_HEADER. Change AC_PROG_INSTALL to + AM_PROG_INSTALL. Add AM_EXEEXT. + * Makefile.am (LINK): Remove. + (gprof_LDFLAGS): Remove + (gprof_DEPENDENCIES): Change libbfd.a to libbfd.la. + (gprof_LDADD): Likewise. + ($(OBJECTS)): Depend upon gconfig.h and ../bfd/config.h. + * gprof.h: Undefine PACKAGE and VERSION after including BFD + sysdep.h file, then include new gconfig.h file. + * gprof.c (VERSION): Don't define. + * acconfig.h: New file. + * stamp-h.in: New file. + * gconfig.in: New file, created by autoheader. + * Makefile.in, configure, aclocal.m4: Rebuild. + +Sat Jun 28 23:20:42 1997 Ian Lance Taylor <ian@cygnus.com> + + * aclocal.m4, configure, Makefile.in: Rebuild with automake 1.2. + +Mon Jun 16 15:31:39 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (INCLUDES): Add -DDEBUG. + * Makefile.in: Rebuild. + +Tue Apr 15 14:19:30 1997 Ian Lance Taylor <ian@cygnus.com> + + Change to use automake: + * Makefile.am: New file. + * configure.in: Run AM_INIT_AUTOMAKE, AM_MAINTAINER_MODE, and + AM_CYGWIN32. + * aclocal.m4: New file, created by aclocal. + * Makefile.in: Replace with file created by automake --cygnus. + * configure: Rebuild. + +Thu Apr 3 13:21:25 1997 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (VERSION): Define as "2.8.1". + + * Branched binutils 2.8. + +Thu Mar 27 17:15:23 1997 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (main): Correct copyright message. + +Mon Mar 24 11:12:26 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (.c.o): Define TARGET_$(MY_TARGET) when compiling. + * gmon.h: Use bytes counts rather than sizeof in struct raw_phdr + and struct raw_arc. + +Mon Mar 17 10:54:47 1997 David Mosberger-Tang <davidm@azstarnet.com> + + * cg_arcs.c (arc_add): memset() newly alloced arc to ensure + all fields are initialized with 0. + +Sat Mar 15 19:17:31 1997 H.J. Lu <hjl@lucon.org> + + * symtab.h (find_call): Declare. + * cg_arcs.c (cg_assemble): Don't declare find_call. + * hist.c (scale_and_align_entries): Declare. + +Thu Feb 27 12:46:53 1997 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Define BSD44_FORMAT if the target looks like a + BSD4.4 derived system. + * configure: Rebuild. + * Makefile.in (.c.o): Add @DEFS@. + * gmon_io.c (gmon_out_read): In BSD44_FORMAT code, get profrate + from profrate field, not version field. + +Thu Jan 16 17:42:54 1997 Ian Lance Taylor <ian@cygnus.com> + + * dummy.c (find_call): Clear ignore_direct_calls. + +Tue Dec 31 15:44:10 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (.c.o): Add -D_GNU_SOURCE. Put $(CFLAGS) at the + end. + (gprof): Put $(CFLAGS) after the other options. + +Tue Nov 26 17:08:38 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure: Rebuild with autoconf 2.12. + +Wed Oct 2 15:23:16 1996 Ian Lance Taylor <ian@cygnus.com> + + * sparc.c (find_call): Align p_lowpc to avoid bus error. + +Tue Oct 1 15:58:10 1996 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (usage): Print bug report address. + (main): Change version printing to match current GNU standards. + +Fri Aug 30 12:16:11 1996 Ian Lance Taylor <ian@cygnus.com> + + * gmon.h: Replace #elif with #else/#endif. + +Thu Aug 29 17:04:10 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.in (i[345]86-*-*): Recognize i686 for pentium pro. + * configure: Regenerate. + +Thu Aug 22 17:12:30 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Set and substitute HLDENV. + * configure: Rebuild. + * Makefile.in (HLDENV): New variable. + (gprof): Use $(HLDENV). + +Wed Aug 7 14:43:51 1996 Philippe De Muyter <phdm@info.ucl.ac.be> + + * core.c (read_function_mappings): Cast xmalloc return. + +Thu Jul 4 12:01:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (VERSION): Define as "2.7.1". + + * Released binutils 2.7. + + * bb_exit_func.c: Rename from __bb_exit_func.c, so that it can be + stored on a System V file system. + +Thu Jun 27 11:36:22 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Call AC_ISC_POSIX. + * configure: Rebuild. + * Makefile.in (gprof): Pass $(CFLAGS) during link. + * hertz.c: Don't include <sys/time.h>; let sysdep.h handle that. + If HAVE_SETITIMER is not defined, try using sysconf. + +Mon Jun 24 18:27:28 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (exec_prefix, bindir, libdir, mandir, infodir, datadir, + INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values. + * configure.in (AC_PREREQ): autoconf 2.5 or higher. + (AC_PROG_INSTALL): added. + * configure: Rebuilt. + +Mon Jun 24 12:03:09 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: On alpha*-*-osf*, link against libbfd.a if not + using shared libraries. + * configure: Rebuild with autoconf 2.10. + +Tue Jun 18 17:35:58 1996 Ian Lance Taylor <ian@cygnus.com> + + * core.c (core_create_line_syms): Use xstrdup rather than strdup. + * source.c (source_file_lookup_path): Likewise. + +Mon Apr 8 14:44:33 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Permit --enable-shared to specify a list of + directories. + * configure: Rebuild. + +Thu Mar 21 17:18:25 1996 Ian Lance Taylor <ian@cygnus.com> + + * core.c (core_create_function_syms): Move filename and func_name + inside ifdef where they are used. + + * core.c (core_sym_class): Parenthesize && within ||. + * symtab.c (symtab_finalize): Correct parenthesization. + + * cg_print.h (cg_print_file_ordering): Declare. + (cg_print_function_ordering): Declare. + + * __bb_exit_func.c (__bb_exit_func): Replace bcopy with memcpy. + * cg_arcs.c (arc_add): Likewise. + * cg_print.c (cg_print_function_ordering): Likewise. + +Thu Mar 21 17:02:02 1996 David Mosberger-Tang <davidm@azstarnet.com> + + * gprof.c (default_excluded_list): Add "__mcount". + + * gprof.c (main): Change ifdef __osf__ to __alpha__. + + * gmon_io.c (gmon_out_read): If BSD44_FORMAT is defined, get the + profiling rate from the header. + + * gmon.h (struct raw_phdr): Only include pad if both __alpha__ and + __osf__ are defined. Add new fields if BSD44_FORMAT is defined. + + * alpha.h (MIN_INSN_SIZE): Define. + * core.c (MIN_INSN_SIZE): If not defined, define as 1. + (core_sym_class): Ignore debugging symbols. + (core_create_line_syms): Use MIN_INSN_SIZE when gathering line + information. + +Wed Mar 20 18:15:47 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * cg_print.c (cg_print_function_ordering): Fix __GNUC__ misspelled + as __GNU_C__. + (order_and_dump_functions_by_arcs): Likewise. + +Tue Mar 12 12:19:50 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure: Rebuild with autoconf 2.8. + +Sun Feb 18 15:06:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Check for 'do not mix' from native linker before + trying to use -rpath. + * configure: Rebuild. + +Tue Feb 13 15:32:53 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Set HDLFLAGS for *-*-hpux with --enable-shared. + * configure: Rebuild. + +Wed Feb 7 14:03:17 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Don't set CC. Look for --enable-shared. Set + BFDLIB and HLDFLAGS and substitute them. + * configure: Rebuild. + * Makefile.in (LIBS): Use @BFDLIB@. + (HLDFLAGS): New variable. + (gprof): Use $(HLDFLAGS). + +Mon Feb 5 16:34:44 1996 Ian Lance Taylor <ian@cygnus.com> + + Support for building bfd and opcodes as shared libraries, based on + patches from Alan Modra <alan@spri.levels.unisa.edu.au>: + * Makefile.in (LIBDEPS): New variable. + (LIBS): Use -L../bfd -lbfd. + (gprof): Depend upon $(LIBDEPS) rather than $(LIBS). + +Sat Dec 30 10:11:03 1995 Jeffrey A Law (law@cygnus.com) + + * gprof.c (long_options): Add "--function-ordering" and + "--file-ordering" options. + (usage): Add new options to usage message. + (main): Handle new options. + * gprof.h (STYLE_FUNCTION_ORDER): Define. + (STYLE_FILE_ORDER): Define. + (function_mapping_file): Declare. + * cg_arcs.c (arcs, numarcs): New globals. + (arc_add): Put new arcs into the arc array so the function/file + ordering code can examine them. + * cg_arcs.h (struct arc): New field "has_been_placed". + (arcs, numarcs): Declare new globals. + * core.c (symbol_map, symbol_map_count): New globals. + (read_function_mappings): New function to read in a function + to object map file. + (core_init): Call read_function_mappings if a function mapping + file exists. + (core_create_function_syms): Handle function to object file + mappings. + * symtab.h (struct sym): New fields "mapped", "has_been_placed", + "nuses", "prev". + * cg_print.c (cmp_arc_count): New function for sorting arcs. + (cmp_fun_nuses): Likewise for functions. + (cg_print_function_ordering): New function to print a suggested + function ordering. + (cg_print_file_ordering): Likewise for ordering .o files. + (order_and_dump_functions_by_arcs): Helper function for function + and object file ordering code. + +Sun Dec 24 21:32:27 1995 Jeffrey A Law (law@cygnus.com) + + * core.c (core_sym_class): Ignore symbols without BSF_FUNCTION + set if ignore_non_function is set. + * gprof.h (ignore_non_functions): Declare. + * gprof.c (ignore_non_functions): Define. + (long_options): Add "ignore-non-functions". + (usage): Add new options. + (main): Recognize "-D" and "--ignore-non-functions" option. + +Tue Nov 21 13:24:39 1995 Ken Raeburn <raeburn@cygnus.com> + + * Makefile.in (.m.c): Strip out directory name from function + name. + + * hist.c (scale_and_align_entries): Don't use DEFUN_VOID. Do + UNITS_TO_CODE adjustment unconditionally; compiler can optimize + away zero-offset case. Refer to scaled_addr, not aligned_addr. + + * vax.c: Don't include vax.h here. + +Thu Nov 16 03:41:37 1995 Ken Raeburn <raeburn@cygnus.com> + + Version 2.6 released. + +Wed Nov 8 11:40:04 1995 Ian Lance Taylor <ian@cygnus.com> + + * gprof.c (main): Cast getenv return value. + +Mon Nov 6 15:05:00 1995 Ken Raeburn <raeburn@cygnus.com> + + * Makefile.in (TAGS): New target. + +Wed Nov 1 12:51:21 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * Makefile.in (DISTSTUFF): Rename to GEN_FILES, to avoid confusion. + (all): Depend on $(GEN_FILES), not diststuff (which also depends + on info). + +Wed Nov 1 15:23:15 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de> + + * sym_ids.c: Include <ctype.h>. + +Wed Oct 25 13:24:31 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * Makefile.in (diststuff): Also make info. + (mostlyclean): Don't remove gprof.info*. + (maintainer-clean realclean): Also remove *.info*. + +Fri Oct 6 16:25:32 1995 Ken Raeburn <raeburn@cygnus.com> + + Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * Makefile.in: Add dependecies for $(OBJS) on header files. + + * cg_print.c (print_cycle, print_members, cg_print_index): Fix new + style output format to make it consistent. + * dummy.c (find_call): Fix typo in error message. + +Wed Sep 20 13:21:02 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (maintainer-clean): New target, synonym for + realclean. + +Fri Sep 8 14:38:08 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (install): Don't install in $(tooldir). + +Fri Aug 25 15:30:05 1995 Ken Raeburn <raeburn@cygnus.com> + + NS32K changes from Ian Dall: + * configure.in: Use ns32k, not ns532. + * ns532.c: Include symtab.h. + (find_call): Renamed from findcall. Print a message. + * ns532.h: Remove dummy.h comments. + +Tue Aug 22 10:00:45 1995 Jeffrey A. Law <law@rtl.cygnus.com> + + * Makefile.in (install): Remove "brokensed" hack, unnecessary now + that we're using autoconf. + +Wed Jul 19 18:46:13 1995 Fred Fish <fnf@cygnus.com> + + * core.c (get_src_info): Cast arg 7 of bfd_find_nearest_line + to proper type of "unsigned int *". + +Fri Jun 16 15:29:36 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * configure.in: Use changequote around use of []. + +Mon Jun 12 12:14:52 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * Makefile.in (distclean, realclean): Remove config.cache and + config.log. + +Wed May 17 17:56:53 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * Makefile.in (Makefile): Added config.status to dependency list. + (config.status): New target. + (SHELL): New definition. + +Tue Apr 25 21:11:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in (install): Depend on "all". + +Thu Apr 20 17:29:07 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in: Change all references to MY_MACHINE to MY_TARGET, + to match configure script. + +Wed Apr 19 11:19:37 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * gen-c-prog.awk: Changed reference to "make-c-prog.awk" in + comment emitted by this script to gen-c-prog.awk. + + * Makefile.in, configure.in: Converted to use autoconf. + * configure: New file, generated with autoconf 2.3. + * config/{mt-alpha, mt-dummy, mt-i386, mt-ns532, mt-sparc, + mt-tahoe, mt-vax}: Removed. + +Mon Mar 13 21:44:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * __bb_exit_func.c: New file, from David Mosberger-Tang. + + Thu Feb 9 16:56:07 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu> + + * All *.c: More cleanup towards GNU format. + + * gmon_out.h (struct gmon_hist_hdr, struct gmon_cg_arc_record): + replaced sizeof (bfd_vma) by size (char*) because Ken tells me + that bfd_vma is only guaranteed to be at least as big as a pointer. + + (GMON_Record_tag): added explicit enumeration values to ensure + compatibility across compilers. + + * gmon_io.c (get_vma, put_vma): replaced sizeof(bfd_vma) by + sizeof(char*). + +Tue Feb 7 17:24:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * All *.c and *.h files: Ran "indent -gnu". Cleaned up a couple + of constructs GNU indent couldn't handle. Block comments not yet + rewritten in GNU format. + + * gprof.c (VERSION): Changed to 2.6, to get in sync for next + binutils release. + +Sun Feb 5 16:19:46 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu> + + * symtab.c (symtab_finalize): ensure globals symbols really + are favored over static ones---even if their name looks less + preferable; this is important for HP-UX; for example, there + is a static label Ltext_something that aliases the global + symbol _start + + * hist.c (hist_print): auto-scaling is now in effect for FSF-style + output only; also, auto-scaling is now performed based on + per-call, rather than total execution time, which is what it was + meant to be. + + * gprof.h (File_Format): new type. + + * gprof.c (VERSION): upped to 2.7---seems to be completely out of + sync with Cygnus version numbers though... + + (long_options): renamed --gmon-info to --file-info, --width added, + renamed --old-file-format to --file-format + (main): dito; also added support to read prof files, but as + mon_out_read() is not implemented, it's #ifdef'd out for now + + (usage): update to reflect new options. + + * gmon_io.c: replaced "old_file_format" by more general + "file_format" option + + * gmon.h (struct raw_phdr): fixed declaration for OSF/1. + + * core.c (core_sym_class): added back check for __gnu_compiled and + ___gnu_compiled for the benefit of systems without + bfd_find_nearest_line() support + + (get_src_info): now the libbfd is fixed, invoke bfd_find_nearest_line() + with section-relative addresses + + (core_create_function_syms): get_src_info() calls are currently + enabled for OSF/1 only. It appears to work allright for SunOS + 4.1.x as well, but on SPARCs it gets painfully slow with the + current implementation of aout_32_find_nearest_line(); + unfortunately, this means that static functions will not have their + filename printed in the call-graph function index; line-level + profiling should still work, but requires some patience + + * cg_print.c (cg_print_index): sanitised printing of index when + using FSF-style output; in particular, output width is now controlled + via option --width and the function tries hard to keep columns + aligned even in the presence of (occasional) long names + + * NOTES: a first shot at updating the documentation. + +Wed Feb 1 19:07:44 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu> + + * core.c (core_create_function_syms): fixed computation of min_vma + and max_vma. + + * *.c: removed rcsid. + +Tue Jan 31 16:18:18 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Lots of changes from David Mosberger-Tang: + + Tue Oct 25 19:20:14 1994 David Mosberger-Tang <davidm@piston.cs.arizona.edu> + + * gprof.c (main): put parentheses around & within &&. + + * basic_blocks.c (bb_read_rec): print warning message (once) when + ignoring basic-block execution counts. + + * source.c (source_file_lookup_name): corrected second argument to + strcmp(). + + * hist.c (print_header): merged Fri Oct 21 18:58:02 1994 change by + Ken Raeburn <raeburn@cujo.cygnus.com> from binutils-2.5.1. + + * gmon_io.c (gmon_out_read): the output stule STYLE_GMON_INFO is now + supported both for old and new (versioned) gmon.out files. Old + files are identified as version 0. + + * gmon.h (struct raw_arc): count field is now sizeof(long) bytes + long (instead of 4) because that is what OSF/1 v3.0 uses. + + * core.c: minor fixes and debugging info changes. + + Sun Sep 11 18:47:47 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * core.c (core_init): if .text cannot be found, try $CODE$ (the + name of the text-section under HP-UX). + + * hist.c (hist_assign_samples): fixed off-by-one bug: highpc + points one past the last sampling bin, so hist_scale should be + computed as "hist_scale /= hist_num_bins", not "hist_scale /= + hist_num_bins - 1". + + * gmon_io.c, hist.c, hist.h: renamed hist_num_samples to + hist_num_bins. + + * configure.in: added alpha-*-*) for per-target config. + + * alpha.c, alpha.h: created. + + * gprof.c (default_excluded_list): <locore>, <hicore> added. + + * core.c (core_create_function_syms, core_create_line_syms): + explicitly keep two sentinels "<locore>" and "<hicore>" that catch + all addresses outside the text-space. Thus, sym_lookup(&symtab, + addr) continues to guarantee not to return 0 on any address. It + also avoids incorrectly crediting the first/last symbol in the + text-space. + + * core.c (core_create_line_syms): always create function symbols + first, then merge in line symbols; this is so that if parts of the + program were compiled without -g, function-level symbols are + available still. + + * utils.c (print_name_only): support for print_path added. + + * symtab.c (cmp_addr): also use is_func flag in comparison. + (symtab_finalize): return immediately when table empty; now + more careful about getting rid of the right duplicate symbol. + + * sparc.c (find_call): many fixes---this function was rather + botched in binutils-2.4 already; it should work again. + + * source.c (source_file_lookup_path): PATH is now strdup'ed (it is + not good to rely on get_src_info() to return distinct string + pointers). + + * search_list.c (search_list_append): added cast for xmalloc(). + + * hist.c: added explicit initialization to some of the global + variables; fixed SItab (scales were off by a factor of 10). + + * hist.h: include of bfd.h added. + + * gprof.c, gprof.h (print_path): added. + + * gprof.h (MAX): fixed. + + * gmon_out.h: renamed gmon_time_hist_hdr to gmon_hist_hdr. + + * gmon_io.c: added some casts to (long) so we can always print as %lx + + * core.c (core_get_text_space): fixed to make it work. + + * cg_print.c (cg_print_index): added support for print_path option. + + * cg_dfn.h (cg_dfn): wrap prototype in PARAMS(). + + * call_graph.c, gmon_io.c, hist.c: avoid taking address of array + as some compilers complain (e.g., DEC's OSF/1 compiler) + + * basic_blocks.c, gmon_io.c, hist.c, source.c, sym_ids.c, + symtab.c: calls to memset() had 2nd and 3rd args reversed. + + Sat Sep 10 21:53:13 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gprof.c: added "_mcount" to default_excluded_list. + (main): if output_style==0 and there is either a histogram or a + call-graph, always generate flat and call-graph, no matter what + line_granularity is set to. + + * source.c (source_file_lookup_name): if searching for sf->name + fails, try again with filename obtained after stripping off any + partial path from sf->name. + + * gprof.h (SRCDEBUG): added. + + * search_list.c (search_list_append): directories were added in wrong + order. + + * reimplemented selection mechanism from ground up; it is now possible + to accurately control what gets included/excluded in each of the + output styles; a "symbol-specification" (spec) is the basic means + to select a set of symbols; a spec has the syntax: + + spec == (FILENAME:(FUNCNAME|LINE_NUM) | NAME). + arc == spec/spec. + + any of the terminal symbols can be empty, in which case they + match anything (wildcards). NAME is interpreted as a FILENAME + if it contains a dot (e.g., foo.c), as LINE_NUM if it starts + with a digit, and as FUNCNAME otherwise. + + For example, to get a call-graph display that ignores arcs + from foo() to bar(), you'd say "--no-graph=foo/bar"; to + show only arcs into bar() (no matter what the caller), + you'd say "--graph=/bar"; and to get a call-graph without + any arc info, you'd say "--graph=/"; similarly, to + get a flat profile without mcount, you'd say "--no-flat=mcount" + and to get a flat profile that shows includes all functions + you'd say "--flat=""" (i.e., an empty spec) + + * hist.c (hist_print): top_time wasn't initialized to 0.0. + + Fri Sep 9 01:10:21 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gmon_out.h: all headers now declared in terms of characters + to avoid getting into trouble with different compilers introducing + different amount of padding; the code already accessed the fields + through bfd functions, so that didn't have to change. + + * hist.c (hist_read_rec, hist_write_rec): added support for + collection pc histograms measuring quantities other than time; + the histogram header now includes a field that specifies the + dimension of the quantity measured by the histogram bins + (normally, this is "seconds", but other meaningful dimensions + include such things as "I-cache misses", "instruction issue stalls" + etc.); there is also a field to specify a one-character + abbreviation for the dimension; in the case of time, this would + be 's'; in most other cases it probably would be '1' (not a physical + dimension). + + Thu Sep 8 16:05:08 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gprof.c, gmon_io.[ch]: BSD_COMPATIBLE is gone and new_file_version + has become old_file_version; gmon_io.c now always supports old-style + gmon.out files; it first tries to read gmon.out as a new version + file, if that fails, it tries to read it in the old format; + although not very likely, it is possible for gprof to mistake an + old-style file as a new one (the first 4 bytes would have to + be "gmon"---including the trailing '\0'); in that case, it is + necessary to specify --old-file-version + + * gprof.h: removed dependency on SYSV; the code now always uses + strrchr(), memset(), and memcpy() and does not include either + of string.h or strings.h; this should make gprof compile on + any (Unix) system without configuration (per suggestion of + raeburn@cygnus.com) + + * gprof.c (usage): fixed location of --new-file-format option. + + * cg_arcs.c (propagate_flags): fixed typo in declaration. + + * flat_bl.m: removed formfeed at end of file; the form-feed + is now printed cg_print.c only when necessary. + + * major rewrite of gprof---too many changes to mention all of + them. new features: + + + -l now requests profiling at the line level (as opposed + to function level); in this mode, gprof creates a "symbol" + (aka name-list entry) for each line of source code, instead + of one per function) + + + support for a new gmon.out file format; the new format + consists of a header with a magic and a version number, + followed by a sequence of profile data; profile data + can any of: (a) PC histogram, (b) call-graph arcs, or + (c) basic-block execution counts; the version number makes + it possible to extend gmon.out in a backwards compatible + fashion + + + support for tcov style annotated output: if the gmon.out file + contains basic-block execution counts, the user can request + the generation of annotated source files, much like Sun's + tcov used to do + + + long options + + + new scheme to suppress symbols that aren't function names + (e.g., avoids mistaking a goto label as a function) + + + reorganized source code to make it more managable; as a + side effect, gprof now compiles cleanly with "gcc -Wall" + + Thu Sep 1 15:46:49 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gprof.c (funcsymbol): bfd_find_nearest_line() is now used as a + final cross-check to determine whether a static symbol should be + considered as a function-name. + + Fri Aug 5 19:32:36 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gmon_io.c (gmon_out_read): recognize "-" as the filename for + stdin; this is useful if you wanna keep gmon.out files compressed; + this way you can "gzcat" the compressed file into gprof. + + * gprof.c: flag_min_count now initialized with 1 instead of 0. + + * basic_blocks.c (bb_annotate_source): added support for creating + .tcov files when option flag_annotate_make_files is TRUE. + (annotate_with_count): all counts less than the minimum count + specified by -m are now annotated with hash-marks. + + * gprof.c (main): -A is now followed by a string of option chars. + + * basic_blocks.c (annotate_with_count): replaced b->count with + cnt. + + * source.c: flag_annotate_source replaced by source_lock_map. + + * source.h: source_lock_map added. + + * gprof.c (main): new command-line syntax: -S simply specifies + which source-files user is interested in; -A requests annotated + source files and -AA requests that all lines in a source file + are annotated. + + Thu Aug 4 23:27:03 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * basic_blocks.c (PATH_MAX): if undefined, define as 1024. + + * sparc.c, i386.c, tahoe.c, vax.c: added include of "time_hist.h" + so s_lowpc etc. get declared. + + * arcs.h (doarcs): created. + + * arcs.c: reordered static functions such that they get defined + before use. + + * gprof.c (main): added options: + -A: request annotation of all source lines (with -S) + -m: minimum execution count (with default basic-block display) + -N: force new file format (only if BSD_COMPATIBLE is defined) + -S: annotate source file + -t: set table length (with -S) + + * Makefile.am (OBJS): added basic_blocks.o call_graph.o gmon_io.o + source.o time_hist.o + + Fri Jul 1 15:23:50 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu) + + * gprof.c (asgnsamples): computation of "pcl" and "pch" depended + on the fact being able to store a long in a double without loss of + precision; this does not hold on machines with 64 bit longs and 64 + bit doubles. + +Fri Oct 21 18:58:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * printgprof.c (flatprofheader): Always set totime to 1.0 if not + greater than 0.0. Suggested by Harold Assink + <carlo@sg.tn.tudelft.nl>. + +Fri Sep 23 15:06:45 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * printgprof.c (printprof): Use free, not cfree. + (printgprof, printindex): Ditto. + +Thu Sep 1 10:40:45 1994 Jeff Law (law@snake.cs.utah.edu) + + * gprof.h (kfromlist, ktolist, flist, Flist, elist, Elist): Make + decls extern to keep native HP compiler quiet. + +Tue Aug 30 11:12:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * gprof.c (funcsymbol): Ignore ___gnu_compiled as well as + __gnu_compiled, for the benefit of systems which add a leading + underscore. + +Wed Aug 24 12:49:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * configure.in: Change i386-*-* to i[345]86-*-*. + +Sun Jul 10 00:35:31 1994 Ian Dall (dall@hfrd.dsto.gov.au) + + * ns532.c, ns532.h: New Files. ns532 support. + + * config/mt-ns532: New File. ns532 support. + + * gprof.c: user register int i instead of defaulting the int. + Allows compilation with -Dregister= for debugging. + + * configure.in: Add ns532 support. + +Thu Jun 23 11:22:41 1994 Jeff Law (law@snake.cs.utah.edu) + + * Makefile.in (gprof): Depend on $(LIBS). + +Fri May 27 12:24:57 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + From binutils-2.4 release: + + Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com) + + * configure.bat: [new] build makefile from makefile.in (dos) + * hertz.c: allow static HERTZ (msdos needs it) + * gprof.c: allow target to select "r" or "rb" for fopen + * gprof.c: ignore __gnu_compiled symbols + * i386.h: dfine FOPEN_RB to "rb" for dos. + +Tue May 17 15:30:22 1994 E. Michael Smith (ems@cygnus.com) + + * Makefile.in (.m.c:): Added .SUFFIXES : .m + so flat_bl.c would make from flat_bl.m file. + +Thu May 5 19:23:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * Makefile.in (install-info): Check for gprof.info in build dir, + fall back to srcdir. Depend on it. + + * gprof.h (TRUE, FALSE): Always use undef before defining them. + +Mon Apr 4 23:47:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * Makefile.in (MY_MACHINE): Renamed from MACHINE to avoid losing + makes (osf1) in which the value of MACHINE can not be changed. + * config/*.mt: Changed appropriately. + +Wed Mar 30 16:12:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * gprof.c (getsymtab): Change nosyms to long. Rename + get_symtab_upper_bound to bfd_get_symtab_upper_bound. Check for + errors from bfd_get_symtab_upper_bound and + bfd_canonicalize_symtab. + +Tue Mar 22 10:50:52 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * gprof.c (funcsymbol): Use bfd_get_symbol_info instead of + bfd_decode_symclass. + +Sun Mar 20 15:40:21 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * Makefile.in: Avoid bug in hpux sed. + +Wed Dec 15 20:16:40 1993 david d `zoo' zuhn (zoo@andros.cygnus.com) + + * gprof.texi (Invoking): add text about -v flag + + * gprof.1: add text about -v flag + +Wed Dec 8 16:55:06 1993 david d `zoo' zuhn (zoo@andros.cygnus.com) + + * gprof.c (VERSION): defined a version macro, print the value + when the -v option is used + +Tue Jul 6 10:11:56 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) + + * Makefile.in: Install correctly. + +Thu Jun 24 14:43:22 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * gprof.c (main): Get whoami from argv, instead of hardcoding. + Use it in usage message. Split usage message to fit in 80 cols. + +Sun Jun 20 20:58:02 1993 Ken Raeburn (raeburn@poseidon.cygnus.com) + + * Makefile.in: Undo 15 June change. + +Wed Jun 16 12:54:53 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) + + * gmon.h, gprof.h: structs of chars used to hold external + representations. + * gprof.c (getpfile, openpfile, readsamples): Swap data in using + new structures. + +Tue Jun 15 23:09:17 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * Makefile.in (.c.o): Look in ../include, not ../bfd, for bfd.h. + +Mon Jun 14 16:22:59 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) + + * Makefile.in: remove parentdir support + +Mon Jun 7 12:56:17 1993 Per Bothner (bothner@rtl.cygnus.com) + + * Makefile.in (INCLUDES): Add -I../bfd for sysdep.h and bfd.h. + * configure.in: No longer need to configure to get sysdep.h. + +Tue May 18 21:44:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in (install): should not depend on install-info + +Mon Apr 26 12:37:46 1993 Ian Lance Taylor (ian@cygnus.com) + + * gprof.h: Include ansidecl.h before sysdep.h. Undefine hz. + +Tue Apr 13 16:14:03 1993 Per Bothner (bothner@cygnus.com) + + * Makefile.in: Add -g to CFLAGS. + Ads LDFLAGS and use in place of CFLAGS where appropriate. + * configure.in: Make a sysdep.hlink in the same way other + bfd-based directories do. + * gprof.h (UNIT): Replace non-standard 'u_short' by 'unsigned + short'. + * gprof.h: #include sysdep.h instead of a bunch of stuff. + * gprof.c (main): Fix typo gproff->gprof. + +Thu Mar 25 19:00:37 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * gprof.texi: add INFO-DIR-ENTRY + +Tue Mar 23 00:03:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: add installcheck target + +Sat Feb 27 18:17:10 1993 Per Bothner (bothner@rtl.cygnus.com) + + * gprof.c (funcsymbol): Invert test for aflag. + +Thu Feb 25 16:01:50 1993 Per Bothner (bothner@rtl.cygnus.com) + + * printgprof (xmalloc, xrealloc): Cast results of malloc + and realloc to PTR. + +Wed Feb 3 13:55:33 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com) + + * Makefile.in: created info, install-info, dvi + +Wed Jan 6 00:58:09 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: fix install rule for $(PROG) + +Fri Oct 9 11:25:41 1992 Mark Eichin (eichin@cygnus.com) + + * gprof.1: updated SYNOPSIS to match actual behavior. + +Mon Oct 5 17:50:16 1992 Per Bothner (bothner@cygnus.com) + + * gen-c-prog.awk: New awk script, lightly changed from + previously deleted make-c-prog.awk. Converts a text file + to a c function that prints that text. + * flat_bl.m, fsf_callg_bl.m, bsd_callg_bl.m: New files. + Inputs to gen-c-prog.awk, containing text describing + gprof output. + * blurbs.c: Removed. Use *_bl.c instead. + * Makefile.in: Use gen-cprog.awk to generate *_bl.c files + from *_bl.m files. Also, improve *clean rules. + * printgprof.c (printgprof): Usw new function names from *_bl.c. + + +Sun Aug 30 19:54:53 1992 Per Bothner (bothner@rtl.cygnus.com) + + * gprof.h, gprof.c, printfgprof.c: Add support for two + output styles: The default is similar to the old FSF gprof, + while -T sets the variable bsd_style_output, which causes + output matching Berkeley's gprof. The biggest differences + are that with the FSF style output, the flat profile comes + before the call graph; numbers come before explanations; + and there is less gratuitous white space. + * gprof.h, gprof.c, printfgprof.c: New discard_underscores + variable causes discarding of initial underscores when + printing symbol names. It is set unless there is a "main" + symbol (without an underscore). + * printfgprof.c: New function printnameonly(), called + by printname(). It handles stripping of initial '_', + as well as C++ name-demangling. + * gprof.callg, gprof.flat, make-c-prog.awk: Removed. + It is just as convenient to edit blurbs.c directly. + * Makefile.in: Removed rule for making blurbs.c. + * blurbs.c: This is now a true source file (as opposed + to being generated from gprof.callg and gprof.flat). + Change style to use one long string literal, instead of + one literal per output line. Add FSF-style blurb for call graph. + +Wed Aug 19 14:36:39 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in: always create installation directories. + +Wed Aug 12 15:14:14 1992 Mark Eichin (eichin@cygnus.com) + + * Makefile.in: change ${MACHINE} to $(MACHINE). + +Sun Jul 19 17:34:01 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: removed installation of the now useless + call.{flag,callg} files. + + * gprof.1: now uses the standard man macros instead of the new BSD + mandoc macros. + +Sun Jul 12 19:06:00 1992 John Gilmore (gnu at cygnus.com) + + * configure.in: Remove host section, expand target section. + * config/mt-{tahoe,vax}: Add, to match existing support files. + * config/tmake-*: Remove leftover crud. + + * blurbs.c: New file, created from gprof.flat and gprof.callg by + * make-c-prog.awk: which processes text files into C programs. + * printgprof.c (flatprofheader, gprofheader): Call new functions + to print blurbs. + (printblurb): Remove. + * Makefile.in: Infrastructure to build blurbs. + * pathnames.h: has been removed. Gprof now has no filename + dependencies in it. + * gprof.c: Lint. + +Sat Jul 11 18:07:21 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: define man1dir and install the man page + +Fri Jul 10 21:14:08 1992 david d `zoo' zuhn (zoo@cygnus.com) + + * Makefile.in: added dummy info and install-info targets + +Thu Jun 4 11:34:02 1992 Mark Eichin (eichin at cygnus.com) + + * lookup.c: fixed fencepost in nllookup and added dbg_nllookup for + help in debugging the problem (with -DDEBUG) + * gprof.c: symbol values are now real values, don't add the vma + anymore. (done for solaris; should verify this on other platforms) + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/gprof/MAINTAINERS b/gprof/MAINTAINERS new file mode 100644 index 000000000000..d59a3bd7f889 --- /dev/null +++ b/gprof/MAINTAINERS @@ -0,0 +1 @@ +See ../binutils/MAINTAINERS diff --git a/gprof/Makefile.am b/gprof/Makefile.am new file mode 100644 index 000000000000..18a0b5206ae7 --- /dev/null +++ b/gprof/Makefile.am @@ -0,0 +1,237 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +SUFFIXES = .m + +SUBDIRS = po + +BASEDIR = $(srcdir)/.. +BFDDIR = $(BASEDIR)/bfd +INCDIR = $(BASEDIR)/include + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + +MKDEP = gcc -MM + +INCLUDES = -D_GNU_SOURCE -DDEBUG -I../bfd -I$(srcdir)/../include -I$(srcdir)/../bfd -I$(srcdir)/../intl -I../intl -I. -DLOCALEDIR="\"$(prefix)/share/locale\"" + +bin_PROGRAMS = gprof + +## Convenience var listing pure sources. +sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \ + cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \ + search_list.c symtab.c sym_ids.c utils.c \ + i386.c alpha.c vax.c tahoe.c sparc.c mips.c +gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c +gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLDEPS) +gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS) + +noinst_HEADERS = \ + basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \ + corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \ + search_list.h source.h sym_ids.h symtab.h utils.h + +BUILT_SOURCES = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c +EXTRA_DIST = $(BUILT_SOURCES) bbconv.pl $(man_MANS) + +diststuff: $(BUILT_SOURCES) info $(man_MANS) + +.m.c: + awk -f $(srcdir)/gen-c-prog.awk > ./$*.c \ + FUNCTION=`(echo $*|sed -e 's,.*/,,g' -e 's/_bl//')`_blurb \ + FILE=$*.m $(srcdir)/$*.m + +POTFILES = $(sources) $(noinst_HEADERS) +po/POTFILES.in: @MAINT@ Makefile + for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \ + && mv tmp $(srcdir)/po/POTFILES.in + +MANCONF = -Dman + +TEXI2POD = perl $(srcdir)/../etc/texi2pod.pl + +POD2MAN = pod2man --center="GNU" --release="binutils-$(VERSION)" --section=1 + +info_TEXINFOS = gprof.texi +man_MANS = gprof.1 + +# Build the man page from the texinfo file +# The sed command removes the no-adjust Nroff command so that +# the man output looks standard. +gprof.1: $(srcdir)/gprof.texi + touch $@ + -$(TEXI2POD) $(MANCONF) -Dgprof < $(srcdir)/gprof.texi > gprof.pod + -($(POD2MAN) gprof.pod | \ + sed -e '/^.if n .na/d' > $@.T$$$$ && \ + mv -f $@.T$$$$ $@) || \ + (rm -f $@.T$$$$ && exit 1) + rm -f gprof.pod + +Makefile: $(BFDDIR)/configure.in + +# We want install to imply install-info as per GNU standards, despite the +# cygnus option. +install: install-info + +# Targets to rebuild dependencies in this Makefile. +# Have to get rid of DEP1 here so that "$?" later includes all sources. +DEP: dep.sed $(gprof_SOURCES) $(noinst_HEADERS) gconfig.h + rm -f DEP1 + $(MAKE) MKDEP="$(MKDEP)" DEP1 + sed -f dep.sed < DEP1 > DEPA + echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> DEPA + if grep ' /' DEPA > /dev/null 2> /dev/null; then \ + echo 'make DEP failed!'; exit 1; \ + else \ + mv -f DEPA $@; \ + fi + +DEP1: $(gprof_SOURCES) + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > DEP2 + echo '# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.' >> DEP2 + $(MKDEP) $(INCLUDES) $(CFLAGS) $? >> DEP2 + mv -f DEP2 $@ + +dep.sed: dep-in.sed config.status + objdir=`pwd`; \ + sed <$(srcdir)/dep-in.sed >dep.sed \ + -e 's!@INCDIR@!$(INCDIR)!' \ + -e 's!@BFDDIR@!$(BFDDIR)!' \ + -e 's!@SRCDIR@!$(srcdir)!' \ + -e "s!@OBJDIR@!$${objdir}!" \ + -e 's!@TOPDIR@!'`echo $(srcdir) | sed -e s,/gprof$$,,`'!' + +dep: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat DEP >> tmp-Makefile + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in + cat DEP >> tmp-Makefile.in + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in + +dep-am: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat DEP >> tmp-Makefile.am + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +CLEANFILES = dep.sed DEP DEPA DEP1 DEP2 + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. +basic_blocks.o: basic_blocks.c $(INCDIR)/libiberty.h \ + $(INCDIR)/ansidecl.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h basic_blocks.h \ + corefile.h gmon_io.h gmon_out.h search_list.h source.h \ + symtab.h sym_ids.h +call_graph.o: call_graph.c gprof.h $(BFDDIR)/sysdep.h \ + $(INCDIR)/ansidecl.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h call_graph.h corefile.h gmon_io.h \ + gmon_out.h sym_ids.h +cg_arcs.o: cg_arcs.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \ + utils.h sym_ids.h +cg_dfn.o: cg_dfn.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h cg_dfn.h utils.h +cg_print.o: cg_print.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h cg_print.h hist.h utils.h corefile.h +corefile.o: corefile.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h corefile.h +gmon_io.o: gmon_io.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h basic_blocks.h \ + corefile.h call_graph.h gmon_io.h gmon_out.h gmon.h \ + hertz.h hist.h $(INCDIR)/libiberty.h +gprof.o: gprof.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h basic_blocks.h call_graph.h cg_arcs.h cg_print.h \ + corefile.h gmon_io.h hertz.h hist.h sym_ids.h $(INCDIR)/demangle.h +hertz.o: hertz.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + hertz.h +hist.o: hist.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h corefile.h gmon_io.h gmon_out.h hist.h sym_ids.h \ + utils.h +source.o: source.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + $(INCDIR)/libiberty.h search_list.h source.h +search_list.o: search_list.c $(INCDIR)/libiberty.h \ + $(INCDIR)/ansidecl.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h search_list.h +symtab.o: symtab.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h +sym_ids.o: sym_ids.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/safe-ctype.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h search_list.h \ + source.h symtab.h cg_arcs.h sym_ids.h +utils.o: utils.c $(INCDIR)/demangle.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h utils.h +i386.o: i386.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +alpha.o: alpha.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +vax.o: vax.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +tahoe.o: tahoe.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +sparc.o: sparc.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +mips.o: mips.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +flat_bl.o: flat_bl.c $(INCDIR)/ansidecl.h +bsd_callg_bl.o: bsd_callg_bl.c $(INCDIR)/ansidecl.h +fsf_callg_bl.o: fsf_callg_bl.c $(INCDIR)/ansidecl.h +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/gprof/Makefile.in b/gprof/Makefile.in new file mode 100644 index 000000000000..8d5dc0f021dd --- /dev/null +++ b/gprof/Makefile.in @@ -0,0 +1,903 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +l = @l@ + +AUTOMAKE_OPTIONS = cygnus + +SUFFIXES = .m + +SUBDIRS = po + +BASEDIR = $(srcdir)/.. +BFDDIR = $(BASEDIR)/bfd +INCDIR = $(BASEDIR)/include + +WARN_CFLAGS = @WARN_CFLAGS@ +AM_CFLAGS = $(WARN_CFLAGS) + +MKDEP = gcc -MM + +INCLUDES = -D_GNU_SOURCE -DDEBUG -I../bfd -I$(srcdir)/../include -I$(srcdir)/../bfd -I$(srcdir)/../intl -I../intl -I. -DLOCALEDIR="\"$(prefix)/share/locale\"" + +bin_PROGRAMS = gprof + +sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \ + cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \ + search_list.c symtab.c sym_ids.c utils.c \ + i386.c alpha.c vax.c tahoe.c sparc.c mips.c + +gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c +gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLDEPS) +gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS) + +noinst_HEADERS = \ + basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \ + corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \ + search_list.h source.h sym_ids.h symtab.h utils.h + + +BUILT_SOURCES = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c +EXTRA_DIST = $(BUILT_SOURCES) bbconv.pl $(man_MANS) + +POTFILES = $(sources) $(noinst_HEADERS) + +MANCONF = -Dman + +TEXI2POD = perl $(srcdir)/../etc/texi2pod.pl + +POD2MAN = pod2man --center="GNU" --release="binutils-$(VERSION)" --section=1 + +info_TEXINFOS = gprof.texi +man_MANS = gprof.1 + +CLEANFILES = dep.sed DEP DEPA DEP1 DEP2 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = gconfig.h +CONFIG_CLEAN_FILES = +bin_PROGRAMS = gprof$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +gprof_OBJECTS = basic_blocks.$(OBJEXT) call_graph.$(OBJEXT) \ +cg_arcs.$(OBJEXT) cg_dfn.$(OBJEXT) cg_print.$(OBJEXT) \ +corefile.$(OBJEXT) gmon_io.$(OBJEXT) gprof.$(OBJEXT) hertz.$(OBJEXT) \ +hist.$(OBJEXT) source.$(OBJEXT) search_list.$(OBJEXT) symtab.$(OBJEXT) \ +sym_ids.$(OBJEXT) utils.$(OBJEXT) i386.$(OBJEXT) alpha.$(OBJEXT) \ +vax.$(OBJEXT) tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT) \ +flat_bl.$(OBJEXT) bsd_callg_bl.$(OBJEXT) fsf_callg_bl.$(OBJEXT) +gprof_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi` +TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex +INFO_DEPS = gprof.info +DVIS = gprof.dvi +TEXINFOS = gprof.texi +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = README ./stamp-h.in ChangeLog Makefile.am Makefile.in \ +TODO acinclude.m4 aclocal.m4 configure configure.in gconfig.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(gprof_SOURCES) +OBJECTS = $(gprof_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .dvi .info .lo .m .o .obj .ps .s .texi .texinfo .txi +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +gconfig.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/gconfig.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=gconfig.h:gconfig.in \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/gconfig.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f gconfig.h + +maintainer-clean-hdr: + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +gprof$(EXEEXT): $(gprof_OBJECTS) $(gprof_DEPENDENCIES) + @rm -f gprof$(EXEEXT) + $(LINK) $(gprof_LDFLAGS) $(gprof_OBJECTS) $(gprof_LDADD) $(LIBS) + +gprof.info: gprof.texi +gprof.dvi: gprof.texi + + +DVIPS = dvips + +.texi.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texi.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.texi: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.txi.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ + if test -f $$d/$$ifile; then \ + echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ + $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ + done; \ + else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + ii=yes; \ + else ii=; fi; \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + test -z "$$ii" \ + || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ + done + @$(NORMAL_UNINSTALL) + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ + done + +dist-info: $(INFO_DEPS) + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + for file in `cd $$d && eval echo $$base*`; do \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f gprof.aux gprof.cp gprof.cps gprof.dvi gprof.fn gprof.fns \ + gprof.ky gprof.kys gprof.ps gprof.log gprof.pg gprof.toc \ + gprof.tp gprof.tps gprof.vr gprof.vrs gprof.op gprof.tr \ + gprof.cv gprof.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + for i in $(INFO_DEPS); do \ + rm -f $$i; \ + if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ + rm -f $$i-[0-9]*; \ + fi; \ + done +clean-info: mostlyclean-aminfo + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) gconfig.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)gconfig.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags gconfig.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info +info-am: $(INFO_DEPS) +info: info-recursive +dvi-am: $(DVIS) +dvi: dvi-recursive +check-am: +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-info-am: +install-info: install-info-recursive +all-recursive-am: gconfig.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: install-binPROGRAMS +install-exec: install-exec-recursive + +install-data-am: install-man +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-binPROGRAMS uninstall-man +uninstall: uninstall-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) gconfig.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1 + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \ + mostlyclean-compile mostlyclean-libtool \ + mostlyclean-aminfo mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-libtool \ + clean-aminfo clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \ + distclean-libtool distclean-aminfo distclean-tags \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-aminfo maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool install-info-am uninstall-info \ +mostlyclean-aminfo distclean-aminfo clean-aminfo \ +maintainer-clean-aminfo install-man1 uninstall-man1 install-man \ +uninstall-man install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-info-am \ +install-info all-recursive-am install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs-am installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +diststuff: $(BUILT_SOURCES) info $(man_MANS) + +.m.c: + awk -f $(srcdir)/gen-c-prog.awk > ./$*.c \ + FUNCTION=`(echo $*|sed -e 's,.*/,,g' -e 's/_bl//')`_blurb \ + FILE=$*.m $(srcdir)/$*.m +po/POTFILES.in: @MAINT@ Makefile + for f in $(POTFILES); do echo $$f; done | LC_COLLATE= sort > tmp \ + && mv tmp $(srcdir)/po/POTFILES.in + +# Build the man page from the texinfo file +# The sed command removes the no-adjust Nroff command so that +# the man output looks standard. +gprof.1: $(srcdir)/gprof.texi + touch $@ + -$(TEXI2POD) $(MANCONF) -Dgprof < $(srcdir)/gprof.texi > gprof.pod + -($(POD2MAN) gprof.pod | \ + sed -e '/^.if n .na/d' > $@.T$$$$ && \ + mv -f $@.T$$$$ $@) || \ + (rm -f $@.T$$$$ && exit 1) + rm -f gprof.pod + +Makefile: $(BFDDIR)/configure.in + +# We want install to imply install-info as per GNU standards, despite the +# cygnus option. +install: install-info + +# Targets to rebuild dependencies in this Makefile. +# Have to get rid of DEP1 here so that "$?" later includes all sources. +DEP: dep.sed $(gprof_SOURCES) $(noinst_HEADERS) gconfig.h + rm -f DEP1 + $(MAKE) MKDEP="$(MKDEP)" DEP1 + sed -f dep.sed < DEP1 > DEPA + echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> DEPA + if grep ' /' DEPA > /dev/null 2> /dev/null; then \ + echo 'make DEP failed!'; exit 1; \ + else \ + mv -f DEPA $@; \ + fi + +DEP1: $(gprof_SOURCES) + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > DEP2 + echo '# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.' >> DEP2 + $(MKDEP) $(INCLUDES) $(CFLAGS) $? >> DEP2 + mv -f DEP2 $@ + +dep.sed: dep-in.sed config.status + objdir=`pwd`; \ + sed <$(srcdir)/dep-in.sed >dep.sed \ + -e 's!@INCDIR@!$(INCDIR)!' \ + -e 's!@BFDDIR@!$(BFDDIR)!' \ + -e 's!@SRCDIR@!$(srcdir)!' \ + -e "s!@OBJDIR@!$${objdir}!" \ + -e 's!@TOPDIR@!'`echo $(srcdir) | sed -e s,/gprof$$,,`'!' + +dep: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat DEP >> tmp-Makefile + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in + cat DEP >> tmp-Makefile.in + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in + +dep-am: DEP + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat DEP >> tmp-Makefile.am + $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. +basic_blocks.o: basic_blocks.c $(INCDIR)/libiberty.h \ + $(INCDIR)/ansidecl.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h basic_blocks.h \ + corefile.h gmon_io.h gmon_out.h search_list.h source.h \ + symtab.h sym_ids.h +call_graph.o: call_graph.c gprof.h $(BFDDIR)/sysdep.h \ + $(INCDIR)/ansidecl.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h call_graph.h corefile.h gmon_io.h \ + gmon_out.h sym_ids.h +cg_arcs.o: cg_arcs.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \ + utils.h sym_ids.h +cg_dfn.o: cg_dfn.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h cg_dfn.h utils.h +cg_print.o: cg_print.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h cg_print.h hist.h utils.h corefile.h +corefile.o: corefile.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h corefile.h +gmon_io.o: gmon_io.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h basic_blocks.h \ + corefile.h call_graph.h gmon_io.h gmon_out.h gmon.h \ + hertz.h hist.h $(INCDIR)/libiberty.h +gprof.o: gprof.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h basic_blocks.h call_graph.h cg_arcs.h cg_print.h \ + corefile.h gmon_io.h hertz.h hist.h sym_ids.h $(INCDIR)/demangle.h +hertz.o: hertz.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + hertz.h +hist.o: hist.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h corefile.h gmon_io.h gmon_out.h hist.h sym_ids.h \ + utils.h +source.o: source.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + $(INCDIR)/libiberty.h search_list.h source.h +search_list.o: search_list.c $(INCDIR)/libiberty.h \ + $(INCDIR)/ansidecl.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h search_list.h +symtab.o: symtab.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h +sym_ids.o: sym_ids.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/safe-ctype.h gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h \ + $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h ../bfd/bfd.h \ + $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h search_list.h \ + source.h symtab.h cg_arcs.h sym_ids.h +utils.o: utils.c $(INCDIR)/demangle.h $(INCDIR)/ansidecl.h \ + gprof.h $(BFDDIR)/sysdep.h ../bfd/config.h $(INCDIR)/fopen-same.h \ + $(INCDIR)/filenames.h ../bfd/bfd.h $(INCDIR)/symcat.h \ + gconfig.h $(INCDIR)/bin-bugs.h search_list.h source.h \ + symtab.h cg_arcs.h utils.h +i386.o: i386.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +alpha.o: alpha.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +vax.o: vax.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +tahoe.o: tahoe.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +sparc.o: sparc.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +mips.o: mips.c gprof.h $(BFDDIR)/sysdep.h $(INCDIR)/ansidecl.h \ + ../bfd/config.h $(INCDIR)/fopen-same.h $(INCDIR)/filenames.h \ + ../bfd/bfd.h $(INCDIR)/symcat.h gconfig.h $(INCDIR)/bin-bugs.h \ + search_list.h source.h symtab.h cg_arcs.h corefile.h \ + hist.h +flat_bl.o: flat_bl.c $(INCDIR)/ansidecl.h +bsd_callg_bl.o: bsd_callg_bl.c $(INCDIR)/ansidecl.h +fsf_callg_bl.o: fsf_callg_bl.c $(INCDIR)/ansidecl.h +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gprof/README b/gprof/README new file mode 100644 index 000000000000..8fe2da8a5ae5 --- /dev/null +++ b/gprof/README @@ -0,0 +1,442 @@ + README for GPROF + +This is the GNU profiler. It is distributed with other "binary +utilities" which should be in ../binutils. See ../binutils/README for +more general notes, including where to send bug reports. + +This file documents the changes and new features available with this +version of GNU gprof. + +* New Features + + o Long options + + o Supports generalized file format, without breaking backward compatibility: + new file format supports basic-block execution counts and non-realtime + histograms (see below) + + o Supports profiling at the line level: flat profiles, call-graph profiles, + and execution-counts can all be displayed at a level that identifies + individual lines rather than just functions + + o Test-coverage support (similar to Sun tcov program): source files + can be annotated with the number of times a function was invoked + or with the number of times each basic-block in a function was + executed + + o Generalized histograms: not just execution-time, but arbitrary + histograms are support (for example, performance counter based + profiles) + + o Powerful mechanism to select data to be included/excluded from + analysis and/or output + + o Support for DEC OSF/1 v3.0 + + o Full cross-platform profiling support: gprof uses BFD to support + arbitrary, non-native object file formats and non-native byte-orders + (this feature has not been tested yet) + + o In the call-graph function index, static function names are now + printed together with the filename in which the function was defined + (required bfd_find_nearest_line() support and symbolic debugging + information to be present in the executable file) + + o Major overhaul of source code (compiles cleanly with -Wall, etc.) + +* Supported Platforms + +The current version is known to work on: + + o DEC OSF/1 v3.0 + All features supported. + + o SunOS 4.1.x + All features supported. + + o Solaris 2.3 + Line-level profiling unsupported because bfd_find_nearest_line() + is not fully implemented for Elf binaries. + + o HP-UX 9.01 + Line-level profiling unsupported because bfd_find_nearest_line() + is not fully implemented for SOM binaries. + +* Detailed Description + +** User Interface Changes + +The command-line interface is backwards compatible with earlier +versions of GNU gprof and Berkeley gprof. The only exception is +the option to delete arcs from the call graph. The old syntax +was: + + -k fromname toname + +while the new syntax is: + + -k fromname/toname + +This change was necessary to be compatible with long-option parsing. +Also, "fromname" and "toname" can now be arbitrary symspecs rather +than just function names (see below for an explanation of symspecs). +For example, option "-k gprof.c/" suppresses all arcs due to calls out +of file "gprof.c". + +*** Sym Specs + +It is often necessary to apply gprof only to specific parts of a +program. GNU gprof has a simple but powerful mechanism to achieve +this. So called {\em symspecs\/} provide the foundation for this +mechanism. A symspec selects the parts of a profiled program to which +an operation should be applied to. The syntax of a symspec is +simple: + + filename_containing_a_dot + | funcname_not_containing_a_dot + | linenumber + | ( [ any_filename ] `:' ( any_funcname | linenumber ) ) + +Here are some examples: + + main.c Selects everything in file "main.c"---the + dot in the string tells gprof to interpret + the string as a filename, rather than as + a function name. To select a file whose + name does contain a dot, a trailing colon + should be specified. For example, "odd:" is + interpreted as the file named "odd". + + main Selects all functions named "main". Notice + that there may be multiple instances of the + same function name because some of the + definitions may be local (i.e., static). + Unless a function name is unique in a program, + you must use the colon notation explained + below to specify a function from a specific + source file. Sometimes, functionnames contain + dots. In such cases, it is necessary to + add a leading colon to the name. For example, + ":.mul" selects function ".mul". + + main.c:main Selects function "main" in file "main.c". + + main.c:134 Selects line 134 in file "main.c". + +IMPLEMENTATION NOTE: The source code uses the type sym_id for symspecs. +At some point, this probably ought to be changed to "sym_spec" to make +reading the code easier. + +*** Long options + +GNU gprof now supports long options. The following is a list of all +supported options. Options that are listed without description +operate in the same manner as the corresponding option in older +versions of gprof. + +Short Form: Long Form: +----------- ---------- +-l --line + Request profiling at the line-level rather + than just at the function level. Source + lines are identified by symbols of the form: + + func (file:line) + + where "func" is the function name, "file" is the + file name and "line" is the line-number that + corresponds to the line. + + To work properly, the binary must contain symbolic + debugging information. This means that the source + have to be translated with option "-g" specified. + Functions for which there is no symbolic debugging + information available are treated as if "--line" + had not been specified. However, the line number + printed with such symbols is usually incorrect + and should be ignored. + +-a --no-static +-A[symspec] --annotated-source[=symspec] + Request output in the form of annotated source + files. If "symspec" is specified, print output only + for symbols selected by "symspec". If the option + is specified multiple times, annotated output is + generated for the union of all symspecs. + + Examples: + + -A Prints annotated source for all + source files. + -Agprof.c Prints annotated source for file + gprof.c. + -Afoobar Prints annotated source for files + containing a function named "foobar". + The entire file will be printed, but + only the function itself will be + annotated with profile data. + +-J[symspec] --no-annotated-source[=symspec] + Suppress annotated source output. If specified + without argument, annotated output is suppressed + completely. With an argument, annotated output + is suppressed only for the symbols selected by + "symspec". If the option is specified multiple + times, annotated output is suppressed for the + union of all symspecs. This option has lower + precedence than --annotated-source + +-p[symspec] --flat-profile[=symspec] + Request output in the form of a flat profile + (unless any other output-style option is specified, + this option is turned on by default). If + "symspec" is specified, include only symbols + selected by "symspec" in flat profile. If the + option is specified multiple times, the flat + profile includes symbols selected by the union + of all symspecs. + +-P[symspec] --no-flat-profile[=symspec] + Suppress output in the flat profile. If given + without an argument, the flat profile is suppressed + completely. If "symspec" is specified, suppress + the selected symbols in the flat profile. If the + option is specified multiple times, the union of + the selected symbols is suppressed. This option + has lower precedence than --flat-profile. + +-q[symspec] --graph[=symspec] + Request output in the form of a call-graph + (unless any other output-style option is specified, + this option is turned on by default). If "symspec" + is specified, include only symbols selected by + "symspec" in the call-graph. If the option is + specified multiple times, the call-graph includes + symbols selected by the union of all symspecs. + +-Q[symspec] --no-graph[=symspec] + Suppress output in the call-graph. If given without + an argument, the call-graph is suppressed completely. + With a "symspec", suppress the selected symbols + from the call-graph. If the option is specified + multiple times, the union of the selected symbols + is suppressed. This option has lower precedence + than --graph. + +-C[symspec] --exec-counts[=symspec] + Request output in the form of execution counts. + If "symspec" is present, include only symbols + selected by "symspec" in the execution count + listing. If the option is specified multiple + times, the execution count listing includes + symbols selected by the union of all symspecs. + +-Z[symspec] --no-exec-counts[=symspec] + Suppress output in the execution count listing. + If given without an argument, the listing is + suppressed completely. With a "symspec", suppress + the selected symbols from the call-graph. If the + option is specified multiple times, the union of + the selected symbols is suppressed. This option + has lower precedence than --exec-counts. + +-i --file-info + Print information about the profile files that + are read. The information consists of the + number and types of records present in the + profile file. Currently, a profile file can + contain any number and any combination of histogram, + call-graph, or basic-block count records. + +-s --sum + +-x --all-lines + This option affects annotated source output only. + By default, only the lines at the beginning of + a basic-block are annotated. If this option is + specified, every line in a basic-block is annotated + by repeating the annotation for the first line. + This option is identical to tcov's "-a". + +-I dirs --directory-path=dirs + This option affects annotated source output only. + Specifies the list of directories to be searched + for source files. The argument "dirs" is a colon + separated list of directories. By default, gprof + searches for source files relative to the current + working directory only. + +-z --display-unused-functions + +-m num --min-count=num + This option affects annotated source and execution + count output only. Symbols that are executed + less than "num" times are suppressed. For annotated + source output, suppressed symbols are marked + by five hash-marks (#####). In an execution count + output, suppressed symbols do not appear at all. + +-L --print-path + Normally, source filenames are printed with the path + component suppressed. With this option, gprof + can be forced to print the full pathname of + source filenames. The full pathname is determined + from symbolic debugging information in the image file + and is relative to the directory in which the compiler + was invoked. + +-y --separate-files + This option affects annotated source output only. + Normally, gprof prints annotated source files + to standard-output. If this option is specified, + annotated source for a file named "path/filename" + is generated in the file "filename-ann". That is, + annotated output is {\em always\/} generated in + gprof's current working directory. Care has to + be taken if a program consists of files that have + identical filenames, but distinct paths. + +-c --static-call-graph + +-t num --table-length=num + This option affects annotated source output only. + After annotating a source file, gprof generates + an execution count summary consisting of a table + of lines with the top execution counts. By + default, this table is ten entries long. + This option can be used to change the table length + or, by specifying an argument value of 0, it can be + suppressed completely. + +-n symspec --time=symspec + Only symbols selected by "symspec" are considered + in total and percentage time computations. + However, this option does not affect percentage time + computation for the flat profile. + If the option is specified multiple times, the union + of all selected symbols is used in time computations. + +-N --no-time=symspec + Exclude the symbols selected by "symspec" from + total and percentage time computations. + However, this option does not affect percentage time + computation for the flat profile. + This option is ignored if any --time options are + specified. + +-w num --width=num + Sets the output line width. Currently, this option + affects the printing of the call-graph function index + only. + +-e <no long form---for backwards compatibility only> +-E <no long form---for backwards compatibility only> +-f <no long form---for backwards compatibility only> +-F <no long form---for backwards compatibility only> +-k <no long form---for backwards compatibility only> +-b --brief +-dnum --debug[=num] + +-h --help + Prints a usage message. + +-O name --file-format=name + Selects the format of the profile data files. + Recognized formats are "auto", "bsd", "magic", + and "prof". The last one is not yet supported. + Format "auto" attempts to detect the file format + automatically (this is the default behavior). + It attempts to read the profile data files as + "magic" files and if this fails, falls back to + the "bsd" format. "bsd" forces gprof to read + the data files in the BSD format. "magic" forces + gprof to read the data files in the "magic" format. + +-T --traditional +-v --version + +** File Format Changes + +The old BSD-derived format used for profile data does not contain a +magic cookie that allows to check whether a data file really is a +gprof file. Furthermore, it does not provide a version number, thus +rendering changes to the file format almost impossible. GNU gprof +uses a new file format that provides these features. For backward +compatibility, GNU gprof continues to support the old BSD-derived +format, but not all features are supported with it. For example, +basic-block execution counts cannot be accommodated by the old file +format. + +The new file format is defined in header file \file{gmon_out.h}. It +consists of a header containing the magic cookie and a version number, +as well as some spare bytes available for future extensions. All data +in a profile data file is in the native format of the host on which +the profile was collected. GNU gprof adapts automatically to the +byte-order in use. + +In the new file format, the header is followed by a sequence of +records. Currently, there are three different record types: histogram +records, call-graph arc records, and basic-block execution count +records. Each file can contain any number of each record type. When +reading a file, GNU gprof will ensure records of the same type are +compatible with each other and compute the union of all records. For +example, for basic-block execution counts, the union is simply the sum +of all execution counts for each basic-block. + +*** Histogram Records + +Histogram records consist of a header that is followed by an array of +bins. The header contains the text-segment range that the histogram +spans, the size of the histogram in bytes (unlike in the old BSD +format, this does not include the size of the header), the rate of the +profiling clock, and the physical dimension that the bin counts +represent after being scaled by the profiling clock rate. The +physical dimension is specified in two parts: a long name of up to 15 +characters and a single character abbreviation. For example, a +histogram representing real-time would specify the long name as +"seconds" and the abbreviation as "s". This feature is useful for +architectures that support performance monitor hardware (which, +fortunately, is becoming increasingly common). For example, under DEC +OSF/1, the "uprofile" command can be used to produce a histogram of, +say, instruction cache misses. In this case, the dimension in the +histogram header could be set to "i-cache misses" and the abbreviation +could be set to "1" (because it is simply a count, not a physical +dimension). Also, the profiling rate would have to be set to 1 in +this case. + +Histogram bins are 16-bit numbers and each bin represent an equal +amount of text-space. For example, if the text-segment is one +thousand bytes long and if there are ten bins in the histogram, each +bin represents one hundred bytes. + + +*** Call-Graph Records + +Call-graph records have a format that is identical to the one used in +the BSD-derived file format. It consists of an arc in the call graph +and a count indicating the number of times the arc was traversed +during program execution. Arcs are specified by a pair of addresses: +the first must be within caller's function and the second must be +within the callee's function. When performing profiling at the +function level, these addresses can point anywhere within the +respective function. However, when profiling at the line-level, it is +better if the addresses are as close to the call-site/entry-point as +possible. This will ensure that the line-level call-graph is able to +identify exactly which line of source code performed calls to a +function. + +*** Basic-Block Execution Count Records + +Basic-block execution count records consist of a header followed by a +sequence of address/count pairs. The header simply specifies the +length of the sequence. In an address/count pair, the address +identifies a basic-block and the count specifies the number of times +that basic-block was executed. Any address within the basic-address can +be used. + +IMPLEMENTATION NOTE: gcc -a can be used to instrument a program to +record basic-block execution counts. However, the __bb_exit_func() +that is currently present in libgcc2.c does not generate a gmon.out +file in a suitable format. This should be fixed for future releases +of gcc. In the meantime, contact davidm@cs.arizona.edu for a version +of __bb_exit_func() to is appropriate. diff --git a/gprof/TEST b/gprof/TEST new file mode 100644 index 000000000000..78a90300cae9 --- /dev/null +++ b/gprof/TEST @@ -0,0 +1,7 @@ +- check whether old file format is properly read when input comes from + stdin + +- check whether underscores are properly dealt with (both, on systems + that prepend them to each C name and on systems that don't) + +- ensure gprof fails gracefully when no debugging info available diff --git a/gprof/TODO b/gprof/TODO new file mode 100644 index 000000000000..324983861c7e --- /dev/null +++ b/gprof/TODO @@ -0,0 +1,69 @@ + +- add support for prof file format so that prof files can be displayed + at the line-level (this is useful for the uprofile tool under DEC's + OSF/1) +- take a hard look at --file-ordering (broken) and --function-ordering + ++ documentation ++ optimize bfd_find_nearest_line_num() (or replace by different interface) ++ cleanup _bfd_ecoff_find_nearest_line_num() fixes & description ++ ensure "cc -pg" produces good files under OSF/1 v3.0 ++ make sure gprof works together with OSF/1 v3.0's profiling libraries ++ implement symtab_parse(); modify sym_lookup() to consider addr_high ++ change gprof.c to collect lists, then invoke symtab_parse() for + each list ++ Questions: + o is -c (--static-call-graph) useful at all? i can't see + how; if it were deleted, gprof would be completely machine + independent => yup, it is + o are (long) option names appropriate? + o -k (--exclude-arc) cannot be implemented with getopt(); + is new syntax (-k from/to) acceptable? If not, how to + fix it? + o in the FSF output, the call-graph index now prints + the filename of static functions in parentheses; e.g., + static function foo() that is defined in file bar.c + would be printed as: + + [4] foo (bar.c) + + is this acceptable? should it be done only optionally? + o symbols with addresses that map back to a different + name are suppressed (happens with labels, for example); + is this acceptable? should it be done only optionally? ++ generalize to allow arbitrary histograms (not just time histograms) ++ basic-block information currently replaces all symbols created from + the core because of an ugly ordering conflict---for now, the current + solution works, but something cleaner is desirable ==> cleaned up, + but it's slower now ++ convert to very new file format (back to trivial format, that is :) ++ replace "dummy.h" for Alpha (if there is any use to it) ++ add support for execution time profiling at a basic-block level ++ fix filename-off-by-one bug for Alpha (see ~/tmp/d.[ch])---no longer + relevant ++ "-pg -a" doesn't work as expected because mcleanup() will overwrite + the file generated by __bb_exit_func() (or vice versa) ++ first basic-block of fac() seems to get credited to last basic-block + of previous function => bug in basic_blocks.c ++ flat profile should provide automatic scaling for per-call times because + otherwise they'll always be zero on a fast machine with tons of small + functions ++ make "-a" imply to retain line number info (without actually generating + the debugging information (unless -g is specified)---no, this is a + bad idea, because it is not clear what level of debugging info should + be requested (e.g., -g vs. -g3); leaving it up to the user seems best ++ add long options support (or at least use getopt instead of ad-hoc + implementation) ++ split into files according to abstract objects that are manipulated ++ replace sccsid by rcsid & add "end of ..." to every .c file ++ use DBG() everywhere ++ fix spacing (" ," -> "," etc.) ++ use DEFUNs everywhere ++ make compile cleanly with -Wall ++ "gcc -pg -O2" doesn't work on tecc.c unless -fno-omit-frame-pointer is + specified; find out why ++ make things portable (prototypes, const, etc.) ++ if NEW_GMON_OUT is not defined, have a flag that will allow to + read new gmon.out style files. The idea being that everyone + will use the new format for basic-block style profiling but + the old format for regular gpprofiling diff --git a/gprof/acinclude.m4 b/gprof/acinclude.m4 new file mode 100644 index 000000000000..c01c95cd2311 --- /dev/null +++ b/gprof/acinclude.m4 @@ -0,0 +1,14 @@ +sinclude(../libtool.m4) +dnl The lines below arrange for aclocal not to bring libtool.m4 +dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake +dnl to add a definition of LIBTOOL to Makefile.in. +ifelse(yes,no,[ +AC_DEFUN([AM_PROG_LIBTOOL],) +AC_SUBST(LIBTOOL) +]) + +sinclude(../gettext.m4) +ifelse(yes,no,[ +AC_DEFUN([CY_WITH_NLS],) +AC_SUBST(INTLLIBS) +]) diff --git a/gprof/aclocal.m4 b/gprof/aclocal.m4 new file mode 100644 index 000000000000..9142402ef2ad --- /dev/null +++ b/gprof/aclocal.m4 @@ -0,0 +1,193 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +sinclude(../libtool.m4) +dnl The lines below arrange for aclocal not to bring libtool.m4 +dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake +dnl to add a definition of LIBTOOL to Makefile.in. +ifelse(yes,no,[ +AC_DEFUN([AM_PROG_LIBTOOL],) +AC_SUBST(LIBTOOL) +]) + +sinclude(../gettext.m4) +ifelse(yes,no,[ +AC_DEFUN([CY_WITH_NLS],) +AC_SUBST(INTLLIBS) +]) + +#serial 1 +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<<am_indx=1 +for am_file in <<$1>>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/gprof/alpha.c b/gprof/alpha.c new file mode 100644 index 000000000000..5fc9b774213d --- /dev/null +++ b/gprof/alpha.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 1983, 1993, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" + +/* + * Opcodes of the call instructions: + */ +#define OP_Jxx 0x1a +#define OP_BSR 0x34 + +#define Jxx_FUNC_JMP 0 +#define Jxx_FUNC_JSR 1 +#define Jxx_FUNC_RET 2 +#define Jxx_FUNC_JSR_COROUTINE 3 + +#if 0 +/* Here to document only. We can't use this when cross compiling as + the bitfield layout might not be the same as native. */ +typedef union + { + struct + { + unsigned other:26; + unsigned op_code:6; + } + a; /* any format */ + struct + { + int disp:21; + unsigned ra:5; + unsigned op_code:6; + } + b; /* branch format */ + struct + { + int hint:14; + unsigned func:2; + unsigned rb:5; + unsigned ra:5; + unsigned op_code:6; + } + j; /* jump format */ + } +alpha_Instruction; +#endif + +static Sym indirect_child; + +void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +/* + * On the Alpha we can only detect PC relative calls, which are + * usually generated for calls to functions within the same + * object file only. This is still better than nothing, however. + * (In particular it should be possible to find functions that + * potentially call integer division routines, for example.) + */ +void +alpha_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + bfd_vma pc, dest_pc; + unsigned int insn; + Sym *child; + + if (indirect_child.name == NULL) + { + sym_init (&indirect_child); + indirect_child.name = _("<indirect child>"); + indirect_child.cg.prop.fract = 1.0; + indirect_child.cg.cyc.head = &indirect_child; + } + + if (!core_text_space) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"), + parent->name, (unsigned long) p_lowpc, + (unsigned long) p_highpc)); + for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4) + { + insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space + + pc - core_text_sect->vma)); + switch (insn & (0x3f << 26)) + { + case OP_Jxx << 26: + /* + * There is no simple and reliable way to determine the + * target of a jsr (the hint bits help, but there aren't + * enough bits to get a satisfactory hit rate). Instead, + * for any indirect jump we simply add an arc from PARENT + * to INDIRECT_CHILD---that way the user it at least able + * to see that there are other calls as well. + */ + if ((insn & (3 << 14)) == Jxx_FUNC_JSR << 14 + || (insn & (3 << 14)) == Jxx_FUNC_JSR_COROUTINE << 14) + { + DBG (CALLDEBUG, + printf (_("[find_call] 0x%lx: jsr%s <indirect_child>\n"), + (unsigned long) pc, + ((insn & (3 << 14)) == Jxx_FUNC_JSR << 14 + ? "" : "_coroutine"))); + arc_add (parent, &indirect_child, (unsigned long) 0); + } + break; + + case OP_BSR << 26: + DBG (CALLDEBUG, + printf (_("[find_call] 0x%lx: bsr"), (unsigned long) pc)); + /* + * Regular PC relative addressing. Check that this is the + * address of a function. The linker sometimes redirects + * the entry point by 8 bytes to skip loading the global + * pointer, so we allow for either address: + */ + dest_pc = pc + 4 + (((bfd_signed_vma) (insn & 0x1fffff) + ^ 0x100000) - 0x100000); + if (dest_pc >= s_lowpc && dest_pc <= s_highpc) + { + child = sym_lookup (&symtab, dest_pc); + DBG (CALLDEBUG, + printf (" 0x%lx\t; name=%s, addr=0x%lx", + (unsigned long) dest_pc, child->name, + (unsigned long) child->addr)); + if (child->addr == dest_pc || child->addr == dest_pc - 8) + { + DBG (CALLDEBUG, printf ("\n")); + /* a hit: */ + arc_add (parent, child, (unsigned long) 0); + continue; + } + } + /* + * Something funny going on. + */ + DBG (CALLDEBUG, printf ("\tbut it's a botch\n")); + break; + + default: + break; + } + } +} diff --git a/gprof/basic_blocks.c b/gprof/basic_blocks.c new file mode 100644 index 000000000000..a37ca0b2441e --- /dev/null +++ b/gprof/basic_blocks.c @@ -0,0 +1,595 @@ +/* basic_blocks.c - Basic-block level related code: reading/writing + of basic-block info to/from gmon.out; computing and formatting of + basic-block related statistics. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "gprof.h" +#include "basic_blocks.h" +#include "corefile.h" +#include "gmon_io.h" +#include "gmon_out.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "sym_ids.h" + +static int cmp_bb PARAMS ((const PTR, const PTR)); +static int cmp_ncalls PARAMS ((const PTR, const PTR)); +static void fskip_string PARAMS ((FILE *)); +static void annotate_with_count PARAMS ((char *, unsigned int, int, PTR)); + +/* Default option values: */ +bfd_boolean bb_annotate_all_lines = FALSE; +unsigned long bb_min_calls = 1; +int bb_table_length = 10; + +/* Variables used to compute annotated source listing stats: */ +static long num_executable_lines; +static long num_lines_executed; + + +/* Helper for sorting. Compares two symbols and returns result + such that sorting will be increasing according to filename, line + number, and address (in that order). */ + +static int +cmp_bb (lp, rp) + const PTR lp; + const PTR rp; +{ + int r; + const Sym *left = *(const Sym **) lp; + const Sym *right = *(const Sym **) rp; + + if (left->file && right->file) + { + r = strcmp (left->file->name, right->file->name); + + if (r) + return r; + + if (left->line_num != right->line_num) + return left->line_num - right->line_num; + } + + if (left->addr < right->addr) + return -1; + else if (left->addr > right->addr) + return 1; + else + return 0; +} + + +/* Helper for sorting. Order basic blocks in decreasing number of + calls, ties are broken in increasing order of line numbers. */ +static int +cmp_ncalls (lp, rp) + const PTR lp; + const PTR rp; +{ + const Sym *left = *(const Sym **) lp; + const Sym *right = *(const Sym **) rp; + + if (!left) + return 1; + else if (!right) + return -1; + + if (left->ncalls < right->ncalls) + return 1; + else if (left->ncalls > right->ncalls) + return -1; + + return left->line_num - right->line_num; +} + +/* Skip over variable length string. */ +static void +fskip_string (fp) + FILE *fp; +{ + int ch; + + while ((ch = fgetc (fp)) != EOF) + { + if (ch == '\0') + break; + } +} + +/* Read a basic-block record from file IFP. FILENAME is the name + of file IFP and is provided for formatting error-messages only. */ + +void +bb_read_rec (ifp, filename) + FILE *ifp; + const char *filename; +{ + int nblocks, b; + bfd_vma addr, ncalls; + Sym *sym; + + if (gmon_io_read_32 (ifp, &nblocks)) + { + fprintf (stderr, _("%s: %s: unexpected end of file\n"), + whoami, filename); + done (1); + } + + nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks); + if (gmon_file_version == 0) + fskip_string (ifp); + + for (b = 0; b < nblocks; ++b) + { + if (gmon_file_version == 0) + { + int line_num; + + /* Version 0 had lots of extra stuff that we don't + care about anymore. */ + if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1) + || (fread (&addr, sizeof (addr), 1, ifp) != 1) + || (fskip_string (ifp), FALSE) + || (fskip_string (ifp), FALSE) + || (fread (&line_num, sizeof (line_num), 1, ifp) != 1)) + { + perror (filename); + done (1); + } + } + else if (gmon_io_read_vma (ifp, &addr) + || gmon_io_read_vma (ifp, &ncalls)) + { + perror (filename); + done (1); + } + + /* Basic-block execution counts are meaningful only if we're + profiling at the line-by-line level: */ + if (line_granularity) + { + sym = sym_lookup (&symtab, addr); + + if (sym) + { + int i; + + DBG (BBDEBUG, + printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n", + (unsigned long) addr, (unsigned long) sym->addr, + sym->name, sym->line_num, (unsigned long) ncalls)); + + for (i = 0; i < NBBS; i++) + { + if (! sym->bb_addr[i] || sym->bb_addr[i] == addr) + { + sym->bb_addr[i] = addr; + sym->bb_calls[i] += ncalls; + break; + } + } + } + } + else + { + static bfd_boolean user_warned = FALSE; + + if (!user_warned) + { + user_warned = TRUE; + fprintf (stderr, + _("%s: warning: ignoring basic-block exec counts (use -l or --line)\n"), + whoami); + } + } + } + return; +} + +/* Write all basic-blocks with non-zero counts to file OFP. FILENAME + is the name of OFP and is provided for producing error-messages + only. */ +void +bb_write_blocks (ofp, filename) + FILE *ofp; + const char *filename; +{ + unsigned int nblocks = 0; + Sym *sym; + int i; + + /* Count how many non-zero blocks with have: */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + for (i = 0; i < NBBS && sym->bb_addr[i]; i++) + ; + nblocks += i; + } + + /* Write header: */ + if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT) + || gmon_io_write_32 (ofp, nblocks)) + { + perror (filename); + done (1); + } + + /* Write counts: */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + for (i = 0; i < NBBS && sym->bb_addr[i]; i++) + { + if (gmon_io_write_vma (ofp, sym->bb_addr[i]) + || gmon_io_write_vma (ofp, (bfd_vma) sym->bb_calls[i])) + { + perror (filename); + done (1); + } + } + } +} + +/* Output basic-block statistics in a format that is easily parseable. + Current the format is: + + <filename>:<line-number>: (<function-name>:<bb-addr): <ncalls> */ + +void +print_exec_counts () +{ + Sym **sorted_bbs, *sym; + unsigned int i, j, len; + + if (first_output) + first_output = FALSE; + else + printf ("\f\n"); + + /* Sort basic-blocks according to function name and line number: */ + sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0])); + len = 0; + + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + /* Accept symbol if it's in the INCL_EXEC table + or there is no INCL_EXEC table + and it does not appear in the EXCL_EXEC table. */ + if (sym_lookup (&syms[INCL_EXEC], sym->addr) + || (syms[INCL_EXEC].len == 0 + && !sym_lookup (&syms[EXCL_EXEC], sym->addr))) + { + sorted_bbs[len++] = sym; + } + } + + qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb); + + /* Output basic-blocks: */ + + for (i = 0; i < len; ++i) + { + if (sym->ncalls > 0 || ! ignore_zeros) + { + /* FIXME: This only works if bfd_vma is unsigned long. */ + printf (_("%s:%d: (%s:0x%lx) %lu executions\n"), + sym->file ? sym->file->name : _("<unknown>"), sym->line_num, + sym->name, (unsigned long) sym->addr, sym->ncalls); + } + + for (j = 0; j < NBBS && sym->bb_addr[j]; j ++) + { + if (sym->bb_calls[j] > 0 || ! ignore_zeros) + { + /* FIXME: This only works if bfd_vma is unsigned long. */ + printf (_("%s:%d: (%s:0x%lx) %lu executions\n"), + sym->file ? sym->file->name : _("<unknown>"), sym->line_num, + sym->name, (unsigned long) sym->bb_addr[j], + sym->bb_calls[j]); + } + } + } + free (sorted_bbs); +} + +/* Helper for bb_annotated_source: format annotation containing + number of line executions. Depends on being called on each + line of a file in sequential order. + + Global variable bb_annotate_all_lines enables execution count + compression (counts are supressed if identical to the last one) + and prints counts on all executed lines. Otherwise, print + all basic-block execution counts exactly once on the line + that starts the basic-block. */ + +static void +annotate_with_count (buf, width, line_num, arg) + char *buf; + unsigned int width; + int line_num; + PTR arg; +{ + Source_File *sf = arg; + Sym *b; + unsigned int i; + static unsigned long last_count; + unsigned long last_print = (unsigned long) -1; + + b = NULL; + + if (line_num <= sf->num_lines) + b = sf->line[line_num - 1]; + + if (!b) + { + for (i = 0; i < width; i++) + buf[i] = ' '; + buf[width] = '\0'; + } + else + { + char tmpbuf[NBBS * 30]; + char *p; + unsigned long ncalls; + int ncalls_set; + unsigned int len; + + ++num_executable_lines; + + p = tmpbuf; + *p = '\0'; + + ncalls = 0; + ncalls_set = 0; + + /* If this is a function entry point, label the line no matter what. + Otherwise, we're in the middle of a function, so check to see + if the first basic-block address is larger than the starting + address of the line. If so, then this line begins with a + a portion of the previous basic-block, so print that prior + execution count (if bb_annotate_all_lines is set). */ + if (b->is_func) + { + sprintf (p, "%lu", b->ncalls); + p += strlen (p); + last_count = b->ncalls; + last_print = last_count; + ncalls = b->ncalls; + ncalls_set = 1; + } + else if (bb_annotate_all_lines + && b->bb_addr[0] && b->bb_addr[0] > b->addr) + { + sprintf (p, "%lu", last_count); + p += strlen (p); + last_print = last_count; + ncalls = last_count; + ncalls_set = 1; + } + + /* Loop through all of this line's basic-blocks. For each one, + update last_count, then compress sequential identical counts + (if bb_annotate_all_lines) and print the execution count. */ + + for (i = 0; i < NBBS && b->bb_addr[i]; i++) + { + last_count = b->bb_calls[i]; + if (! ncalls_set) + { + ncalls = 0; + ncalls_set = 1; + } + ncalls += last_count; + + if (bb_annotate_all_lines && last_count == last_print) + continue; + + if (p > tmpbuf) + *p++ = ','; + sprintf (p, "%lu", last_count); + p += strlen (p); + + last_print = last_count; + } + + /* We're done. If nothing has been printed on this line, + print the last execution count (bb_annotate_all_lines), + which could be from either a previous line (if there were + no BBs on this line), or from this line (if all our BB + counts were compressed out because they were identical). */ + + if (bb_annotate_all_lines && p == tmpbuf) + { + sprintf (p, "%lu", last_count); + p += strlen (p); + ncalls = last_count; + ncalls_set = 1; + } + + if (! ncalls_set) + { + unsigned int c; + + for (c = 0; c < width; c++) + buf[c] = ' '; + buf[width] = '\0'; + return; + } + + ++num_lines_executed; + + if (ncalls < bb_min_calls) + { + strcpy (tmpbuf, "#####"); + p = tmpbuf + 5; + } + + strcpy (p, " -> "); + p += 4; + + len = p - tmpbuf; + if (len >= width) + { + strncpy (buf, tmpbuf, width); + buf[width] = '\0'; + } + else + { + unsigned int c; + + strcpy (buf + width - len, tmpbuf); + for (c = 0; c < width - len; ++c) + buf[c] = ' '; + } + } +} + +/* Annotate the files named in SOURCE_FILES with basic-block statistics + (execution counts). After each source files, a few statistics + regarding that source file are printed. */ + +void +print_annotated_source () +{ + Sym *sym, *line_stats, *new_line; + Source_File *sf; + int i, table_len; + FILE *ofp; + + /* Find maximum line number for each source file that user is + interested in: */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + /* Accept symbol if it's file is known, its line number is + bigger than anything we have seen for that file so far and + if it's in the INCL_ANNO table or there is no INCL_ANNO + table and it does not appear in the EXCL_ANNO table. */ + if (sym->file && sym->line_num > sym->file->num_lines + && (sym_lookup (&syms[INCL_ANNO], sym->addr) + || (syms[INCL_ANNO].len == 0 + && !sym_lookup (&syms[EXCL_ANNO], sym->addr)))) + { + sym->file->num_lines = sym->line_num; + } + } + + /* Allocate line descriptors: */ + for (sf = first_src_file; sf; sf = sf->next) + { + if (sf->num_lines > 0) + { + sf->line = (void *) xmalloc (sf->num_lines * sizeof (sf->line[0])); + memset (sf->line, 0, sf->num_lines * sizeof (sf->line[0])); + } + } + + /* Count executions per line: */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + if (sym->file && sym->file->num_lines + && (sym_lookup (&syms[INCL_ANNO], sym->addr) + || (syms[INCL_ANNO].len == 0 + && !sym_lookup (&syms[EXCL_ANNO], sym->addr)))) + { + sym->file->ncalls += sym->ncalls; + line_stats = sym->file->line[sym->line_num - 1]; + + if (!line_stats) + { + /* Common case has at most one basic-block per source line: */ + sym->file->line[sym->line_num - 1] = sym; + } + else if (!line_stats->addr) + { + /* sym is the 3rd .. nth basic block for this line: */ + line_stats->ncalls += sym->ncalls; + } + else + { + /* sym is the second basic block for this line. */ + new_line = (Sym *) xmalloc (sizeof (*new_line)); + *new_line = *line_stats; + new_line->addr = 0; + new_line->ncalls += sym->ncalls; + sym->file->line[sym->line_num - 1] = new_line; + } + } + } + + /* Plod over source files, annotating them: */ + for (sf = first_src_file; sf; sf = sf->next) + { + if (!sf->num_lines || (ignore_zeros && sf->ncalls == 0)) + continue; + + num_executable_lines = num_lines_executed = 0; + + ofp = annotate_source (sf, 16, annotate_with_count, sf); + if (!ofp) + continue; + + if (bb_table_length > 0) + { + fprintf (ofp, _("\n\nTop %d Lines:\n\n Line Count\n\n"), + bb_table_length); + + /* Abuse line arrays---it's not needed anymore: */ + qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls); + table_len = bb_table_length; + + if (table_len > sf->num_lines) + table_len = sf->num_lines; + + for (i = 0; i < table_len; ++i) + { + sym = sf->line[i]; + + if (!sym || sym->ncalls == 0) + break; + + fprintf (ofp, "%9d %10lu\n", sym->line_num, sym->ncalls); + } + } + + free (sf->line); + sf->line = 0; + + fprintf (ofp, _("\nExecution Summary:\n\n")); + fprintf (ofp, _("%9ld Executable lines in this file\n"), + num_executable_lines); + fprintf (ofp, _("%9ld Lines executed\n"), num_lines_executed); + fprintf (ofp, _("%9.2f Percent of the file executed\n"), + num_executable_lines + ? 100.0 * num_lines_executed / (double) num_executable_lines + : 100.0); + fprintf (ofp, _("\n%9lu Total number of line executions\n"), + sf->ncalls); + fprintf (ofp, _("%9.2f Average executions per line\n"), + num_executable_lines + ? (double) sf->ncalls / (double) num_executable_lines + : 0.0); + + if (ofp != stdout) + fclose (ofp); + } +} diff --git a/gprof/basic_blocks.h b/gprof/basic_blocks.h new file mode 100644 index 000000000000..4308a792595f --- /dev/null +++ b/gprof/basic_blocks.h @@ -0,0 +1,33 @@ +/* basic_blocks.h + Copyright 2000, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef basic_blocks_h +#define basic_blocks_h + +/* Options: */ +extern bfd_boolean bb_annotate_all_lines; /* Force annotation of all lines? */ +extern int bb_table_length; /* Length of most-used bb table. */ +extern unsigned long bb_min_calls; /* Minimum execution count. */ + +extern void bb_read_rec PARAMS ((FILE *, const char *)); +extern void bb_write_blocks PARAMS ((FILE *, const char *)); +extern void bb_create_syms PARAMS ((void)); +extern void print_annotated_source PARAMS ((void)); +extern void print_exec_counts PARAMS ((void)); +#endif /* basic_blocks_h */ diff --git a/gprof/bb_exit_func.c b/gprof/bb_exit_func.c new file mode 100644 index 000000000000..33f9296cef59 --- /dev/null +++ b/gprof/bb_exit_func.c @@ -0,0 +1,93 @@ +/* bb_exit_func.c - dumps all the basic-block statistics linked into + the bb_head chain to .d files. + + Copyright 2000, 2001 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + + This code was contributed by: + + David Mosberger-Tang <David.Mosberger@acm.org> */ + +#include <stdio.h> +#include <strings.h> +#include "bfd.h" +#include "gmon_out.h" + +/* structure emitted by -a */ +struct bb +{ + long zero_word; + const char *filename; + long *counts; + long ncounts; + struct bb *next; + const unsigned long *addresses; +}; + +struct bb *__bb_head = (struct bb *) 0; + + +void +__bb_exit_func (void) +{ + const int version = GMON_VERSION; + struct gmon_hdr ghdr; + struct bb *ptr; + FILE *fp; + /* GEN_GMON_CNT_FILE should be defined on systems with mcleanup() + functions that do not write basic-block to gmon.out. In such + cases profiling with "-pg -a" would result in a gmon.out file + without basic-block info (because the file written here would be + overwritten. Thus, a separate file is generated instead. The + two files can easily be combined by specifying them on gprof's + command line (and possibly generating a gmon.sum file with "gprof + -s"). */ +#ifndef GEN_GMON_CNT_FILE +# define OUT_NAME "gmon.out" +#else +# define OUT_NAME "gmon.cnt" +#endif + fp = fopen (OUT_NAME, "wb"); + if (!fp) + { + perror (OUT_NAME); + return; + } + memcpy (&ghdr.cookie[0], GMON_MAGIC, 4); + memcpy (&ghdr.version, &version, sizeof (version)); + fwrite (&ghdr, sizeof (ghdr), 1, fp); + + for (ptr = __bb_head; ptr != 0; ptr = ptr->next) + { + u_int ncounts = ptr->ncounts; + u_char tag; + u_int i; + + tag = GMON_TAG_BB_COUNT; + fwrite (&tag, sizeof (tag), 1, fp); + fwrite (&ncounts, sizeof (ncounts), 1, fp); + + for (i = 0; i < ncounts; ++i) + { + fwrite (&ptr->addresses[i], sizeof (ptr->addresses[0]), 1, fp); + fwrite (&ptr->counts[i], sizeof (ptr->counts[0]), 1, fp); + } + } + fclose (fp); +} diff --git a/gprof/bbconv.pl b/gprof/bbconv.pl new file mode 100755 index 000000000000..d83c00e2db9d --- /dev/null +++ b/gprof/bbconv.pl @@ -0,0 +1,55 @@ +#! /usr/bin/perl + +# This script converts a "bb.out" file into a format +# suitable for processing by gprof +# +# Copyright 2001 Free Software Foundation, Inc. +# +# This file is part of GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Write a new-style gmon header + +print pack("A4Ix12", "gmon", 1); + + +# The input file format contains header lines and data lines. +# Header lines contain a count of how many data lines follow before +# the next header line. $blockcount is set to the count that +# appears in each header line, then decremented at each data line. +# $blockcount should always be zero at the start of a header line, +# and should never be zero at the start of a data line. + +$blockcount=0; + +while (<>) { + if (/^File .*, ([0-9]+) basic blocks/) { + print STDERR "Miscount: line $.\n" if ($blockcount != 0); + $blockcount = $1; + + print pack("cI", 2, $blockcount); + } + if (/Block.*executed([ 0-9]+) time.* address= 0x([0-9a-fA-F]*)/) { + print STDERR "Miscount: line $.\n" if ($blockcount == 0); + $blockcount-- if ($blockcount > 0); + + $count = $1; + $addr = hex $2; + + print pack("II",$addr,$count); + } +} diff --git a/gprof/bsd_callg_bl.c b/gprof/bsd_callg_bl.c new file mode 100644 index 000000000000..e6f9b36a2fb1 --- /dev/null +++ b/gprof/bsd_callg_bl.c @@ -0,0 +1,120 @@ +/* ==> Do not modify this file!! It is created automatically + from bsd_callg_bl.m using the gen-c-prog.awk script. <== */ + +#include <stdio.h> +#include "ansidecl.h" + +void bsd_callg_blurb PARAMS ((FILE *)); +void +bsd_callg_blurb (file) + FILE *file; +{ + fputs ("\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs ("call graph profile:\n", file); + fputs (" The sum of self and descendents is the major sort\n", file); + fputs (" for this listing.\n", file); + fputs ("\n", file); + fputs (" function entries:\n", file); + fputs ("\n", file); + fputs ("index the index of the function in the call graph\n", file); + fputs (" listing, as an aid to locating it (see below).\n", file); + fputs ("\n", file); + fputs ("%time the percentage of the total time of the program\n", file); + fputs (" accounted for by this function and its\n", file); + fputs (" descendents.\n", file); + fputs ("\n", file); + fputs ("self the number of seconds spent in this function\n", file); + fputs (" itself.\n", file); + fputs ("\n", file); + fputs ("descendents\n", file); + fputs (" the number of seconds spent in the descendents of\n", file); + fputs (" this function on behalf of this function.\n", file); + fputs ("\n", file); + fputs ("called the number of times this function is called (other\n", file); + fputs (" than recursive calls).\n", file); + fputs ("\n", file); + fputs ("self the number of times this function calls itself\n", file); + fputs (" recursively.\n", file); + fputs ("\n", file); + fputs ("name the name of the function, with an indication of\n", file); + fputs (" its membership in a cycle, if any.\n", file); + fputs ("\n", file); + fputs ("index the index of the function in the call graph\n", file); + fputs (" listing, as an aid to locating it.\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs (" parent listings:\n", file); + fputs ("\n", file); + fputs ("self* the number of seconds of this function's self time\n", file); + fputs (" which is due to calls from this parent.\n", file); + fputs ("\n", file); + fputs ("descendents*\n", file); + fputs (" the number of seconds of this function's\n", file); + fputs (" descendent time which is due to calls from this\n", file); + fputs (" parent.\n", file); + fputs ("\n", file); + fputs ("called** the number of times this function is called by\n", file); + fputs (" this parent. This is the numerator of the\n", file); + fputs (" fraction which divides up the function's time to\n", file); + fputs (" its parents.\n", file); + fputs ("\n", file); + fputs ("total* the number of times this function was called by\n", file); + fputs (" all of its parents. This is the denominator of\n", file); + fputs (" the propagation fraction.\n", file); + fputs ("\n", file); + fputs ("parents the name of this parent, with an indication of the\n", file); + fputs (" parent's membership in a cycle, if any.\n", file); + fputs ("\n", file); + fputs ("index the index of this parent in the call graph\n", file); + fputs (" listing, as an aid in locating it.\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs (" children listings:\n", file); + fputs ("\n", file); + fputs ("self* the number of seconds of this child's self time\n", file); + fputs (" which is due to being called by this function.\n", file); + fputs ("\n", file); + fputs ("descendent*\n", file); + fputs (" the number of seconds of this child's descendent's\n", file); + fputs (" time which is due to being called by this\n", file); + fputs (" function.\n", file); + fputs ("\n", file); + fputs ("called** the number of times this child is called by this\n", file); + fputs (" function. This is the numerator of the\n", file); + fputs (" propagation fraction for this child.\n", file); + fputs ("\n", file); + fputs ("total* the number of times this child is called by all\n", file); + fputs (" functions. This is the denominator of the\n", file); + fputs (" propagation fraction.\n", file); + fputs ("\n", file); + fputs ("children the name of this child, and an indication of its\n", file); + fputs (" membership in a cycle, if any.\n", file); + fputs ("\n", file); + fputs ("index the index of this child in the call graph listing,\n", file); + fputs (" as an aid to locating it.\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs (" * these fields are omitted for parents (or\n", file); + fputs (" children) in the same cycle as the function. If\n", file); + fputs (" the function (or child) is a member of a cycle,\n", file); + fputs (" the propagated times and propagation denominator\n", file); + fputs (" represent the self time and descendent time of the\n", file); + fputs (" cycle as a whole.\n", file); + fputs ("\n", file); + fputs (" ** static-only parents and children are indicated\n", file); + fputs (" by a call count of 0.\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs (" cycle listings:\n", file); + fputs (" the cycle as a whole is listed with the same\n", file); + fputs (" fields as a function entry. Below it are listed\n", file); + fputs (" the members of the cycle, and their contributions\n", file); + fputs (" to the time and call counts of the cycle.\n", file); + fputs ("\n", file); +} diff --git a/gprof/bsd_callg_bl.m b/gprof/bsd_callg_bl.m new file mode 100644 index 000000000000..533c96ca4396 --- /dev/null +++ b/gprof/bsd_callg_bl.m @@ -0,0 +1,108 @@ + + + +call graph profile: + The sum of self and descendents is the major sort + for this listing. + + function entries: + +index the index of the function in the call graph + listing, as an aid to locating it (see below). + +%time the percentage of the total time of the program + accounted for by this function and its + descendents. + +self the number of seconds spent in this function + itself. + +descendents + the number of seconds spent in the descendents of + this function on behalf of this function. + +called the number of times this function is called (other + than recursive calls). + +self the number of times this function calls itself + recursively. + +name the name of the function, with an indication of + its membership in a cycle, if any. + +index the index of the function in the call graph + listing, as an aid to locating it. + + + + parent listings: + +self* the number of seconds of this function's self time + which is due to calls from this parent. + +descendents* + the number of seconds of this function's + descendent time which is due to calls from this + parent. + +called** the number of times this function is called by + this parent. This is the numerator of the + fraction which divides up the function's time to + its parents. + +total* the number of times this function was called by + all of its parents. This is the denominator of + the propagation fraction. + +parents the name of this parent, with an indication of the + parent's membership in a cycle, if any. + +index the index of this parent in the call graph + listing, as an aid in locating it. + + + + children listings: + +self* the number of seconds of this child's self time + which is due to being called by this function. + +descendent* + the number of seconds of this child's descendent's + time which is due to being called by this + function. + +called** the number of times this child is called by this + function. This is the numerator of the + propagation fraction for this child. + +total* the number of times this child is called by all + functions. This is the denominator of the + propagation fraction. + +children the name of this child, and an indication of its + membership in a cycle, if any. + +index the index of this child in the call graph listing, + as an aid to locating it. + + + + * these fields are omitted for parents (or + children) in the same cycle as the function. If + the function (or child) is a member of a cycle, + the propagated times and propagation denominator + represent the self time and descendent time of the + cycle as a whole. + + ** static-only parents and children are indicated + by a call count of 0. + + + + cycle listings: + the cycle as a whole is listed with the same + fields as a function entry. Below it are listed + the members of the cycle, and their contributions + to the time and call counts of the cycle. + diff --git a/gprof/call_graph.c b/gprof/call_graph.c new file mode 100644 index 000000000000..e798a0e18975 --- /dev/null +++ b/gprof/call_graph.c @@ -0,0 +1,137 @@ +/* call_graph.c - Create call graphs. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "call_graph.h" +#include "corefile.h" +#include "gmon_io.h" +#include "gmon_out.h" +#include "sym_ids.h" + +void +cg_tally (from_pc, self_pc, count) + bfd_vma from_pc; + bfd_vma self_pc; + unsigned long count; +{ + Sym *parent; + Sym *child; + + parent = sym_lookup (&symtab, from_pc); + child = sym_lookup (&symtab, self_pc); + + if (child == NULL || parent == NULL) + return; + + /* If we're doing line-by-line profiling, both the parent and the + child will probably point to line symbols instead of function + symbols. For the parent this is fine, since this identifies the + line number in the calling routing, but the child should always + point to a function entry point, so we back up in the symbol + table until we find it. + + For normal profiling, is_func will be set on all symbols, so this + code will do nothing. */ + while (child >= symtab.base && ! child->is_func) + --child; + + if (child < symtab.base) + return; + + /* Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table + is empty and it is not in the EXCL_ARCS table. */ + if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child) + || (syms[INCL_ARCS].len == 0 + && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child))) + { + child->ncalls += count; + DBG (TALLYDEBUG, + printf (_("[cg_tally] arc from %s to %s traversed %lu times\n"), + parent->name, child->name, count)); + arc_add (parent, child, count); + } +} + +/* Read a record from file IFP describing an arc in the function + call-graph and the count of how many times the arc has been + traversed. FILENAME is the name of file IFP and is provided + for formatting error-messages only. */ + +void +cg_read_rec (ifp, filename) + FILE *ifp; + const char *filename; +{ + bfd_vma from_pc, self_pc; + unsigned int count; + + if (gmon_io_read_vma (ifp, &from_pc) + || gmon_io_read_vma (ifp, &self_pc) + || gmon_io_read_32 (ifp, &count)) + { + fprintf (stderr, _("%s: %s: unexpected end of file\n"), + whoami, filename); + done (1); + } + + DBG (SAMPLEDEBUG, + printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %lu\n", + (unsigned long) from_pc, (unsigned long) self_pc, + (unsigned long) count)); + /* Add this arc: */ + cg_tally (from_pc, self_pc, count); +} + +/* Write all the arcs in the call-graph to file OFP. FILENAME is + the name of OFP and is provided for formatting error-messages + only. */ + +void +cg_write_arcs (ofp, filename) + FILE *ofp; + const char *filename; +{ + Arc *arc; + Sym *sym; + + for (sym = symtab.base; sym < symtab.limit; sym++) + { + for (arc = sym->cg.children; arc; arc = arc->next_child) + { + if (gmon_io_write_8 (ofp, GMON_TAG_CG_ARC) + || gmon_io_write_vma (ofp, arc->parent->addr) + || gmon_io_write_vma (ofp, arc->child->addr) + || gmon_io_write_32 (ofp, arc->count)) + { + perror (filename); + done (1); + } + DBG (SAMPLEDEBUG, + printf ("[cg_write_arcs] frompc 0x%lx selfpc 0x%lx count %lu\n", + (unsigned long) arc->parent->addr, + (unsigned long) arc->child->addr, arc->count)); + } + } +} diff --git a/gprof/call_graph.h b/gprof/call_graph.h new file mode 100644 index 000000000000..233dd701ecbf --- /dev/null +++ b/gprof/call_graph.h @@ -0,0 +1,28 @@ +/* call_graph.h + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef call_graph_h +#define call_graph_h + +extern void cg_tally PARAMS ((bfd_vma, bfd_vma, unsigned long)); +extern void cg_read_rec PARAMS ((FILE *, const char *)); +extern void cg_write_arcs PARAMS ((FILE *, const char *)); + +#endif /* call_graph_h */ diff --git a/gprof/cg_arcs.c b/gprof/cg_arcs.c new file mode 100644 index 000000000000..cea21cf50538 --- /dev/null +++ b/gprof/cg_arcs.c @@ -0,0 +1,717 @@ +/* + * Copyright (c) 1983, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "call_graph.h" +#include "cg_arcs.h" +#include "cg_dfn.h" +#include "cg_print.h" +#include "utils.h" +#include "sym_ids.h" + +static int cmp_topo PARAMS ((const PTR, const PTR)); +static void propagate_time PARAMS ((Sym *)); +static void cycle_time PARAMS ((void)); +static void cycle_link PARAMS ((void)); +static void inherit_flags PARAMS ((Sym *)); +static void propagate_flags PARAMS ((Sym **)); +static int cmp_total PARAMS ((const PTR, const PTR)); + +Sym *cycle_header; +unsigned int num_cycles; +Arc **arcs; +unsigned int numarcs; + +/* + * Return TRUE iff PARENT has an arc to covers the address + * range covered by CHILD. + */ +Arc * +arc_lookup (parent, child) + Sym *parent; + Sym *child; +{ + Arc *arc; + + if (!parent || !child) + { + printf ("[arc_lookup] parent == 0 || child == 0\n"); + return 0; + } + DBG (LOOKUPDEBUG, printf ("[arc_lookup] parent %s child %s\n", + parent->name, child->name)); + for (arc = parent->cg.children; arc; arc = arc->next_child) + { + DBG (LOOKUPDEBUG, printf ("[arc_lookup]\t parent %s child %s\n", + arc->parent->name, arc->child->name)); + if (child->addr >= arc->child->addr + && child->end_addr <= arc->child->end_addr) + { + return arc; + } + } + return 0; +} + + +/* + * Add (or just increment) an arc: + */ +void +arc_add (parent, child, count) + Sym *parent; + Sym *child; + unsigned long count; +{ + static unsigned int maxarcs = 0; + Arc *arc, **newarcs; + + DBG (TALLYDEBUG, printf ("[arc_add] %lu arcs from %s to %s\n", + count, parent->name, child->name)); + arc = arc_lookup (parent, child); + if (arc) + { + /* + * A hit: just increment the count. + */ + DBG (TALLYDEBUG, printf ("[tally] hit %lu += %lu\n", + arc->count, count)); + arc->count += count; + return; + } + arc = (Arc *) xmalloc (sizeof (*arc)); + memset (arc, 0, sizeof (*arc)); + arc->parent = parent; + arc->child = child; + arc->count = count; + + /* If this isn't an arc for a recursive call to parent, then add it + to the array of arcs. */ + if (parent != child) + { + /* If we've exhausted space in our current array, get a new one + and copy the contents. We might want to throttle the doubling + factor one day. */ + if (numarcs == maxarcs) + { + /* Determine how much space we want to allocate. */ + if (maxarcs == 0) + maxarcs = 1; + maxarcs *= 2; + + /* Allocate the new array. */ + newarcs = (Arc **)xmalloc(sizeof (Arc *) * maxarcs); + + /* Copy the old array's contents into the new array. */ + memcpy (newarcs, arcs, numarcs * sizeof (Arc *)); + + /* Free up the old array. */ + free (arcs); + + /* And make the new array be the current array. */ + arcs = newarcs; + } + + /* Place this arc in the arc array. */ + arcs[numarcs++] = arc; + } + + /* prepend this child to the children of this parent: */ + arc->next_child = parent->cg.children; + parent->cg.children = arc; + + /* prepend this parent to the parents of this child: */ + arc->next_parent = child->cg.parents; + child->cg.parents = arc; +} + + +static int +cmp_topo (lp, rp) + const PTR lp; + const PTR rp; +{ + const Sym *left = *(const Sym **) lp; + const Sym *right = *(const Sym **) rp; + + return left->cg.top_order - right->cg.top_order; +} + + +static void +propagate_time (parent) + Sym *parent; +{ + Arc *arc; + Sym *child; + double share, prop_share; + + if (parent->cg.prop.fract == 0.0) + { + return; + } + + /* gather time from children of this parent: */ + + for (arc = parent->cg.children; arc; arc = arc->next_child) + { + child = arc->child; + if (arc->count == 0 || child == parent || child->cg.prop.fract == 0) + { + continue; + } + if (child->cg.cyc.head != child) + { + if (parent->cg.cyc.num == child->cg.cyc.num) + { + continue; + } + if (parent->cg.top_order <= child->cg.top_order) + { + fprintf (stderr, "[propagate] toporder botches\n"); + } + child = child->cg.cyc.head; + } + else + { + if (parent->cg.top_order <= child->cg.top_order) + { + fprintf (stderr, "[propagate] toporder botches\n"); + continue; + } + } + if (child->ncalls == 0) + { + continue; + } + + /* distribute time for this arc: */ + arc->time = child->hist.time * (((double) arc->count) + / ((double) child->ncalls)); + arc->child_time = child->cg.child_time + * (((double) arc->count) / ((double) child->ncalls)); + share = arc->time + arc->child_time; + parent->cg.child_time += share; + + /* (1 - cg.prop.fract) gets lost along the way: */ + prop_share = parent->cg.prop.fract * share; + + /* fix things for printing: */ + parent->cg.prop.child += prop_share; + arc->time *= parent->cg.prop.fract; + arc->child_time *= parent->cg.prop.fract; + + /* add this share to the parent's cycle header, if any: */ + if (parent->cg.cyc.head != parent) + { + parent->cg.cyc.head->cg.child_time += share; + parent->cg.cyc.head->cg.prop.child += prop_share; + } + DBG (PROPDEBUG, + printf ("[prop_time] child \t"); + print_name (child); + printf (" with %f %f %lu/%lu\n", child->hist.time, + child->cg.child_time, arc->count, child->ncalls); + printf ("[prop_time] parent\t"); + print_name (parent); + printf ("\n[prop_time] share %f\n", share)); + } +} + + +/* + * Compute the time of a cycle as the sum of the times of all + * its members. + */ +static void +cycle_time () +{ + Sym *member, *cyc; + + for (cyc = &cycle_header[1]; cyc <= &cycle_header[num_cycles]; ++cyc) + { + for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next) + { + if (member->cg.prop.fract == 0.0) + { + /* + * All members have the same propfraction except those + * that were excluded with -E. + */ + continue; + } + cyc->hist.time += member->hist.time; + } + cyc->cg.prop.self = cyc->cg.prop.fract * cyc->hist.time; + } +} + + +static void +cycle_link () +{ + Sym *sym, *cyc, *member; + Arc *arc; + int num; + + /* count the number of cycles, and initialize the cycle lists: */ + + num_cycles = 0; + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + /* this is how you find unattached cycles: */ + if (sym->cg.cyc.head == sym && sym->cg.cyc.next) + { + ++num_cycles; + } + } + + /* + * cycle_header is indexed by cycle number: i.e. it is origin 1, + * not origin 0. + */ + cycle_header = (Sym *) xmalloc ((num_cycles + 1) * sizeof (Sym)); + + /* + * Now link cycles to true cycle-heads, number them, accumulate + * the data for the cycle. + */ + num = 0; + cyc = cycle_header; + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + if (!(sym->cg.cyc.head == sym && sym->cg.cyc.next != 0)) + { + continue; + } + ++num; + ++cyc; + sym_init (cyc); + cyc->cg.print_flag = TRUE; /* should this be printed? */ + cyc->cg.top_order = DFN_NAN; /* graph call chain top-sort order */ + cyc->cg.cyc.num = num; /* internal number of cycle on */ + cyc->cg.cyc.head = cyc; /* pointer to head of cycle */ + cyc->cg.cyc.next = sym; /* pointer to next member of cycle */ + DBG (CYCLEDEBUG, printf ("[cycle_link] "); + print_name (sym); + printf (" is the head of cycle %d\n", num)); + + /* link members to cycle header: */ + for (member = sym; member; member = member->cg.cyc.next) + { + member->cg.cyc.num = num; + member->cg.cyc.head = cyc; + } + + /* + * Count calls from outside the cycle and those among cycle + * members: + */ + for (member = sym; member; member = member->cg.cyc.next) + { + for (arc = member->cg.parents; arc; arc = arc->next_parent) + { + if (arc->parent == member) + { + continue; + } + if (arc->parent->cg.cyc.num == num) + { + cyc->cg.self_calls += arc->count; + } + else + { + cyc->ncalls += arc->count; + } + } + } + } +} + + +/* + * Check if any parent of this child (or outside parents of this + * cycle) have their print flags on and set the print flag of the + * child (cycle) appropriately. Similarly, deal with propagation + * fractions from parents. + */ +static void +inherit_flags (child) + Sym *child; +{ + Sym *head, *parent, *member; + Arc *arc; + + head = child->cg.cyc.head; + if (child == head) + { + /* just a regular child, check its parents: */ + child->cg.print_flag = FALSE; + child->cg.prop.fract = 0.0; + for (arc = child->cg.parents; arc; arc = arc->next_parent) + { + parent = arc->parent; + if (child == parent) + { + continue; + } + child->cg.print_flag |= parent->cg.print_flag; + /* + * If the child was never actually called (e.g., this arc + * is static (and all others are, too)) no time propagates + * along this arc. + */ + if (child->ncalls != 0) + { + child->cg.prop.fract += parent->cg.prop.fract + * (((double) arc->count) / ((double) child->ncalls)); + } + } + } + else + { + /* + * Its a member of a cycle, look at all parents from outside + * the cycle. + */ + head->cg.print_flag = FALSE; + head->cg.prop.fract = 0.0; + for (member = head->cg.cyc.next; member; member = member->cg.cyc.next) + { + for (arc = member->cg.parents; arc; arc = arc->next_parent) + { + if (arc->parent->cg.cyc.head == head) + { + continue; + } + parent = arc->parent; + head->cg.print_flag |= parent->cg.print_flag; + /* + * If the cycle was never actually called (e.g. this + * arc is static (and all others are, too)) no time + * propagates along this arc. + */ + if (head->ncalls != 0) + { + head->cg.prop.fract += parent->cg.prop.fract + * (((double) arc->count) / ((double) head->ncalls)); + } + } + } + for (member = head; member; member = member->cg.cyc.next) + { + member->cg.print_flag = head->cg.print_flag; + member->cg.prop.fract = head->cg.prop.fract; + } + } +} + + +/* + * In one top-to-bottom pass over the topologically sorted symbols + * propagate: + * cg.print_flag as the union of parents' print_flags + * propfraction as the sum of fractional parents' propfractions + * and while we're here, sum time for functions. + */ +static void +propagate_flags (symbols) + Sym **symbols; +{ + int index; + Sym *old_head, *child; + + old_head = 0; + for (index = symtab.len - 1; index >= 0; --index) + { + child = symbols[index]; + /* + * If we haven't done this function or cycle, inherit things + * from parent. This way, we are linear in the number of arcs + * since we do all members of a cycle (and the cycle itself) + * as we hit the first member of the cycle. + */ + if (child->cg.cyc.head != old_head) + { + old_head = child->cg.cyc.head; + inherit_flags (child); + } + DBG (PROPDEBUG, + printf ("[prop_flags] "); + print_name (child); + printf ("inherits print-flag %d and prop-fract %f\n", + child->cg.print_flag, child->cg.prop.fract)); + if (!child->cg.print_flag) + { + /* + * Printflag is off. It gets turned on by being in the + * INCL_GRAPH table, or there being an empty INCL_GRAPH + * table and not being in the EXCL_GRAPH table. + */ + if (sym_lookup (&syms[INCL_GRAPH], child->addr) + || (syms[INCL_GRAPH].len == 0 + && !sym_lookup (&syms[EXCL_GRAPH], child->addr))) + { + child->cg.print_flag = TRUE; + } + } + else + { + /* + * This function has printing parents: maybe someone wants + * to shut it up by putting it in the EXCL_GRAPH table. + * (But favor INCL_GRAPH over EXCL_GRAPH.) + */ + if (!sym_lookup (&syms[INCL_GRAPH], child->addr) + && sym_lookup (&syms[EXCL_GRAPH], child->addr)) + { + child->cg.print_flag = FALSE; + } + } + if (child->cg.prop.fract == 0.0) + { + /* + * No parents to pass time to. Collect time from children + * if its in the INCL_TIME table, or there is an empty + * INCL_TIME table and its not in the EXCL_TIME table. + */ + if (sym_lookup (&syms[INCL_TIME], child->addr) + || (syms[INCL_TIME].len == 0 + && !sym_lookup (&syms[EXCL_TIME], child->addr))) + { + child->cg.prop.fract = 1.0; + } + } + else + { + /* + * It has parents to pass time to, but maybe someone wants + * to shut it up by puttting it in the EXCL_TIME table. + * (But favor being in INCL_TIME tabe over being in + * EXCL_TIME table.) + */ + if (!sym_lookup (&syms[INCL_TIME], child->addr) + && sym_lookup (&syms[EXCL_TIME], child->addr)) + { + child->cg.prop.fract = 0.0; + } + } + child->cg.prop.self = child->hist.time * child->cg.prop.fract; + print_time += child->cg.prop.self; + DBG (PROPDEBUG, + printf ("[prop_flags] "); + print_name (child); + printf (" ends up with printflag %d and prop-fract %f\n", + child->cg.print_flag, child->cg.prop.fract); + printf ("[prop_flags] time %f propself %f print_time %f\n", + child->hist.time, child->cg.prop.self, print_time)); + } +} + + +/* + * Compare by decreasing propagated time. If times are equal, but one + * is a cycle header, say that's first (e.g. less, i.e. -1). If one's + * name doesn't have an underscore and the other does, say that one is + * first. All else being equal, compare by names. + */ +static int +cmp_total (lp, rp) + const PTR lp; + const PTR rp; +{ + const Sym *left = *(const Sym **) lp; + const Sym *right = *(const Sym **) rp; + double diff; + + diff = (left->cg.prop.self + left->cg.prop.child) + - (right->cg.prop.self + right->cg.prop.child); + if (diff < 0.0) + { + return 1; + } + if (diff > 0.0) + { + return -1; + } + if (!left->name && left->cg.cyc.num != 0) + { + return -1; + } + if (!right->name && right->cg.cyc.num != 0) + { + return 1; + } + if (!left->name) + { + return -1; + } + if (!right->name) + { + return 1; + } + if (left->name[0] != '_' && right->name[0] == '_') + { + return -1; + } + if (left->name[0] == '_' && right->name[0] != '_') + { + return 1; + } + if (left->ncalls > right->ncalls) + { + return -1; + } + if (left->ncalls < right->ncalls) + { + return 1; + } + return strcmp (left->name, right->name); +} + + +/* + * Topologically sort the graph (collapsing cycles), and propagates + * time bottom up and flags top down. + */ +Sym ** +cg_assemble () +{ + Sym *parent, **time_sorted_syms, **top_sorted_syms; + unsigned int index; + Arc *arc; + + /* + * initialize various things: + * zero out child times. + * count self-recursive calls. + * indicate that nothing is on cycles. + */ + for (parent = symtab.base; parent < symtab.limit; parent++) + { + parent->cg.child_time = 0.0; + arc = arc_lookup (parent, parent); + if (arc && parent == arc->child) + { + parent->ncalls -= arc->count; + parent->cg.self_calls = arc->count; + } + else + { + parent->cg.self_calls = 0; + } + parent->cg.prop.fract = 0.0; + parent->cg.prop.self = 0.0; + parent->cg.prop.child = 0.0; + parent->cg.print_flag = FALSE; + parent->cg.top_order = DFN_NAN; + parent->cg.cyc.num = 0; + parent->cg.cyc.head = parent; + parent->cg.cyc.next = 0; + if (ignore_direct_calls) + { + find_call (parent, parent->addr, (parent + 1)->addr); + } + } + /* + * Topologically order things. If any node is unnumbered, number + * it and any of its descendents. + */ + for (parent = symtab.base; parent < symtab.limit; parent++) + { + if (parent->cg.top_order == DFN_NAN) + { + cg_dfn (parent); + } + } + + /* link together nodes on the same cycle: */ + cycle_link (); + + /* sort the symbol table in reverse topological order: */ + top_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + for (index = 0; index < symtab.len; ++index) + { + top_sorted_syms[index] = &symtab.base[index]; + } + qsort (top_sorted_syms, symtab.len, sizeof (Sym *), cmp_topo); + DBG (DFNDEBUG, + printf ("[cg_assemble] topological sort listing\n"); + for (index = 0; index < symtab.len; ++index) + { + printf ("[cg_assemble] "); + printf ("%d:", top_sorted_syms[index]->cg.top_order); + print_name (top_sorted_syms[index]); + printf ("\n"); + } + ); + /* + * Starting from the topological top, propagate print flags to + * children. also, calculate propagation fractions. this happens + * before time propagation since time propagation uses the + * fractions. + */ + propagate_flags (top_sorted_syms); + + /* + * Starting from the topological bottom, propogate children times + * up to parents. + */ + cycle_time (); + for (index = 0; index < symtab.len; ++index) + { + propagate_time (top_sorted_syms[index]); + } + + free (top_sorted_syms); + + /* + * Now, sort by CG.PROP.SELF + CG.PROP.CHILD. Sorting both the regular + * function names and cycle headers. + */ + time_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); + for (index = 0; index < symtab.len; index++) + { + time_sorted_syms[index] = &symtab.base[index]; + } + for (index = 1; index <= num_cycles; index++) + { + time_sorted_syms[symtab.len + index - 1] = &cycle_header[index]; + } + qsort (time_sorted_syms, symtab.len + num_cycles, sizeof (Sym *), + cmp_total); + for (index = 0; index < symtab.len + num_cycles; index++) + { + time_sorted_syms[index]->cg.index = index + 1; + } + return time_sorted_syms; +} diff --git a/gprof/cg_arcs.h b/gprof/cg_arcs.h new file mode 100644 index 000000000000..0364eefa2e91 --- /dev/null +++ b/gprof/cg_arcs.h @@ -0,0 +1,33 @@ +#ifndef cg_arcs_h +#define cg_arcs_h + +/* + * Arc structure for call-graph. + * + * With pointers to the symbols of the parent and the child, a count + * of how many times this arc was traversed, and pointers to the next + * parent of this child and the next child of this parent. + */ +typedef struct arc + { + Sym *parent; /* source vertice of arc */ + Sym *child; /* dest vertice of arc */ + unsigned long count; /* # of calls from parent to child */ + double time; /* time inherited along arc */ + double child_time; /* child-time inherited along arc */ + struct arc *next_parent; /* next parent of CHILD */ + struct arc *next_child; /* next child of PARENT */ + int has_been_placed; /* have this arc's functions been placed? */ + } +Arc; + +extern unsigned int num_cycles; /* number of cycles discovered */ +extern Sym *cycle_header; /* cycle headers */ + +extern void arc_add PARAMS ((Sym * parent, Sym * child, unsigned long count)); +extern Arc *arc_lookup PARAMS ((Sym * parent, Sym * child)); +extern Sym **cg_assemble PARAMS ((void)); +extern Arc **arcs; +extern unsigned int numarcs; + +#endif /* cg_arcs_h */ diff --git a/gprof/cg_dfn.c b/gprof/cg_dfn.c new file mode 100644 index 000000000000..5c8b5ec745e2 --- /dev/null +++ b/gprof/cg_dfn.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "cg_dfn.h" +#include "utils.h" + +#define DFN_INCR_DEPTH (128) + +typedef struct + { + Sym *sym; + int cycle_top; + } +DFN_Stack; + +static bfd_boolean is_numbered PARAMS ((Sym *)); +static bfd_boolean is_busy PARAMS ((Sym *)); +static void find_cycle PARAMS ((Sym *)); +static void pre_visit PARAMS ((Sym *)); +static void post_visit PARAMS ((Sym *)); + +DFN_Stack *dfn_stack = NULL; +int dfn_maxdepth = 0; +int dfn_depth = 0; +int dfn_counter = DFN_NAN; + + +/* + * Is CHILD already numbered? + */ +static bfd_boolean +is_numbered (child) + Sym *child; +{ + return child->cg.top_order != DFN_NAN && child->cg.top_order != DFN_BUSY; +} + + +/* + * Is CHILD already busy? + */ +static bfd_boolean +is_busy (child) + Sym *child; +{ + if (child->cg.top_order == DFN_NAN) + { + return FALSE; + } + return TRUE; +} + + +/* + * CHILD is part of a cycle. Find the top caller into this cycle + * that is not part of the cycle and make all functions in cycle + * members of that cycle (top caller == caller with smallest + * depth-first number). + */ +static void +find_cycle (child) + Sym *child; +{ + Sym *head = 0; + Sym *tail; + int cycle_top; + int index; + + for (cycle_top = dfn_depth; cycle_top > 0; --cycle_top) + { + head = dfn_stack[cycle_top].sym; + if (child == head) + { + break; + } + if (child->cg.cyc.head != child && child->cg.cyc.head == head) + { + break; + } + } + if (cycle_top <= 0) + { + fprintf (stderr, "[find_cycle] couldn't find head of cycle\n"); + done (1); + } +#ifdef DEBUG + if (debug_level & DFNDEBUG) + { + printf ("[find_cycle] dfn_depth %d cycle_top %d ", + dfn_depth, cycle_top); + if (head) + { + print_name (head); + } + else + { + printf ("<unknown>"); + } + printf ("\n"); + } +#endif + if (cycle_top == dfn_depth) + { + /* + * This is previous function, e.g. this calls itself. Sort of + * boring. + * + * Since we are taking out self-cycles elsewhere no need for + * the special case, here. + */ + DBG (DFNDEBUG, + printf ("[find_cycle] "); + print_name (child); + printf ("\n")); + } + else + { + /* + * Glom intervening functions that aren't already glommed into + * this cycle. Things have been glommed when their cyclehead + * field points to the head of the cycle they are glommed + * into. + */ + for (tail = head; tail->cg.cyc.next; tail = tail->cg.cyc.next) + { + /* void: chase down to tail of things already glommed */ + DBG (DFNDEBUG, + printf ("[find_cycle] tail "); + print_name (tail); + printf ("\n")); + } + /* + * If what we think is the top of the cycle has a cyclehead + * field, then it's not really the head of the cycle, which is + * really what we want. + */ + if (head->cg.cyc.head != head) + { + head = head->cg.cyc.head; + DBG (DFNDEBUG, printf ("[find_cycle] new cyclehead "); + print_name (head); + printf ("\n")); + } + for (index = cycle_top + 1; index <= dfn_depth; ++index) + { + child = dfn_stack[index].sym; + if (child->cg.cyc.head == child) + { + /* + * Not yet glommed anywhere, glom it and fix any + * children it has glommed. + */ + tail->cg.cyc.next = child; + child->cg.cyc.head = head; + DBG (DFNDEBUG, printf ("[find_cycle] glomming "); + print_name (child); + printf (" onto "); + print_name (head); + printf ("\n")); + for (tail = child; tail->cg.cyc.next; tail = tail->cg.cyc.next) + { + tail->cg.cyc.next->cg.cyc.head = head; + DBG (DFNDEBUG, printf ("[find_cycle] and its tail "); + print_name (tail->cg.cyc.next); + printf (" onto "); + print_name (head); + printf ("\n")); + } + } + else if (child->cg.cyc.head != head /* firewall */ ) + { + fprintf (stderr, "[find_cycle] glommed, but not to head\n"); + done (1); + } + } + } +} + + +/* + * Prepare for visiting the children of PARENT. Push a parent onto + * the stack and mark it busy. + */ +static void +pre_visit (parent) + Sym *parent; +{ + ++dfn_depth; + + if (dfn_depth >= dfn_maxdepth) + { + dfn_maxdepth += DFN_INCR_DEPTH; + dfn_stack = xrealloc (dfn_stack, dfn_maxdepth * sizeof *dfn_stack); + } + + dfn_stack[dfn_depth].sym = parent; + dfn_stack[dfn_depth].cycle_top = dfn_depth; + parent->cg.top_order = DFN_BUSY; + DBG (DFNDEBUG, printf ("[pre_visit]\t\t%d:", dfn_depth); + print_name (parent); + printf ("\n")); +} + + +/* + * Done with visiting node PARENT. Pop PARENT off dfn_stack + * and number functions if PARENT is head of a cycle. + */ +static void +post_visit (parent) + Sym *parent; +{ + Sym *member; + + DBG (DFNDEBUG, printf ("[post_visit]\t%d: ", dfn_depth); + print_name (parent); + printf ("\n")); + /* + * Number functions and things in their cycles unless the function + * is itself part of a cycle: + */ + if (parent->cg.cyc.head == parent) + { + ++dfn_counter; + for (member = parent; member; member = member->cg.cyc.next) + { + member->cg.top_order = dfn_counter; + DBG (DFNDEBUG, printf ("[post_visit]\t\tmember "); + print_name (member); + printf ("-> cg.top_order = %d\n", dfn_counter)); + } + } + else + { + DBG (DFNDEBUG, printf ("[post_visit]\t\tis part of a cycle\n")); + } + --dfn_depth; +} + + +/* + * Given this PARENT, depth first number its children. + */ +void +cg_dfn (parent) + Sym *parent; +{ + Arc *arc; + + DBG (DFNDEBUG, printf ("[dfn] dfn( "); + print_name (parent); + printf (")\n")); + /* + * If we're already numbered, no need to look any further: + */ + if (is_numbered (parent)) + { + return; + } + /* + * If we're already busy, must be a cycle: + */ + if (is_busy (parent)) + { + find_cycle (parent); + return; + } + pre_visit (parent); + /* + * Recursively visit children: + */ + for (arc = parent->cg.children; arc; arc = arc->next_child) + { + cg_dfn (arc->child); + } + post_visit (parent); +} diff --git a/gprof/cg_dfn.h b/gprof/cg_dfn.h new file mode 100644 index 000000000000..4bd3030257c8 --- /dev/null +++ b/gprof/cg_dfn.h @@ -0,0 +1,17 @@ +#ifndef cg_dfn_h +#define cg_dfn_h + +/* + * Flags which mark a symbol as topologically ``busy'' or as + * topologically ``not_numbered'': + */ +#define DFN_BUSY -1 +#define DFN_NAN 0 + +/* + * Depth-first numbering of a call-graph. + */ + +extern void cg_dfn PARAMS ((Sym * root)); + +#endif /* cg_dfn_h */ diff --git a/gprof/cg_print.c b/gprof/cg_print.c new file mode 100644 index 000000000000..21847027c1c7 --- /dev/null +++ b/gprof/cg_print.c @@ -0,0 +1,1297 @@ +/* cg_print.c - Print routines for displaying call graphs. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "cg_print.h" +#include "hist.h" +#include "utils.h" +#include "corefile.h" + +/* Return value of comparison functions used to sort tables. */ +#define LESSTHAN -1 +#define EQUALTO 0 +#define GREATERTHAN 1 + +static void print_header PARAMS ((void)); +static void print_cycle PARAMS ((Sym *)); +static int cmp_member PARAMS ((Sym *, Sym *)); +static void sort_members PARAMS ((Sym *)); +static void print_members PARAMS ((Sym *)); +static int cmp_arc PARAMS ((Arc *, Arc *)); +static void sort_parents PARAMS ((Sym *)); +static void print_parents PARAMS ((Sym *)); +static void sort_children PARAMS ((Sym *)); +static void print_children PARAMS ((Sym *)); +static void print_line PARAMS ((Sym *)); +static int cmp_name PARAMS ((const PTR, const PTR)); +static int cmp_arc_count PARAMS ((const PTR, const PTR)); +static int cmp_fun_nuses PARAMS ((const PTR, const PTR)); +static void order_and_dump_functions_by_arcs + PARAMS ((Arc **, unsigned long, int, Arc **, unsigned long *)); + +/* Declarations of automatically generated functions to output blurbs. */ +extern void bsd_callg_blurb PARAMS ((FILE * fp)); +extern void fsf_callg_blurb PARAMS ((FILE * fp)); + +double print_time = 0.0; + + +static void +print_header () +{ + if (first_output) + first_output = FALSE; + else + printf ("\f\n"); + + if (!bsd_style_output) + { + if (print_descriptions) + printf (_("\t\t Call graph (explanation follows)\n\n")); + else + printf (_("\t\t\tCall graph\n\n")); + } + + printf (_("\ngranularity: each sample hit covers %ld byte(s)"), + (long) hist_scale * sizeof (UNIT)); + + if (print_time > 0.0) + printf (_(" for %.2f%% of %.2f seconds\n\n"), + 100.0 / print_time, print_time / hz); + else + { + printf (_(" no time propagated\n\n")); + + /* This doesn't hurt, since all the numerators will be 0.0. */ + print_time = 1.0; + } + + if (bsd_style_output) + { + printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", + "", "", "", "", _("called"), _("total"), _("parents")); + printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n", + _("index"), _("%time"), _("self"), _("descendants"), + _("called"), _("self"), _("name"), _("index")); + printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", + "", "", "", "", _("called"), _("total"), _("children")); + printf ("\n"); + } + else + { + printf (_("index %% time self children called name\n")); + } +} + +/* Print a cycle header. */ + +static void +print_cycle (cyc) + Sym *cyc; +{ + char buf[BUFSIZ]; + + sprintf (buf, "[%d]", cyc->cg.index); + printf (bsd_style_output + ? "%-6.6s %5.1f %7.2f %11.2f %7lu" + : "%-6.6s %5.1f %7.2f %7.2f %7lu", buf, + 100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time, + cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls); + + if (cyc->cg.self_calls != 0) + printf ("+%-7lu", cyc->cg.self_calls); + else + printf (" %7.7s", ""); + + printf (_(" <cycle %d as a whole> [%d]\n"), cyc->cg.cyc.num, cyc->cg.index); +} + +/* Compare LEFT and RIGHT membmer. Major comparison key is + CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS. */ + +static int +cmp_member (left, right) + Sym *left; + Sym *right; +{ + double left_time = left->cg.prop.self + left->cg.prop.child; + double right_time = right->cg.prop.self + right->cg.prop.child; + unsigned long left_calls = left->ncalls + left->cg.self_calls; + unsigned long right_calls = right->ncalls + right->cg.self_calls; + + if (left_time > right_time) + return GREATERTHAN; + + if (left_time < right_time) + return LESSTHAN; + + if (left_calls > right_calls) + return GREATERTHAN; + + if (left_calls < right_calls) + return LESSTHAN; + + return EQUALTO; +} + +/* Sort members of a cycle. */ + +static void +sort_members (cyc) + Sym *cyc; +{ + Sym *todo, *doing, *prev; + + /* Detach cycle members from cyclehead, + and insertion sort them back on. */ + todo = cyc->cg.cyc.next; + cyc->cg.cyc.next = 0; + + for (doing = todo; doing && doing->cg.cyc.next; doing = todo) + { + todo = doing->cg.cyc.next; + + for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next) + { + if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN) + break; + } + + doing->cg.cyc.next = prev->cg.cyc.next; + prev->cg.cyc.next = doing; + } +} + +/* Print the members of a cycle. */ + +static void +print_members (cyc) + Sym *cyc; +{ + Sym *member; + + sort_members (cyc); + + for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next) + { + printf (bsd_style_output + ? "%6.6s %5.5s %7.2f %11.2f %7lu" + : "%6.6s %5.5s %7.2f %7.2f %7lu", + "", "", member->cg.prop.self / hz, member->cg.prop.child / hz, + member->ncalls); + + if (member->cg.self_calls != 0) + printf ("+%-7lu", member->cg.self_calls); + else + printf (" %7.7s", ""); + + printf (" "); + print_name (member); + printf ("\n"); + } +} + +/* Compare two arcs to/from the same child/parent. + - if one arc is a self arc, it's least. + - if one arc is within a cycle, it's less than. + - if both arcs are within a cycle, compare arc counts. + - if neither arc is within a cycle, compare with + time + child_time as major key + arc count as minor key. */ + +static int +cmp_arc (left, right) + Arc *left; + Arc *right; +{ + Sym *left_parent = left->parent; + Sym *left_child = left->child; + Sym *right_parent = right->parent; + Sym *right_child = right->child; + double left_time, right_time; + + DBG (TIMEDEBUG, + printf ("[cmp_arc] "); + print_name (left_parent); + printf (" calls "); + print_name (left_child); + printf (" %f + %f %lu/%lu\n", left->time, left->child_time, + left->count, left_child->ncalls); + printf ("[cmp_arc] "); + print_name (right_parent); + printf (" calls "); + print_name (right_child); + printf (" %f + %f %lu/%lu\n", right->time, right->child_time, + right->count, right_child->ncalls); + printf ("\n"); + ); + + if (left_parent == left_child) + return LESSTHAN; /* Left is a self call. */ + + if (right_parent == right_child) + return GREATERTHAN; /* Right is a self call. */ + + if (left_parent->cg.cyc.num != 0 && left_child->cg.cyc.num != 0 + && left_parent->cg.cyc.num == left_child->cg.cyc.num) + { + /* Left is a call within a cycle. */ + if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0 + && right_parent->cg.cyc.num == right_child->cg.cyc.num) + { + /* Right is a call within the cycle, too. */ + if (left->count < right->count) + return LESSTHAN; + + if (left->count > right->count) + return GREATERTHAN; + + return EQUALTO; + } + else + { + /* Right isn't a call within the cycle. */ + return LESSTHAN; + } + } + else + { + /* Left isn't a call within a cycle. */ + if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0 + && right_parent->cg.cyc.num == right_child->cg.cyc.num) + { + /* Right is a call within a cycle. */ + return GREATERTHAN; + } + else + { + /* Neither is a call within a cycle. */ + left_time = left->time + left->child_time; + right_time = right->time + right->child_time; + + if (left_time < right_time) + return LESSTHAN; + + if (left_time > right_time) + return GREATERTHAN; + + if (left->count < right->count) + return LESSTHAN; + + if (left->count > right->count) + return GREATERTHAN; + + return EQUALTO; + } + } +} + + +static void +sort_parents (child) + Sym * child; +{ + Arc *arc, *detached, sorted, *prev; + + /* Unlink parents from child, then insertion sort back on to + sorted's parents. + *arc the arc you have detached and are inserting. + *detached the rest of the arcs to be sorted. + sorted arc list onto which you insertion sort. + *prev arc before the arc you are comparing. */ + sorted.next_parent = 0; + + for (arc = child->cg.parents; arc; arc = detached) + { + detached = arc->next_parent; + + /* Consider *arc as disconnected; insert it into sorted. */ + for (prev = &sorted; prev->next_parent; prev = prev->next_parent) + { + if (cmp_arc (arc, prev->next_parent) != GREATERTHAN) + break; + } + + arc->next_parent = prev->next_parent; + prev->next_parent = arc; + } + + /* Reattach sorted arcs to child. */ + child->cg.parents = sorted.next_parent; +} + + +static void +print_parents (child) + Sym *child; +{ + Sym *parent; + Arc *arc; + Sym *cycle_head; + + if (child->cg.cyc.head != 0) + cycle_head = child->cg.cyc.head; + else + cycle_head = child; + + if (!child->cg.parents) + { + printf (bsd_style_output + ? _("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n") + : _("%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n"), + "", "", "", "", "", ""); + return; + } + + sort_parents (child); + + for (arc = child->cg.parents; arc; arc = arc->next_parent) + { + parent = arc->parent; + if (child == parent || (child->cg.cyc.num != 0 + && parent->cg.cyc.num == child->cg.cyc.num)) + { + /* Selfcall or call among siblings. */ + printf (bsd_style_output + ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s " + : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ", + "", "", "", "", + arc->count, ""); + print_name (parent); + printf ("\n"); + } + else + { + /* Regular parent of child. */ + printf (bsd_style_output + ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu " + : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ", + "", "", + arc->time / hz, arc->child_time / hz, + arc->count, cycle_head->ncalls); + print_name (parent); + printf ("\n"); + } + } +} + + +static void +sort_children (parent) + Sym *parent; +{ + Arc *arc, *detached, sorted, *prev; + + /* Unlink children from parent, then insertion sort back on to + sorted's children. + *arc the arc you have detached and are inserting. + *detached the rest of the arcs to be sorted. + sorted arc list onto which you insertion sort. + *prev arc before the arc you are comparing. */ + sorted.next_child = 0; + + for (arc = parent->cg.children; arc; arc = detached) + { + detached = arc->next_child; + + /* Consider *arc as disconnected; insert it into sorted. */ + for (prev = &sorted; prev->next_child; prev = prev->next_child) + { + if (cmp_arc (arc, prev->next_child) != LESSTHAN) + break; + } + + arc->next_child = prev->next_child; + prev->next_child = arc; + } + + /* Reattach sorted children to parent. */ + parent->cg.children = sorted.next_child; +} + + +static void +print_children (parent) + Sym *parent; +{ + Sym *child; + Arc *arc; + + sort_children (parent); + arc = parent->cg.children; + + for (arc = parent->cg.children; arc; arc = arc->next_child) + { + child = arc->child; + if (child == parent || (child->cg.cyc.num != 0 + && child->cg.cyc.num == parent->cg.cyc.num)) + { + /* Self call or call to sibling. */ + printf (bsd_style_output + ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s " + : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ", + "", "", "", "", arc->count, ""); + print_name (child); + printf ("\n"); + } + else + { + /* Regular child of parent. */ + printf (bsd_style_output + ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu " + : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ", + "", "", + arc->time / hz, arc->child_time / hz, + arc->count, child->cg.cyc.head->ncalls); + print_name (child); + printf ("\n"); + } + } +} + + +static void +print_line (np) + Sym *np; +{ + char buf[BUFSIZ]; + + sprintf (buf, "[%d]", np->cg.index); + printf (bsd_style_output + ? "%-6.6s %5.1f %7.2f %11.2f" + : "%-6.6s %5.1f %7.2f %7.2f", buf, + 100 * (np->cg.prop.self + np->cg.prop.child) / print_time, + np->cg.prop.self / hz, np->cg.prop.child / hz); + + if ((np->ncalls + np->cg.self_calls) != 0) + { + printf (" %7lu", np->ncalls); + + if (np->cg.self_calls != 0) + printf ("+%-7lu ", np->cg.self_calls); + else + printf (" %7.7s ", ""); + } + else + { + printf (" %7.7s %7.7s ", "", ""); + } + + print_name (np); + printf ("\n"); +} + + +/* Print dynamic call graph. */ + +void +cg_print (timesortsym) + Sym ** timesortsym; +{ + unsigned int index; + Sym *parent; + + if (print_descriptions && bsd_style_output) + bsd_callg_blurb (stdout); + + print_header (); + + for (index = 0; index < symtab.len + num_cycles; ++index) + { + parent = timesortsym[index]; + + if ((ignore_zeros && parent->ncalls == 0 + && parent->cg.self_calls == 0 && parent->cg.prop.self == 0 + && parent->cg.prop.child == 0) + || !parent->cg.print_flag + || (line_granularity && ! parent->is_func)) + continue; + + if (!parent->name && parent->cg.cyc.num != 0) + { + /* Cycle header. */ + print_cycle (parent); + print_members (parent); + } + else + { + print_parents (parent); + print_line (parent); + print_children (parent); + } + + if (bsd_style_output) + printf ("\n"); + + printf ("-----------------------------------------------\n"); + + if (bsd_style_output) + printf ("\n"); + } + + free (timesortsym); + + if (print_descriptions && !bsd_style_output) + fsf_callg_blurb (stdout); +} + + +static int +cmp_name (left, right) + const PTR left; + const PTR right; +{ + const Sym **npp1 = (const Sym **) left; + const Sym **npp2 = (const Sym **) right; + + return strcmp ((*npp1)->name, (*npp2)->name); +} + + +void +cg_print_index () +{ + unsigned int index; + unsigned int nnames, todo, i, j; + int col, starting_col; + Sym **name_sorted_syms, *sym; + const char *filename; + char buf[20]; + int column_width = (output_width - 1) / 3; /* Don't write in last col! */ + + /* Now, sort regular function name + alphabetically to create an index. */ + name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); + + for (index = 0, nnames = 0; index < symtab.len; index++) + { + if (ignore_zeros && symtab.base[index].ncalls == 0 + && symtab.base[index].hist.time == 0) + continue; + + name_sorted_syms[nnames++] = &symtab.base[index]; + } + + qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name); + + for (index = 1, todo = nnames; index <= num_cycles; index++) + name_sorted_syms[todo++] = &cycle_header[index]; + + printf ("\f\n"); + printf (_("Index by function name\n\n")); + index = (todo + 2) / 3; + + for (i = 0; i < index; i++) + { + col = 0; + starting_col = 0; + + for (j = i; j < todo; j += index) + { + sym = name_sorted_syms[j]; + + if (sym->cg.print_flag) + sprintf (buf, "[%d]", sym->cg.index); + else + sprintf (buf, "(%d)", sym->cg.index); + + if (j < nnames) + { + if (bsd_style_output) + { + printf ("%6.6s %-19.19s", buf, sym->name); + } + else + { + col += strlen (buf); + + for (; col < starting_col + 5; ++col) + putchar (' '); + + printf (" %s ", buf); + col += print_name_only (sym); + + if (!line_granularity && sym->is_static && sym->file) + { + filename = sym->file->name; + + if (!print_path) + { + filename = strrchr (filename, '/'); + + if (filename) + ++filename; + else + filename = sym->file->name; + } + + printf (" (%s)", filename); + col += strlen (filename) + 3; + } + } + } + else + { + if (bsd_style_output) + { + printf ("%6.6s ", buf); + sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num); + printf ("%-19.19s", buf); + } + else + { + col += strlen (buf); + for (; col < starting_col + 5; ++col) + putchar (' '); + printf (" %s ", buf); + sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num); + printf ("%s", buf); + col += strlen (buf); + } + } + + starting_col += column_width; + } + + printf ("\n"); + } + + free (name_sorted_syms); +} + +/* Compare two arcs based on their usage counts. + We want to sort in descending order. */ + +static int +cmp_arc_count (left, right) + const PTR left; + const PTR right; +{ + const Arc **npp1 = (const Arc **) left; + const Arc **npp2 = (const Arc **) right; + + if ((*npp1)->count > (*npp2)->count) + return -1; + else if ((*npp1)->count < (*npp2)->count) + return 1; + else + return 0; +} + +/* Compare two funtions based on their usage counts. + We want to sort in descending order. */ + +static int +cmp_fun_nuses (left, right) + const PTR left; + const PTR right; +{ + const Sym **npp1 = (const Sym **) left; + const Sym **npp2 = (const Sym **) right; + + if ((*npp1)->nuses > (*npp2)->nuses) + return -1; + else if ((*npp1)->nuses < (*npp2)->nuses) + return 1; + else + return 0; +} + +/* Print a suggested function ordering based on the profiling data. + + We perform 4 major steps when ordering functions: + + * Group unused functions together and place them at the + end of the function order. + + * Search the highest use arcs (those which account for 90% of + the total arc count) for functions which have several parents. + + Group those with the most call sites together (currently the + top 1.25% which have at least five different call sites). + + These are emitted at the start of the function order. + + * Use a greedy placement algorithm to place functions which + occur in the top 99% of the arcs in the profile. Some provisions + are made to handle high usage arcs where the parent and/or + child has already been placed. + + * Run the same greedy placement algorithm on the remaining + arcs to place the leftover functions. + + + The various "magic numbers" should (one day) be tuneable by command + line options. They were arrived at by benchmarking a few applications + with various values to see which values produced better overall function + orderings. + + Of course, profiling errors, machine limitations (PA long calls), and + poor cutoff values for the placement algorithm may limit the usefullness + of the resulting function order. Improvements would be greatly appreciated. + + Suggestions: + + * Place the functions with many callers near the middle of the + list to reduce long calls. + + * Propagate arc usage changes as functions are placed. Ie if + func1 and func2 are placed together, arcs to/from those arcs + to the same parent/child should be combined, then resort the + arcs to choose the next one. + + * Implement some global positioning algorithm to place the + chains made by the greedy local positioning algorithm. Probably + by examining arcs which haven't been placed yet to tie two + chains together. + + * Take a function's size and time into account in the algorithm; + size in particular is important on the PA (long calls). Placing + many small functions onto their own page may be wise. + + * Use better profiling information; many published algorithms + are based on call sequences through time, rather than just + arc counts. + + * Prodecure cloning could improve performance when a small number + of arcs account for most of the calls to a particular function. + + * Use relocation information to avoid moving unused functions + completely out of the code stream; this would avoid severe lossage + when the profile data bears little resemblance to actual runs. + + * Propagation of arc usages should also improve .o link line + ordering which shares the same arc placement algorithm with + the function ordering code (in fact it is a degenerate case + of function ordering). */ + +void +cg_print_function_ordering () +{ + unsigned long index, used, unused, scratch_index; + unsigned long unplaced_arc_count, high_arc_count, scratch_arc_count; +#ifdef __GNUC__ + unsigned long long total_arcs, tmp_arcs_count; +#else + unsigned long total_arcs, tmp_arcs_count; +#endif + Sym **unused_syms, **used_syms, **scratch_syms; + Arc **unplaced_arcs, **high_arcs, **scratch_arcs; + + index = 0; + used = 0; + unused = 0; + scratch_index = 0; + unplaced_arc_count = 0; + high_arc_count = 0; + scratch_arc_count = 0; + + /* First group all the unused functions together. */ + unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + + /* Walk through all the functions; mark those which are never + called as placed (we'll emit them as a group later). */ + for (index = 0, used = 0, unused = 0; index < symtab.len; index++) + { + if (symtab.base[index].ncalls == 0) + { + /* Filter out gprof generated names. */ + if (strcmp (symtab.base[index].name, "<locore>") + && strcmp (symtab.base[index].name, "<hicore>")) + { + unused_syms[unused++] = &symtab.base[index]; + symtab.base[index].has_been_placed = 1; + } + } + else + { + used_syms[used++] = &symtab.base[index]; + symtab.base[index].has_been_placed = 0; + symtab.base[index].next = 0; + symtab.base[index].prev = 0; + symtab.base[index].nuses = 0; + } + } + + /* Sort the arcs from most used to least used. */ + qsort (arcs, numarcs, sizeof (Arc *), cmp_arc_count); + + /* Compute the total arc count. Also mark arcs as unplaced. + + Note we don't compensate for overflow if that happens! + Overflow is much less likely when this file is compiled + with GCC as it can double-wide integers via long long. */ + total_arcs = 0; + for (index = 0; index < numarcs; index++) + { + total_arcs += arcs[index]->count; + arcs[index]->has_been_placed = 0; + } + + /* We want to pull out those functions which are referenced + by many highly used arcs and emit them as a group. This + could probably use some tuning. */ + tmp_arcs_count = 0; + for (index = 0; index < numarcs; index++) + { + tmp_arcs_count += arcs[index]->count; + + /* Count how many times each parent and child are used up + to our threshhold of arcs (90%). */ + if ((double)tmp_arcs_count / (double)total_arcs > 0.90) + break; + + arcs[index]->child->nuses++; + } + + /* Now sort a temporary symbol table based on the number of + times each function was used in the highest used arcs. */ + memcpy (scratch_syms, used_syms, used * sizeof (Sym *)); + qsort (scratch_syms, used, sizeof (Sym *), cmp_fun_nuses); + + /* Now pick out those symbols we're going to emit as + a group. We take up to 1.25% of the used symbols. */ + for (index = 0; index < used / 80; index++) + { + Sym *sym = scratch_syms[index]; + Arc *arc; + + /* If we hit symbols that aren't used from many call sites, + then we can quit. We choose five as the low limit for + no particular reason. */ + if (sym->nuses == 5) + break; + + /* We're going to need the arcs between these functions. + Unfortunately, we don't know all these functions + until we're done. So we keep track of all the arcs + to the functions we care about, then prune out those + which are uninteresting. + + An interesting variation would be to quit when we found + multi-call site functions which account for some percentage + of the arcs. */ + arc = sym->cg.children; + + while (arc) + { + if (arc->parent != arc->child) + scratch_arcs[scratch_arc_count++] = arc; + arc->has_been_placed = 1; + arc = arc->next_child; + } + + arc = sym->cg.parents; + + while (arc) + { + if (arc->parent != arc->child) + scratch_arcs[scratch_arc_count++] = arc; + arc->has_been_placed = 1; + arc = arc->next_parent; + } + + /* Keep track of how many symbols we're going to place. */ + scratch_index = index; + + /* A lie, but it makes identifying + these functions easier later. */ + sym->has_been_placed = 1; + } + + /* Now walk through the temporary arcs and copy + those we care about into the high arcs array. */ + for (index = 0; index < scratch_arc_count; index++) + { + Arc *arc = scratch_arcs[index]; + + /* If this arc refers to highly used functions, then + then we want to keep it. */ + if (arc->child->has_been_placed + && arc->parent->has_been_placed) + { + high_arcs[high_arc_count++] = scratch_arcs[index]; + + /* We need to turn of has_been_placed since we're going to + use the main arc placement algorithm on these arcs. */ + arc->child->has_been_placed = 0; + arc->parent->has_been_placed = 0; + } + } + + /* Dump the multi-site high usage functions which are not + going to be ordered by the main ordering algorithm. */ + for (index = 0; index < scratch_index; index++) + { + if (scratch_syms[index]->has_been_placed) + printf ("%s\n", scratch_syms[index]->name); + } + + /* Now we can order the multi-site high use + functions based on the arcs between them. */ + qsort (high_arcs, high_arc_count, sizeof (Arc *), cmp_arc_count); + order_and_dump_functions_by_arcs (high_arcs, high_arc_count, 1, + unplaced_arcs, &unplaced_arc_count); + + /* Order and dump the high use functions left, + these typically have only a few call sites. */ + order_and_dump_functions_by_arcs (arcs, numarcs, 0, + unplaced_arcs, &unplaced_arc_count); + + /* Now place the rarely used functions. */ + order_and_dump_functions_by_arcs (unplaced_arcs, unplaced_arc_count, 1, + scratch_arcs, &scratch_arc_count); + + /* Output any functions not emitted by the order_and_dump calls. */ + for (index = 0; index < used; index++) + if (used_syms[index]->has_been_placed == 0) + printf("%s\n", used_syms[index]->name); + + /* Output the unused functions. */ + for (index = 0; index < unused; index++) + printf("%s\n", unused_syms[index]->name); + + unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + + free (unused_syms); + free (used_syms); + free (scratch_syms); + free (high_arcs); + free (scratch_arcs); + free (unplaced_arcs); +} + +/* Place functions based on the arcs in THE_ARCS with ARC_COUNT entries; + place unused arcs into UNPLACED_ARCS/UNPLACED_ARC_COUNT. + + If ALL is nonzero, then place all functions referenced by THE_ARCS, + else only place those referenced in the top 99% of the arcs in THE_ARCS. */ + +#define MOST 0.99 +static void +order_and_dump_functions_by_arcs (the_arcs, arc_count, all, + unplaced_arcs, unplaced_arc_count) + Arc **the_arcs; + unsigned long arc_count; + int all; + Arc **unplaced_arcs; + unsigned long *unplaced_arc_count; +{ +#ifdef __GNUC__ + unsigned long long tmp_arcs, total_arcs; +#else + unsigned long tmp_arcs, total_arcs; +#endif + unsigned int index; + + /* If needed, compute the total arc count. + + Note we don't compensate for overflow if that happens! */ + if (! all) + { + total_arcs = 0; + for (index = 0; index < arc_count; index++) + total_arcs += the_arcs[index]->count; + } + else + total_arcs = 0; + + tmp_arcs = 0; + + for (index = 0; index < arc_count; index++) + { + Sym *sym1, *sym2; + Sym *child, *parent; + + tmp_arcs += the_arcs[index]->count; + + /* Ignore this arc if it's already been placed. */ + if (the_arcs[index]->has_been_placed) + continue; + + child = the_arcs[index]->child; + parent = the_arcs[index]->parent; + + /* If we're not using all arcs, and this is a rarely used + arc, then put it on the unplaced_arc list. Similarly + if both the parent and child of this arc have been placed. */ + if ((! all && (double)tmp_arcs / (double)total_arcs > MOST) + || child->has_been_placed || parent->has_been_placed) + { + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + continue; + } + + /* If all slots in the parent and child are full, then there isn't + anything we can do right now. We'll place this arc on the + unplaced arc list in the hope that a global positioning + algorithm can use it to place function chains. */ + if (parent->next && parent->prev && child->next && child->prev) + { + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + continue; + } + + /* If the parent is unattached, then find the closest + place to attach it onto child's chain. Similarly + for the opposite case. */ + if (!parent->next && !parent->prev) + { + int next_count = 0; + int prev_count = 0; + Sym *prev = child; + Sym *next = child; + + /* Walk to the beginning and end of the child's chain. */ + while (next->next) + { + next = next->next; + next_count++; + } + + while (prev->prev) + { + prev = prev->prev; + prev_count++; + } + + /* Choose the closest. */ + child = next_count < prev_count ? next : prev; + } + else if (! child->next && !child->prev) + { + int next_count = 0; + int prev_count = 0; + Sym *prev = parent; + Sym *next = parent; + + while (next->next) + { + next = next->next; + next_count++; + } + + while (prev->prev) + { + prev = prev->prev; + prev_count++; + } + + parent = prev_count < next_count ? prev : next; + } + else + { + /* Couldn't find anywhere to attach the functions, + put the arc on the unplaced arc list. */ + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + continue; + } + + /* Make sure we don't tie two ends together. */ + sym1 = parent; + if (sym1->next) + while (sym1->next) + sym1 = sym1->next; + else + while (sym1->prev) + sym1 = sym1->prev; + + sym2 = child; + if (sym2->next) + while (sym2->next) + sym2 = sym2->next; + else + while (sym2->prev) + sym2 = sym2->prev; + + if (sym1 == child + && sym2 == parent) + { + /* This would tie two ends together. */ + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + continue; + } + + if (parent->next) + { + /* Must attach to the parent's prev field. */ + if (! child->next) + { + /* parent-prev and child-next */ + parent->prev = child; + child->next = parent; + the_arcs[index]->has_been_placed = 1; + } + } + else if (parent->prev) + { + /* Must attach to the parent's next field. */ + if (! child->prev) + { + /* parent-next and child-prev */ + parent->next = child; + child->prev = parent; + the_arcs[index]->has_been_placed = 1; + } + } + else + { + /* Can attach to either field in the parent, depends + on where we've got space in the child. */ + if (child->prev) + { + /* parent-prev and child-next. */ + parent->prev = child; + child->next = parent; + the_arcs[index]->has_been_placed = 1; + } + else + { + /* parent-next and child-prev. */ + parent->next = child; + child->prev = parent; + the_arcs[index]->has_been_placed = 1; + } + } + } + + /* Dump the chains of functions we've made. */ + for (index = 0; index < arc_count; index++) + { + Sym *sym; + if (the_arcs[index]->parent->has_been_placed + || the_arcs[index]->child->has_been_placed) + continue; + + sym = the_arcs[index]->parent; + + /* If this symbol isn't attached to any other + symbols, then we've got a rarely used arc. + + Skip it for now, we'll deal with them later. */ + if (sym->next == NULL + && sym->prev == NULL) + continue; + + /* Get to the start of this chain. */ + while (sym->prev) + sym = sym->prev; + + while (sym) + { + /* Mark it as placed. */ + sym->has_been_placed = 1; + printf ("%s\n", sym->name); + sym = sym->next; + } + } + + /* If we want to place all the arcs, then output + those which weren't placed by the main algorithm. */ + if (all) + for (index = 0; index < arc_count; index++) + { + Sym *sym; + if (the_arcs[index]->parent->has_been_placed + || the_arcs[index]->child->has_been_placed) + continue; + + sym = the_arcs[index]->parent; + + sym->has_been_placed = 1; + printf ("%s\n", sym->name); + } +} + +/* Print a suggested .o ordering for files on a link line based + on profiling information. This uses the function placement + code for the bulk of its work. */ + +void +cg_print_file_ordering () +{ + unsigned long scratch_arc_count, index; + Arc **scratch_arcs; + char *last; + + scratch_arc_count = 0; + + scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); + for (index = 0; index < numarcs; index++) + { + if (! arcs[index]->parent->mapped + || ! arcs[index]->child->mapped) + arcs[index]->has_been_placed = 1; + } + + order_and_dump_functions_by_arcs (arcs, numarcs, 0, + scratch_arcs, &scratch_arc_count); + + /* Output .o's not handled by the main placement algorithm. */ + for (index = 0; index < symtab.len; index++) + { + if (symtab.base[index].mapped + && ! symtab.base[index].has_been_placed) + printf ("%s\n", symtab.base[index].name); + } + + /* Now output any .o's that didn't have any text symbols. */ + last = NULL; + for (index = 0; index < symbol_map_count; index++) + { + unsigned int index2; + + /* Don't bother searching if this symbol + is the same as the previous one. */ + if (last && !strcmp (last, symbol_map[index].file_name)) + continue; + + for (index2 = 0; index2 < symtab.len; index2++) + { + if (! symtab.base[index2].mapped) + continue; + + if (!strcmp (symtab.base[index2].name, symbol_map[index].file_name)) + break; + } + + /* If we didn't find it in the symbol table, then it must + be a .o with no text symbols. Output it last. */ + if (index2 == symtab.len) + printf ("%s\n", symbol_map[index].file_name); + last = symbol_map[index].file_name; + } +} diff --git a/gprof/cg_print.h b/gprof/cg_print.h new file mode 100644 index 000000000000..ce41987df2cb --- /dev/null +++ b/gprof/cg_print.h @@ -0,0 +1,31 @@ +/* cg_print.h + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef cg_print_h +#define cg_print_h + +extern double print_time; /* Total of time being printed. */ + +extern void cg_print PARAMS ((Sym **)); +extern void cg_print_index PARAMS ((void)); +extern void cg_print_file_ordering PARAMS ((void)); +extern void cg_print_function_ordering PARAMS ((void)); + +#endif /* cg_print_h */ diff --git a/gprof/configure b/gprof/configure new file mode 100755 index 000000000000..37875c66a8be --- /dev/null +++ b/gprof/configure @@ -0,0 +1,4794 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --with-pic try to use only PIC/non-PIC objects [default=use both]" +ac_help="$ac_help + --disable-nls do not use Native Language Support" +ac_help="$ac_help + --with-included-gettext use the GNU gettext library included here" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-build-warnings Enable build-time compiler warnings if gcc is used" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +sitefile= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --site-file=FILE use FILE as the site file + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -site-file | --site-file | --site-fil | --site-fi | --site-f) + ac_prev=sitefile ;; + -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) + sitefile="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=gprof.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$sitefile"; then + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi +else + CONFIG_SITE="$sitefile" +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:557: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 562 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:590: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 595 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:602: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:667: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:688: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:706: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6 +echo "configure:730: checking for strerror in -lcposix" >&5 +ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcposix $LIBS" +cat > conftest.$ac_ext <<EOF +#line 738 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strerror(); + +int main() { +strerror() +; return 0; } +EOF +if { (eval echo configure:749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lcposix" +else + echo "$ac_t""no" 1>&6 +fi + + + + +BFD_VERSION=`sed -n -e 's/^.._INIT_AUTOMAKE.*,[ ]*\([^ ]*\)[ ]*).*/\1/p' < ${srcdir}/../bfd/configure.in` +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:785: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:838: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:895: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=gprof + +VERSION=${BFD_VERSION} + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:941: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:954: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:967: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:980: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:993: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1079: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1109: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1160: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1192: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1203 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1234: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1239: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1267: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1310: checking for ld used by GCC" >&5 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1340: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1343: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1378: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 +echo "configure:1395: checking for $LD option to reload object files" >&5 +if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_ld_reload_flag='-r' +fi + +echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1407: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1445: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 +echo "configure:1466: checking how to recognise dependant libraries" >&5 +if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.012) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | mips* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newsos6) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac + +fi + +echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + +echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:1639: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:1645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1665: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 +echo "configure:1708: checking for ${ac_tool_prefix}file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo $ac_n "checking for file""... $ac_c" 1>&6 +echo "configure:1770: checking for file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1841: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1873: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + +# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1908: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_STRIP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1940: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="strip" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + STRIP=":" +fi +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi + +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 2007 "configure"' > conftest.$ac_ext + if { (eval echo configure:2008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo configure:2041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:2059: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + cat > conftest.$ac_ext <<EOF +#line 2072 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2079: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + + + + + + + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2202: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2232: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2283: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:2315: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 2326 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:2331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:2357: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:2362: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2371: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:2390: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:2433: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +for ac_func in setmode +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2489: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2494 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +ALL_LINGUAS="fr tr sv es id da pt_BR de" +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:2544: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 2559 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2565: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 2576 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2582: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 2593 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2599: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2626: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:2654: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2659 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2684 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2702 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext <<EOF +#line 2723 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:2734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:2758: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2763 "configure" +#include "confdefs.h" + +int main() { + +/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *ccp; +char **p; +/* NEC SVR4.0.2 mips cc rejects this. */ +struct point {int x, y;}; +static struct point const zero = {0,0}; +/* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in an arm + of an if-expression whose if-part is not a constant expression */ +const char *g = "string"; +ccp = &g + (g ? g-g : 0); +/* HPUX 7.0 cc rejects these. */ +++ccp; +p = (char**) ccp; +ccp = (char const *const *) p; +{ /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; +} +{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; +} +{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; +} +{ /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:2812: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:2833: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <<EOF +#line 2840 "configure" +#include "confdefs.h" + +int main() { +} $ac_kw foo() { +; return 0; } +EOF +if { (eval echo configure:2847: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <<EOF +#define inline $ac_cv_c_inline +EOF + ;; +esac + +echo $ac_n "checking for off_t""... $ac_c" 1>&6 +echo "configure:2873: checking for off_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2878 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_off_t=yes +else + rm -rf conftest* + ac_cv_type_off_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_off_t" 1>&6 +if test $ac_cv_type_off_t = no; then + cat >> confdefs.h <<\EOF +#define off_t long +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:2906: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2911 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 +echo "configure:2941: checking for working alloca.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2946 "configure" +#include "confdefs.h" +#include <alloca.h> +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:2953: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&6 +echo "configure:2974: checking for alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2979 "configure" +#include "confdefs.h" + +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int main() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if { (eval echo configure:3007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_alloca_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_alloca_works=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 +if test $ac_cv_func_alloca_works = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca_works = no; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.${ac_objext} + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 +echo "configure:3039: checking whether alloca needs Cray hooks" >&5 +if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3044 "configure" +#include "confdefs.h" +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_os_cray" 1>&6 +if test $ac_cv_os_cray = yes; then +for ac_func in _getb67 GETB67 getb67; do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3069: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3074 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<EOF +#define CRAY_STACKSEG_END $ac_func +EOF + + break +else + echo "$ac_t""no" 1>&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:3124: checking stack direction for C alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat > conftest.$ac_ext <<EOF +#line 3132 "configure" +#include "confdefs.h" +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:3151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_stack_direction=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_stack_direction=-1 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 +cat >> confdefs.h <<EOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3176: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3181 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3186: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3215: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3220 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:3268: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext <<EOF +#line 3276 "configure" +#include "confdefs.h" + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the filesystem buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propogated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ +#include <sys/types.h> +#include <fcntl.h> +#include <sys/mman.h> + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include <unistd.h> +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:3416: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + + + for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3444: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3449 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3454: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3484: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3489 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3512: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + for ac_func in stpcpy +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3541: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3546 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STPCPY 1 +EOF + + fi + + if test $ac_cv_header_locale_h = yes; then + echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 +echo "configure:3603: checking for LC_MESSAGES" >&5 +if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3608 "configure" +#include "confdefs.h" +#include <locale.h> +int main() { +return LC_MESSAGES +; return 0; } +EOF +if { (eval echo configure:3615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + am_cv_val_LC_MESSAGES=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + am_cv_val_LC_MESSAGES=no +fi +rm -f conftest* +fi + +echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 + if test $am_cv_val_LC_MESSAGES = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LC_MESSAGES 1 +EOF + + fi + fi + echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 +echo "configure:3636: checking whether NLS is requested" >&5 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=$enableval +else + USE_NLS=yes +fi + + echo "$ac_t""$USE_NLS" 1>&6 + + + USE_INCLUDED_LIBINTL=no + + if test "$USE_NLS" = "yes"; then + cat >> confdefs.h <<\EOF +#define ENABLE_NLS 1 +EOF + + echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 +echo "configure:3656: checking whether included gettext is requested" >&5 + # Check whether --with-included-gettext or --without-included-gettext was given. +if test "${with_included_gettext+set}" = set; then + withval="$with_included_gettext" + nls_cv_force_use_gnu_gettext=$withval +else + nls_cv_force_use_gnu_gettext=no +fi + + echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 +echo "configure:3675: checking for libintl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3680 "configure" +#include "confdefs.h" +#include <libintl.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3685: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 +echo "configure:3702: checking for gettext in libc" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3707 "configure" +#include "confdefs.h" +#include <libintl.h> +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:3714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libc=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 + + if test "$gt_cv_func_gettext_libc" != "yes"; then + echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 +echo "configure:3730: checking for bindtextdomain in -lintl" >&5 +ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3738 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bindtextdomain(); + +int main() { +bindtextdomain() +; return 0; } +EOF +if { (eval echo configure:3749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 +echo "configure:3765: checking for gettext in libintl" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3770 "configure" +#include "confdefs.h" + +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:3777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libintl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libintl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTEXT 1 +EOF + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3805: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3839: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3844 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3894: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3930: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + cat > conftest.$ac_ext <<EOF +#line 3962 "configure" +#include "confdefs.h" + +int main() { +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr +; return 0; } +EOF +if { (eval echo configure:3970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + fi + +else + echo "$ac_t""no" 1>&6 +fi + + + + if test "$CATOBJEXT" = "NONE"; then + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + INTLOBJS="\$(GETTOBJS)" + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4002: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4036: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4072: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/../intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6 + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:4162: checking for catalogs to be installed" >&5 + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + echo "$ac_t""$LINGUAS" 1>&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include <locale.h>" + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header <locale.h>. Take care yourself. */" + fi + + + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 +echo "configure:4190: checking for linux/version.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4195 "configure" +#include "confdefs.h" +#include <linux/version.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + msgformat=linux +else + echo "$ac_t""no" 1>&6 +msgformat=xopen +fi + + + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + + + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + + + l= + + + if test -f $srcdir/po/POTFILES.in; then + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + fi + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:4263: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:4288: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:4298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + + +for ac_hdr in sys/gmon_out.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4323: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4328 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4333: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +build_warnings="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" +# Check whether --enable-build-warnings or --disable-build-warnings was given. +if test "${enable_build_warnings+set}" = set; then + enableval="$enable_build_warnings" + case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting warning flags = $build_warnings" 6>&1 +fi +fi +WARN_CFLAGS="" +if test "x${build_warnings}" != x -a "x$GCC" = xyes ; then + WARN_CFLAGS="${build_warnings}" +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in gconfig.h:gconfig.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@LN_S@%$LN_S%g +s%@OBJEXT@%$OBJEXT%g +s%@EXEEXT@%$EXEEXT%g +s%@RANLIB@%$RANLIB%g +s%@STRIP@%$STRIP%g +s%@LIBTOOL@%$LIBTOOL%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g +s%@USE_NLS@%$USE_NLS%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@GMOFILES@%$GMOFILES%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@INTLDEPS@%$INTLDEPS%g +s%@INTLLIBS@%$INTLLIBS%g +s%@INTLOBJS@%$INTLOBJS%g +s%@POFILES@%$POFILES%g +s%@POSUB@%$POSUB%g +s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g +s%@GT_NO@%$GT_NO%g +s%@GT_YES@%$GT_YES%g +s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g +s%@l@%$l%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@WARN_CFLAGS@%$WARN_CFLAGS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="gconfig.h:gconfig.in" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + + +EOF +cat >> $CONFIG_STATUS <<\EOF +test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h +sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/gprof/configure.in b/gprof/configure.in new file mode 100644 index 000000000000..01464f3ecc52 --- /dev/null +++ b/gprof/configure.in @@ -0,0 +1,56 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.13) +AC_INIT(gprof.c) + +AC_CANONICAL_SYSTEM +AC_ISC_POSIX + +changequote(,)dnl +BFD_VERSION=`sed -n -e 's/^.._INIT_AUTOMAKE.*,[ ]*\([^ ]*\)[ ]*).*/\1/p' < ${srcdir}/../bfd/configure.in` +changequote([,])dnl +AM_INIT_AUTOMAKE(gprof, ${BFD_VERSION}) + +AM_PROG_LIBTOOL + +dnl For simplicity, we use the BFD configuration file for most +dnl things. However, we also need our own configuration file for +dnl the automake PACKAGE and VERSION macros. We don't name it +dnl config.h, to avoid any possible confusion with the bfd config.h. +AM_CONFIG_HEADER(gconfig.h:gconfig.in) + +AC_PROG_CC +AC_PROG_INSTALL + +AC_CHECK_FUNCS(setmode) + +ALL_LINGUAS="fr tr sv es id da pt_BR de" +CY_GNU_GETTEXT + +AM_MAINTAINER_MODE +AC_EXEEXT + +AC_CHECK_HEADERS(sys/gmon_out.h) + +build_warnings="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" +AC_ARG_ENABLE(build-warnings, +[ --enable-build-warnings Enable build-time compiler warnings if gcc is used], +[case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting warning flags = $build_warnings" 6>&1 +fi])dnl +WARN_CFLAGS="" +if test "x${build_warnings}" != x -a "x$GCC" = xyes ; then + WARN_CFLAGS="${build_warnings}" +fi +AC_SUBST(WARN_CFLAGS) + +AC_OUTPUT(Makefile po/Makefile.in:po/Make-in, +[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile]) diff --git a/gprof/corefile.c b/gprof/corefile.c new file mode 100644 index 000000000000..7081ca5335cc --- /dev/null +++ b/gprof/corefile.c @@ -0,0 +1,773 @@ +/* corefile.c + + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "corefile.h" + +bfd *core_bfd; +int core_num_syms; +asymbol **core_syms; +asection *core_text_sect; +PTR core_text_space; + +int min_insn_size; +int offset_to_code; + +/* For mapping symbols to specific .o files during file ordering. */ +struct function_map *symbol_map; +unsigned int symbol_map_count; + +static void read_function_mappings PARAMS ((const char *)); +static int core_sym_class PARAMS ((asymbol *)); +static bfd_boolean get_src_info + PARAMS ((bfd_vma, const char **, const char **, int *)); + +extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); +extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); +extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); +extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); +extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); +extern void mips_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +static void +read_function_mappings (filename) + const char *filename; +{ + FILE *file = fopen (filename, "r"); + char dummy[1024]; + int count = 0; + + if (!file) + { + fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename); + done (1); + } + + /* First parse the mapping file so we know how big we need to + make our tables. We also do some sanity checks at this + time. */ + while (!feof (file)) + { + int matches; + + matches = fscanf (file, "%[^\n:]", dummy); + if (!matches) + { + fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), + whoami, filename); + done (1); + } + + /* Just skip messages about files with no symbols. */ + if (!strncmp (dummy, "No symbols in ", 14)) + { + fscanf (file, "\n"); + continue; + } + + /* Don't care what else is on this line at this point. */ + fscanf (file, "%[^\n]\n", dummy); + count++; + } + + /* Now we know how big we need to make our table. */ + symbol_map = ((struct function_map *) + xmalloc (count * sizeof (struct function_map))); + + /* Rewind the input file so we can read it again. */ + rewind (file); + + /* Read each entry and put it into the table. */ + count = 0; + while (!feof (file)) + { + int matches; + char *tmp; + + matches = fscanf (file, "%[^\n:]", dummy); + if (!matches) + { + fprintf (stderr, _("%s: unable to parse mapping file %s.\n"), + whoami, filename); + done (1); + } + + /* Just skip messages about files with no symbols. */ + if (!strncmp (dummy, "No symbols in ", 14)) + { + fscanf (file, "\n"); + continue; + } + + /* dummy has the filename, go ahead and copy it. */ + symbol_map[count].file_name = xmalloc (strlen (dummy) + 1); + strcpy (symbol_map[count].file_name, dummy); + + /* Now we need the function name. */ + fscanf (file, "%[^\n]\n", dummy); + tmp = strrchr (dummy, ' ') + 1; + symbol_map[count].function_name = xmalloc (strlen (tmp) + 1); + strcpy (symbol_map[count].function_name, tmp); + count++; + } + + /* Record the size of the map table for future reference. */ + symbol_map_count = count; +} + + +void +core_init (aout_name) + const char *aout_name; +{ + core_bfd = bfd_openr (aout_name, 0); + + if (!core_bfd) + { + perror (aout_name); + done (1); + } + + if (!bfd_check_format (core_bfd, bfd_object)) + { + fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, aout_name); + done (1); + } + + /* Get core's text section. */ + core_text_sect = bfd_get_section_by_name (core_bfd, ".text"); + if (!core_text_sect) + { + core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$"); + if (!core_text_sect) + { + fprintf (stderr, _("%s: can't find .text section in %s\n"), + whoami, aout_name); + done (1); + } + } + + /* Read core's symbol table. */ + + /* This will probably give us more than we need, but that's ok. */ + core_num_syms = bfd_get_symtab_upper_bound (core_bfd); + if (core_num_syms < 0) + { + fprintf (stderr, "%s: %s: %s\n", whoami, aout_name, + bfd_errmsg (bfd_get_error ())); + done (1); + } + + core_syms = (asymbol **) xmalloc (core_num_syms); + core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms); + + if (core_num_syms < 0) + { + fprintf (stderr, "%s: %s: %s\n", whoami, aout_name, + bfd_errmsg (bfd_get_error ())); + done (1); + } + + min_insn_size = 1; + offset_to_code = 0; + + switch (bfd_get_arch (core_bfd)) + { + case bfd_arch_vax: + case bfd_arch_tahoe: + offset_to_code = 2; + break; + + case bfd_arch_alpha: + min_insn_size = 4; + break; + + default: + break; + } + + if (function_mapping_file) + read_function_mappings (function_mapping_file); +} + +/* Read in the text space of an a.out file. */ + +void +core_get_text_space (cbfd) + bfd *cbfd; +{ + core_text_space = (PTR) malloc ((unsigned int) core_text_sect->_raw_size); + + if (!core_text_space) + { + fprintf (stderr, _("%s: ran out room for %lu bytes of text space\n"), + whoami, (unsigned long) core_text_sect->_raw_size); + done (1); + } + + if (!bfd_get_section_contents (cbfd, core_text_sect, core_text_space, + (bfd_vma) 0, core_text_sect->_raw_size)) + { + bfd_perror ("bfd_get_section_contents"); + free (core_text_space); + core_text_space = 0; + } + + if (!core_text_space) + fprintf (stderr, _("%s: can't do -c\n"), whoami); +} + + +void +find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + switch (bfd_get_arch (core_bfd)) + { + case bfd_arch_i386: + i386_find_call (parent, p_lowpc, p_highpc); + break; + + case bfd_arch_alpha: + alpha_find_call (parent, p_lowpc, p_highpc); + break; + + case bfd_arch_vax: + vax_find_call (parent, p_lowpc, p_highpc); + break; + + case bfd_arch_sparc: + sparc_find_call (parent, p_lowpc, p_highpc); + break; + + case bfd_arch_tahoe: + tahoe_find_call (parent, p_lowpc, p_highpc); + break; + + case bfd_arch_mips: + mips_find_call (parent, p_lowpc, p_highpc); + break; + + default: + fprintf (stderr, _("%s: -c not supported on architecture %s\n"), + whoami, bfd_printable_name(core_bfd)); + + /* Don't give the error more than once. */ + ignore_direct_calls = FALSE; + } +} + +/* Return class of symbol SYM. The returned class can be any of: + 0 -> symbol is not interesting to us + 'T' -> symbol is a global name + 't' -> symbol is a local (static) name. */ + +static int +core_sym_class (sym) + asymbol *sym; +{ + symbol_info syminfo; + const char *name; + char sym_prefix; + int i; + + if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0) + return 0; + + /* Must be a text symbol, and static text symbols + don't qualify if ignore_static_funcs set. */ + if (ignore_static_funcs && (sym->flags & BSF_LOCAL)) + { + DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n", + sym->name)); + return 0; + } + + bfd_get_symbol_info (core_bfd, sym, &syminfo); + i = syminfo.type; + + if (i == 'T') + return i; /* It's a global symbol. */ + + if (i == 'W') + /* Treat weak symbols as text symbols. FIXME: a weak symbol may + also be a data symbol. */ + return 'T'; + + if (i != 't') + { + /* Not a static text symbol. */ + DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n", + sym->name, i)); + return 0; + } + + /* Do some more filtering on static function-names. */ + if (ignore_static_funcs) + return 0; + + /* Can't zero-length name or funny characters in name, where + `funny' includes: `.' (.o file names) and `$' (Pascal labels). */ + if (!sym->name || sym->name[0] == '\0') + return 0; + + for (name = sym->name; *name; ++name) + { + if (*name == '.' || *name == '$') + return 0; + } + + /* On systems where the C compiler adds an underscore to all + names, static names without underscores seem usually to be + labels in hand written assembler in the library. We don't want + these names. This is certainly necessary on a Sparc running + SunOS 4.1 (try profiling a program that does a lot of + division). I don't know whether it has harmful side effects on + other systems. Perhaps it should be made configurable. */ + sym_prefix = bfd_get_symbol_leading_char (core_bfd); + + if ((sym_prefix && sym_prefix != sym->name[0]) + /* GCC may add special symbols to help gdb figure out the file + language. We want to ignore these, since sometimes they mask + the real function. (dj@ctron) */ + || !strncmp (sym->name, "__gnu_compiled", 14) + || !strncmp (sym->name, "___gnu_compiled", 15)) + { + return 0; + } + + /* If the object file supports marking of function symbols, then + we can zap anything that doesn't have BSF_FUNCTION set. */ + if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0) + return 0; + + return 't'; /* It's a static text symbol. */ +} + +/* Get whatever source info we can get regarding address ADDR. */ + +static bfd_boolean +get_src_info (addr, filename, name, line_num) + bfd_vma addr; + const char **filename; + const char **name; + int *line_num; +{ + const char *fname = 0, *func_name = 0; + int l = 0; + + if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms, + addr - core_text_sect->vma, + &fname, &func_name, (unsigned int *) &l) + && fname && func_name && l) + { + DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n", + (unsigned long) addr, fname, l, func_name)); + *filename = fname; + *name = func_name; + *line_num = l; + return TRUE; + } + else + { + DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n", + (long) addr, fname ? fname : "<unknown>", l, + func_name ? func_name : "<unknown>")); + return FALSE; + } +} + +/* Read in symbol table from core. + One symbol per function is entered. */ + +void +core_create_function_syms (cbfd) + bfd *cbfd ATTRIBUTE_UNUSED; +{ + bfd_vma min_vma = ~(bfd_vma) 0; + bfd_vma max_vma = 0; + int class; + long i, found, skip; + unsigned int j; + + /* Pass 1 - determine upper bound on number of function names. */ + symtab.len = 0; + + for (i = 0; i < core_num_syms; ++i) + { + if (!core_sym_class (core_syms[i])) + continue; + + /* This should be replaced with a binary search or hashed + search. Gross. + + Don't create a symtab entry for a function that has + a mapping to a file, unless it's the first function + in the file. */ + skip = 0; + for (j = 0; j < symbol_map_count; j++) + if (!strcmp (core_syms[i]->name, symbol_map[j].function_name)) + { + if (j > 0 && ! strcmp (symbol_map [j].file_name, + symbol_map [j - 1].file_name)) + skip = 1; + break; + } + + if (!skip) + ++symtab.len; + } + + if (symtab.len == 0) + { + fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name); + done (1); + } + + /* The "+ 2" is for the sentinels. */ + symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym)); + + /* Pass 2 - create symbols. */ + symtab.limit = symtab.base; + + for (i = 0; i < core_num_syms; ++i) + { + asection *sym_sec; + + class = core_sym_class (core_syms[i]); + + if (!class) + { + DBG (AOUTDEBUG, + printf ("[core_create_function_syms] rejecting: 0x%lx %s\n", + (unsigned long) core_syms[i]->value, + core_syms[i]->name)); + continue; + } + + /* This should be replaced with a binary search or hashed + search. Gross. */ + skip = 0; + found = 0; + + for (j = 0; j < symbol_map_count; j++) + if (!strcmp (core_syms[i]->name, symbol_map[j].function_name)) + { + if (j > 0 && ! strcmp (symbol_map [j].file_name, + symbol_map [j - 1].file_name)) + skip = 1; + else + found = j; + break; + } + + if (skip) + continue; + + sym_init (symtab.limit); + + /* Symbol offsets are always section-relative. */ + sym_sec = core_syms[i]->section; + symtab.limit->addr = core_syms[i]->value; + if (sym_sec) + symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec); + + if (symbol_map_count + && !strcmp (core_syms[i]->name, symbol_map[found].function_name)) + { + symtab.limit->name = symbol_map[found].file_name; + symtab.limit->mapped = 1; + } + else + { + symtab.limit->name = core_syms[i]->name; + symtab.limit->mapped = 0; + } + + /* Lookup filename and line number, if we can. */ + { + const char *filename, *func_name; + + if (get_src_info (symtab.limit->addr, &filename, &func_name, + &symtab.limit->line_num)) + { + symtab.limit->file = source_file_lookup_path (filename); + + /* FIXME: Checking __osf__ here does not work with a cross + gprof. */ +#ifdef __osf__ + /* Suppress symbols that are not function names. This is + useful to suppress code-labels and aliases. + + This is known to be useful under DEC's OSF/1. Under SunOS 4.x, + labels do not appear in the symbol table info, so this isn't + necessary. */ + + if (strcmp (symtab.limit->name, func_name) != 0) + { + /* The symbol's address maps to a different name, so + it can't be a function-entry point. This happens + for labels, for example. */ + DBG (AOUTDEBUG, + printf ("[core_create_function_syms: rej %s (maps to %s)\n", + symtab.limit->name, func_name)); + continue; + } +#endif + } + } + + symtab.limit->is_func = TRUE; + symtab.limit->is_bb_head = TRUE; + + if (class == 't') + symtab.limit->is_static = TRUE; + + /* Keep track of the minimum and maximum vma addresses used by all + symbols. When computing the max_vma, use the ending address of the + section containing the symbol, if available. */ + min_vma = MIN (symtab.limit->addr, min_vma); + if (sym_sec) + max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec) + + bfd_section_size (sym_sec->owner, sym_sec) - 1, + max_vma); + else + max_vma = MAX (symtab.limit->addr, max_vma); + + /* If we see "main" without an initial '_', we assume names + are *not* prefixed by '_'. */ + if (symtab.limit->name[0] == 'm' && discard_underscores + && strcmp (symtab.limit->name, "main") == 0) + discard_underscores = 0; + + DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n", + (long) (symtab.limit - symtab.base), + symtab.limit->name, + (unsigned long) symtab.limit->addr)); + ++symtab.limit; + } + + /* Create sentinels. */ + sym_init (symtab.limit); + symtab.limit->name = "<locore>"; + symtab.limit->addr = 0; + symtab.limit->end_addr = min_vma - 1; + ++symtab.limit; + + sym_init (symtab.limit); + symtab.limit->name = "<hicore>"; + symtab.limit->addr = max_vma + 1; + symtab.limit->end_addr = ~(bfd_vma) 0; + ++symtab.limit; + + symtab.len = symtab.limit - symtab.base; + symtab_finalize (&symtab); +} + +/* Read in symbol table from core. + One symbol per line of source code is entered. */ + +void +core_create_line_syms (cbfd) + bfd *cbfd; +{ + char *prev_name, *prev_filename; + unsigned int prev_name_len, prev_filename_len; + bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0; + bfd_vma offset; + Sym *prev, dummy, *sentinel, *sym; + const char *filename; + int prev_line_num; + Sym_Table ltab; + + /* Create symbols for functions as usual. This is necessary in + cases where parts of a program were not compiled with -g. For + those parts we still want to get info at the function level. */ + core_create_function_syms (cbfd); + + /* Pass 1 - counter number of symbols. */ + + /* To find all line information, walk through all possible + text-space addresses (one by one!) and get the debugging + info for each address. When the debugging info changes, + it is time to create a new symbol. + + Of course, this is rather slow and it would be better if + bfd would provide an iterator for enumerating all line infos. */ + prev_name_len = PATH_MAX; + prev_filename_len = PATH_MAX; + prev_name = xmalloc (prev_name_len); + prev_filename = xmalloc (prev_filename_len); + ltab.len = 0; + prev_line_num = 0; + + for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size) + { + unsigned int len; + + vma = core_text_sect->vma + offset; + + if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num) + || (prev_line_num == dummy.line_num + && prev_name != NULL + && strcmp (prev_name, dummy.name) == 0 + && strcmp (prev_filename, filename) == 0)) + continue; + + ++ltab.len; + prev_line_num = dummy.line_num; + + len = strlen (dummy.name); + if (len >= prev_name_len) + { + prev_name_len = len + 1024; + free (prev_name); + prev_name = xmalloc (prev_name_len); + } + + strcpy (prev_name, dummy.name); + len = strlen (filename); + + if (len >= prev_filename_len) + { + prev_filename_len = len + 1024; + free (prev_filename); + prev_filename = xmalloc (prev_filename_len); + } + + strcpy (prev_filename, filename); + + min_vma = MIN (vma, min_vma); + max_vma = MAX (vma, max_vma); + } + + free (prev_name); + free (prev_filename); + + /* Make room for function symbols, too. */ + ltab.len += symtab.len; + ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym)); + ltab.limit = ltab.base; + + /* Pass 2 - create symbols. */ + + /* We now set is_static as we go along, rather than by running + through the symbol table at the end. + + The old way called symtab_finalize before the is_static pass, + causing a problem since symtab_finalize uses is_static as part of + its address conflict resolution algorithm. Since global symbols + were prefered over static symbols, and all line symbols were + global at that point, static function names that conflicted with + their own line numbers (static, but labeled as global) were + rejected in favor of the line num. + + This was not the desired functionality. We always want to keep + our function symbols and discard any conflicting line symbols. + Perhaps symtab_finalize should be modified to make this + distinction as well, but the current fix works and the code is a + lot cleaner now. */ + prev = 0; + + for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size) + { + sym_init (ltab.limit); + + if (!get_src_info (core_text_sect->vma + offset, &filename, + <ab.limit->name, <ab.limit->line_num) + || (prev && prev->line_num == ltab.limit->line_num + && strcmp (prev->name, ltab.limit->name) == 0 + && strcmp (prev->file->name, filename) == 0)) + continue; + + /* Make name pointer a malloc'ed string. */ + ltab.limit->name = xstrdup (ltab.limit->name); + ltab.limit->file = source_file_lookup_path (filename); + + ltab.limit->addr = core_text_sect->vma + offset; + + /* Set is_static based on the enclosing function, using either: + 1) the previous symbol, if it's from the same function, or + 2) a symtab lookup. */ + if (prev && ltab.limit->file == prev->file && + strcmp (ltab.limit->name, prev->name) == 0) + { + ltab.limit->is_static = prev->is_static; + } + else + { + sym = sym_lookup(&symtab, ltab.limit->addr); + ltab.limit->is_static = sym->is_static; + } + + prev = ltab.limit; + + /* If we see "main" without an initial '_', we assume names + are *not* prefixed by '_'. */ + if (ltab.limit->name[0] == 'm' && discard_underscores + && strcmp (ltab.limit->name, "main") == 0) + discard_underscores = 0; + + DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n", + (unsigned long) (ltab.limit - ltab.base), + ltab.limit->name, + (unsigned long) ltab.limit->addr)); + ++ltab.limit; + } + + /* Update sentinels. */ + sentinel = sym_lookup (&symtab, (bfd_vma) 0); + + if (sentinel + && strcmp (sentinel->name, "<locore>") == 0 + && min_vma <= sentinel->end_addr) + sentinel->end_addr = min_vma - 1; + + sentinel = sym_lookup (&symtab, ~(bfd_vma) 0); + + if (sentinel + && strcmp (sentinel->name, "<hicore>") == 0 + && max_vma >= sentinel->addr) + sentinel->addr = max_vma + 1; + + /* Copy in function symbols. */ + memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym)); + ltab.limit += symtab.len; + + if ((unsigned int) (ltab.limit - ltab.base) != ltab.len) + { + fprintf (stderr, + _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"), + whoami, ltab.len, (long) (ltab.limit - ltab.base)); + done (1); + } + + /* Finalize ltab and make it symbol table. */ + symtab_finalize (<ab); + free (symtab.base); + symtab = ltab; +} diff --git a/gprof/corefile.h b/gprof/corefile.h new file mode 100644 index 000000000000..7ecbbff87fd9 --- /dev/null +++ b/gprof/corefile.h @@ -0,0 +1,47 @@ +/* corefile.h + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef corefile_h +#define corefile_h + +struct function_map +{ + char *function_name; + char *file_name; +}; + +extern struct function_map *symbol_map; +extern unsigned int symbol_map_count; + +extern bfd *core_bfd; /* BFD for core-file. */ +extern int core_num_syms; /* # of entries in symbol-table. */ +extern asymbol **core_syms; /* Symbol table in a.out. */ +extern asection *core_text_sect;/* Core text section. */ +extern PTR core_text_space; /* Text space of a.out in core. */ +extern int min_insn_size; /* Size of smallest instruction, in bytes. */ +extern int offset_to_code; /* Offset (in bytes) of code from entry + address of routine. */ + +extern void core_init PARAMS ((const char *)); +extern void core_get_text_space PARAMS ((bfd *)); +extern void core_create_function_syms PARAMS ((bfd *)); +extern void core_create_line_syms PARAMS ((bfd *)); + +#endif /* corefile_h */ diff --git a/gprof/dep-in.sed b/gprof/dep-in.sed new file mode 100644 index 000000000000..aeb22a1acc78 --- /dev/null +++ b/gprof/dep-in.sed @@ -0,0 +1,20 @@ +:loop +/\\$/N +/\\$/b loop + +s!@INCDIR@!$(INCDIR)!g +s!@TOPDIR@/include!$(INCDIR)!g +s!@BFDDIR@!$(BFDDIR)!g +s!@TOPDIR@/bfd!$(BFDDIR)!g +s!@SRCDIR@/!!g +s!@OBJDIR@/!!g +s! \.\./intl/libintl\.h!!g + +s/\\\n */ /g + +s/ *$// +s/ */ /g +/:$/d + +s/\(.\{50\}[^ ]*\) /\1 \\\ + /g diff --git a/gprof/flat_bl.c b/gprof/flat_bl.c new file mode 100644 index 000000000000..e4d32c2bdd4b --- /dev/null +++ b/gprof/flat_bl.c @@ -0,0 +1,39 @@ +/* ==> Do not modify this file!! It is created automatically + from flat_bl.m using the gen-c-prog.awk script. <== */ + +#include <stdio.h> +#include "ansidecl.h" + +void flat_blurb PARAMS ((FILE *)); +void +flat_blurb (file) + FILE *file; +{ + fputs ("\n", file); + fputs (" % the percentage of the total running time of the\n", file); + fputs ("time program used by this function.\n", file); + fputs ("\n", file); + fputs ("cumulative a running sum of the number of seconds accounted\n", file); + fputs (" seconds for by this function and those listed above it.\n", file); + fputs ("\n", file); + fputs (" self the number of seconds accounted for by this\n", file); + fputs ("seconds function alone. This is the major sort for this\n", file); + fputs (" listing.\n", file); + fputs ("\n", file); + fputs ("calls the number of times this function was invoked, if\n", file); + fputs (" this function is profiled, else blank.\n", file); + fputs (" \n", file); + fputs (" self the average number of milliseconds spent in this\n", file); + fputs ("ms/call function per call, if this function is profiled,\n", file); + fputs (" else blank.\n", file); + fputs ("\n", file); + fputs (" total the average number of milliseconds spent in this\n", file); + fputs ("ms/call function and its descendents per call, if this \n", file); + fputs (" function is profiled, else blank.\n", file); + fputs ("\n", file); + fputs ("name the name of the function. This is the minor sort\n", file); + fputs (" for this listing. The index shows the location of\n", file); + fputs (" the function in the gprof listing. If the index is\n", file); + fputs (" in parenthesis it shows where it would appear in\n", file); + fputs (" the gprof listing if it were to be printed.\n", file); +} diff --git a/gprof/flat_bl.m b/gprof/flat_bl.m new file mode 100644 index 000000000000..db2871a13848 --- /dev/null +++ b/gprof/flat_bl.m @@ -0,0 +1,27 @@ + + % the percentage of the total running time of the +time program used by this function. + +cumulative a running sum of the number of seconds accounted + seconds for by this function and those listed above it. + + self the number of seconds accounted for by this +seconds function alone. This is the major sort for this + listing. + +calls the number of times this function was invoked, if + this function is profiled, else blank. + + self the average number of milliseconds spent in this +ms/call function per call, if this function is profiled, + else blank. + + total the average number of milliseconds spent in this +ms/call function and its descendents per call, if this + function is profiled, else blank. + +name the name of the function. This is the minor sort + for this listing. The index shows the location of + the function in the gprof listing. If the index is + in parenthesis it shows where it would appear in + the gprof listing if it were to be printed. diff --git a/gprof/fsf_callg_bl.c b/gprof/fsf_callg_bl.c new file mode 100644 index 000000000000..ab7baabc468d --- /dev/null +++ b/gprof/fsf_callg_bl.c @@ -0,0 +1,95 @@ +/* ==> Do not modify this file!! It is created automatically + from fsf_callg_bl.m using the gen-c-prog.awk script. <== */ + +#include <stdio.h> +#include "ansidecl.h" + +void fsf_callg_blurb PARAMS ((FILE *)); +void +fsf_callg_blurb (file) + FILE *file; +{ + fputs ("\n", file); + fputs (" This table describes the call tree of the program, and was sorted by\n", file); + fputs (" the total amount of time spent in each function and its children.\n", file); + fputs ("\n", file); + fputs (" Each entry in this table consists of several lines. The line with the\n", file); + fputs (" index number at the left hand margin lists the current function.\n", file); + fputs (" The lines above it list the functions that called this function,\n", file); + fputs (" and the lines below it list the functions this one called.\n", file); + fputs (" This line lists:\n", file); + fputs (" index A unique number given to each element of the table.\n", file); + fputs (" Index numbers are sorted numerically.\n", file); + fputs (" The index number is printed next to every function name so\n", file); + fputs (" it is easier to look up where the function in the table.\n", file); + fputs ("\n", file); + fputs (" % time This is the percentage of the `total' time that was spent\n", file); + fputs (" in this function and its children. Note that due to\n", file); + fputs (" different viewpoints, functions excluded by options, etc,\n", file); + fputs (" these numbers will NOT add up to 100%.\n", file); + fputs ("\n", file); + fputs (" self This is the total amount of time spent in this function.\n", file); + fputs ("\n", file); + fputs (" children This is the total amount of time propagated into this\n", file); + fputs (" function by its children.\n", file); + fputs ("\n", file); + fputs (" called This is the number of times the function was called.\n", file); + fputs (" If the function called itself recursively, the number\n", file); + fputs (" only includes non-recursive calls, and is followed by\n", file); + fputs (" a `+' and the number of recursive calls.\n", file); + fputs ("\n", file); + fputs (" name The name of the current function. The index number is\n", file); + fputs (" printed after it. If the function is a member of a\n", file); + fputs (" cycle, the cycle number is printed between the\n", file); + fputs (" function's name and the index number.\n", file); + fputs ("\n", file); + fputs ("\n", file); + fputs (" For the function's parents, the fields have the following meanings:\n", file); + fputs ("\n", file); + fputs (" self This is the amount of time that was propagated directly\n", file); + fputs (" from the function into this parent.\n", file); + fputs ("\n", file); + fputs (" children This is the amount of time that was propagated from\n", file); + fputs (" the function's children into this parent.\n", file); + fputs ("\n", file); + fputs (" called This is the number of times this parent called the\n", file); + fputs (" function `/' the total number of times the function\n", file); + fputs (" was called. Recursive calls to the function are not\n", file); + fputs (" included in the number after the `/'.\n", file); + fputs ("\n", file); + fputs (" name This is the name of the parent. The parent's index\n", file); + fputs (" number is printed after it. If the parent is a\n", file); + fputs (" member of a cycle, the cycle number is printed between\n", file); + fputs (" the name and the index number.\n", file); + fputs ("\n", file); + fputs (" If the parents of the function cannot be determined, the word\n", file); + fputs (" `<spontaneous>' is printed in the `name' field, and all the other\n", file); + fputs (" fields are blank.\n", file); + fputs ("\n", file); + fputs (" For the function's children, the fields have the following meanings:\n", file); + fputs ("\n", file); + fputs (" self This is the amount of time that was propagated directly\n", file); + fputs (" from the child into the function.\n", file); + fputs ("\n", file); + fputs (" children This is the amount of time that was propagated from the\n", file); + fputs (" child's children to the function.\n", file); + fputs ("\n", file); + fputs (" called This is the number of times the function called\n", file); + fputs (" this child `/' the total number of times the child\n", file); + fputs (" was called. Recursive calls by the child are not\n", file); + fputs (" listed in the number after the `/'.\n", file); + fputs ("\n", file); + fputs (" name This is the name of the child. The child's index\n", file); + fputs (" number is printed after it. If the child is a\n", file); + fputs (" member of a cycle, the cycle number is printed\n", file); + fputs (" between the name and the index number.\n", file); + fputs ("\n", file); + fputs (" If there are any cycles (circles) in the call graph, there is an\n", file); + fputs (" entry for the cycle-as-a-whole. This entry shows who called the\n", file); + fputs (" cycle (as parents) and the members of the cycle (as children.)\n", file); + fputs (" The `+' recursive calls entry shows the number of function calls that\n", file); + fputs (" were internal to the cycle, and the calls entry for each member shows,\n", file); + fputs (" for that member, how many times it was called from other members of\n", file); + fputs (" the cycle.\n", file); + fputs ("\n", file); +} diff --git a/gprof/fsf_callg_bl.m b/gprof/fsf_callg_bl.m new file mode 100644 index 000000000000..7e16821ede2f --- /dev/null +++ b/gprof/fsf_callg_bl.m @@ -0,0 +1,83 @@ + + This table describes the call tree of the program, and was sorted by + the total amount of time spent in each function and its children. + + Each entry in this table consists of several lines. The line with the + index number at the left hand margin lists the current function. + The lines above it list the functions that called this function, + and the lines below it list the functions this one called. + This line lists: + index A unique number given to each element of the table. + Index numbers are sorted numerically. + The index number is printed next to every function name so + it is easier to look up where the function in the table. + + % time This is the percentage of the `total' time that was spent + in this function and its children. Note that due to + different viewpoints, functions excluded by options, etc, + these numbers will NOT add up to 100%. + + self This is the total amount of time spent in this function. + + children This is the total amount of time propagated into this + function by its children. + + called This is the number of times the function was called. + If the function called itself recursively, the number + only includes non-recursive calls, and is followed by + a `+' and the number of recursive calls. + + name The name of the current function. The index number is + printed after it. If the function is a member of a + cycle, the cycle number is printed between the + function's name and the index number. + + + For the function's parents, the fields have the following meanings: + + self This is the amount of time that was propagated directly + from the function into this parent. + + children This is the amount of time that was propagated from + the function's children into this parent. + + called This is the number of times this parent called the + function `/' the total number of times the function + was called. Recursive calls to the function are not + included in the number after the `/'. + + name This is the name of the parent. The parent's index + number is printed after it. If the parent is a + member of a cycle, the cycle number is printed between + the name and the index number. + + If the parents of the function cannot be determined, the word + `<spontaneous>' is printed in the `name' field, and all the other + fields are blank. + + For the function's children, the fields have the following meanings: + + self This is the amount of time that was propagated directly + from the child into the function. + + children This is the amount of time that was propagated from the + child's children to the function. + + called This is the number of times the function called + this child `/' the total number of times the child + was called. Recursive calls by the child are not + listed in the number after the `/'. + + name This is the name of the child. The child's index + number is printed after it. If the child is a + member of a cycle, the cycle number is printed + between the name and the index number. + + If there are any cycles (circles) in the call graph, there is an + entry for the cycle-as-a-whole. This entry shows who called the + cycle (as parents) and the members of the cycle (as children.) + The `+' recursive calls entry shows the number of function calls that + were internal to the cycle, and the calls entry for each member shows, + for that member, how many times it was called from other members of + the cycle. + diff --git a/gprof/gconfig.in b/gprof/gconfig.in new file mode 100644 index 000000000000..d1c2ebd38cef --- /dev/null +++ b/gprof/gconfig.in @@ -0,0 +1,132 @@ +/* gconfig.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `long' if <sys/types.h> doesn't define. */ +#undef off_t + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +#undef size_t + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + +/* Define if you have the setmode function. */ +#undef HAVE_SETMODE + +/* Define if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strchr function. */ +#undef HAVE_STRCHR + +/* Define if you have the <argz.h> header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the <nl_types.h> header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <sys/gmon_out.h> header file. */ +#undef HAVE_SYS_GMON_OUT_H + +/* Define if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the <values.h> header file. */ +#undef HAVE_VALUES_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + +/* Define if you have the stpcpy function */ +#undef HAVE_STPCPY + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if NLS is requested */ +#undef ENABLE_NLS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + diff --git a/gprof/gen-c-prog.awk b/gprof/gen-c-prog.awk new file mode 100644 index 000000000000..b235a64a4518 --- /dev/null +++ b/gprof/gen-c-prog.awk @@ -0,0 +1,28 @@ +NR == 1 { + FS="\""; + print "/* ==> Do not modify this file!! It is created automatically" + printf " from %s using the gen-c-prog.awk script. <== */\n\n", FILE + print "#include <stdio.h>" + print "#include \"ansidecl.h\"" +} + + { + if (curfun != FUNCTION) + { + if (curfun) + print "}" + curfun = FUNCTION + print "" + print "void ", FUNCTION, "PARAMS ((FILE *));" + print "void"; + printf "%s (file)\n", FUNCTION + print " FILE *file;"; + print "{"; + } + printf " fputs (\""; + for (i = 1; i < NF; i++) + printf "%s\\\"", $i; + printf "%s\\n\", file);\n", $NF; +} + +END { print "}" } diff --git a/gprof/gmon.h b/gprof/gmon.h new file mode 100644 index 000000000000..7f1c333525e5 --- /dev/null +++ b/gprof/gmon.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1983, 1991, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef gmon_h +#define gmon_h + +/* Size of the 4.4BSD gmon header */ +#define GMON_HDRSIZE_BSD44_32 (4 + 4 + 4 + 4 + 4 + (3 * 4)) +#define GMON_HDRSIZE_BSD44_64 (8 + 8 + 4 + 4 + 4 + (3 * 4)) + +#if 0 /* For documentation purposes only. */ + struct raw_phdr + { + char low_pc[sizeof(void *)]; /* base pc address of sample buffer */ + char high_pc[sizeof(void *)];/* max pc address of sampled buffer */ + char ncnt[4]; /* size of sample buffer (plus this + header) */ + + char version[4]; /* version number */ + char profrate[4]; /* profiling clock rate */ + char spare[3*4]; /* reserved */ + }; +#endif + +#define GMONVERSION 0x00051879 + +/* Size of the old BSD gmon header */ +#define GMON_HDRSIZE_OLDBSD_32 (4 + 4 + 4) + +/* FIXME: Checking host compiler defines here means that we can't + use a cross gprof alpha OSF. */ +#if defined(__alpha__) && defined (__osf__) +#define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4 + 4) +#else +#define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4) +#endif + +#if 0 /* For documentation purposes only. */ + struct old_raw_phdr + { + char low_pc[sizeof(void *)]; /* base pc address of sample buffer */ + char high_pc[sizeof(void *)];/* max pc address of sampled buffer */ + char ncnt[4]; /* size of sample buffer (plus this + header) */ +#if defined (__alpha__) && defined (__osf__) + /* + * DEC's OSF v3.0 uses 4 bytes of padding to bring the header to + * a size that is a multiple of 8. + */ + char pad[4]; +#endif + }; +#endif + +/* + * Histogram counters are unsigned shorts: + */ +#define HISTCOUNTER unsigned short + +/* + * Fraction of text space to allocate for histogram counters here, 1/2: + */ +#define HISTFRACTION 2 + +/* + * Fraction of text space to allocate for from hash buckets. The + * value of HASHFRACTION is based on the minimum number of bytes of + * separation between two subroutine call points in the object code. + * Given MIN_SUBR_SEPARATION bytes of separation the value of + * HASHFRACTION is calculated as: + * + * HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1); + * + * For the VAX, the shortest two call sequence is: + * + * calls $0,(r0) + * calls $0,(r0) + * + * which is separated by only three bytes, thus HASHFRACTION is + * calculated as: + * + * HASHFRACTION = 3 / (2 * 2 - 1) = 1 + * + * Note that the division above rounds down, thus if MIN_SUBR_FRACTION + * is less than three, this algorithm will not work! + */ +#define HASHFRACTION 1 + +/* + * Percent of text space to allocate for tostructs with a minimum: + */ +#define ARCDENSITY 2 +#define MINARCS 50 + +struct tostruct + { + char *selfpc; + int count; + unsigned short link; + }; + +/* + * A raw arc, with pointers to the calling site and the called site + * and a count. Everything is defined in terms of characters so + * as to get a packed representation (otherwise, different compilers + * might introduce different padding): + */ +#if 0 /* For documentation purposes only. */ + struct raw_arc + { + char from_pc[sizeof(void *)]; + char self_pc[sizeof(void *)]; + char count[sizeof(long)]; + }; +#endif + +/* + * General rounding functions: + */ +#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) + +#endif /* gmon_h */ diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c new file mode 100644 index 000000000000..6188631f101d --- /dev/null +++ b/gprof/gmon_io.c @@ -0,0 +1,779 @@ +/* gmon_io.c - Input and output from/to gmon.out files. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "basic_blocks.h" +#include "corefile.h" +#include "call_graph.h" +#include "gmon_io.h" +#include "gmon_out.h" +#include "gmon.h" /* Fetch header for old format. */ +#include "hertz.h" +#include "hist.h" +#include "libiberty.h" + +enum gmon_ptr_size { + ptr_32bit, + ptr_64bit +}; + +enum gmon_ptr_signedness { + ptr_signed, + ptr_unsigned +}; + +static enum gmon_ptr_size gmon_get_ptr_size PARAMS ((void)); +static enum gmon_ptr_signedness gmon_get_ptr_signedness PARAMS ((void)); + +#ifdef BFD_HOST_U_64_BIT +static int gmon_io_read_64 PARAMS ((FILE *, BFD_HOST_U_64_BIT *)); +static int gmon_io_write_64 PARAMS ((FILE *, BFD_HOST_U_64_BIT)); +#endif +static int gmon_read_raw_arc + PARAMS ((FILE *, bfd_vma *, bfd_vma *, unsigned long *)); +static int gmon_write_raw_arc + PARAMS ((FILE *, bfd_vma, bfd_vma, unsigned long)); + +int gmon_input = 0; +int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */ + +static enum gmon_ptr_size +gmon_get_ptr_size () +{ + int size; + + /* Pick best size for pointers. Start with the ELF size, and if not + elf go with the architecture's address size. */ + size = bfd_get_arch_size (core_bfd); + if (size == -1) + size = bfd_arch_bits_per_address (core_bfd); + + switch (size) + { + case 32: + return ptr_32bit; + + case 64: + return ptr_64bit; + + default: + fprintf (stderr, _("%s: address size has unexpected value of %u\n"), + whoami, size); + done (1); + } +} + +static enum gmon_ptr_signedness +gmon_get_ptr_signedness () +{ + int sext; + + /* Figure out whether to sign extend. If BFD doesn't know, assume no. */ + sext = bfd_get_sign_extend_vma (core_bfd); + if (sext == -1) + return ptr_unsigned; + return (sext ? ptr_signed : ptr_unsigned); +} + +int +gmon_io_read_32 (ifp, valp) + FILE *ifp; + unsigned int *valp; +{ + char buf[4]; + + if (fread (buf, 1, 4, ifp) != 4) + return 1; + *valp = bfd_get_32 (core_bfd, buf); + return 0; +} + +#ifdef BFD_HOST_U_64_BIT +static int +gmon_io_read_64 (ifp, valp) + FILE *ifp; + BFD_HOST_U_64_BIT *valp; +{ + char buf[8]; + + if (fread (buf, 1, 8, ifp) != 8) + return 1; + *valp = bfd_get_64 (core_bfd, buf); + return 0; +} +#endif + +int +gmon_io_read_vma (ifp, valp) + FILE *ifp; + bfd_vma *valp; +{ + unsigned int val32; +#ifdef BFD_HOST_U_64_BIT + BFD_HOST_U_64_BIT val64; +#endif + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + if (gmon_io_read_32 (ifp, &val32)) + return 1; + if (gmon_get_ptr_signedness () == ptr_signed) + *valp = (int) val32; + else + *valp = val32; + break; + +#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_read_64 (ifp, &val64)) + return 1; +#ifdef BFD_HOST_64_BIT + if (gmon_get_ptr_signedness () == ptr_signed) + *valp = (BFD_HOST_64_BIT) val64; + else +#endif + *valp = val64; + break; +#endif + } + return 0; +} + +int +gmon_io_read (ifp, buf, n) + FILE *ifp; + char *buf; + size_t n; +{ + if (fread (buf, 1, n, ifp) != n) + return 1; + return 0; +} + +int +gmon_io_write_32 (ofp, val) + FILE *ofp; + unsigned int val; +{ + char buf[4]; + + bfd_put_32 (core_bfd, (bfd_vma) val, buf); + if (fwrite (buf, 1, 4, ofp) != 4) + return 1; + return 0; +} + +#ifdef BFD_HOST_U_64_BIT +static int +gmon_io_write_64 (ofp, val) + FILE *ofp; + BFD_HOST_U_64_BIT val; +{ + char buf[8]; + + bfd_put_64 (core_bfd, (bfd_vma) val, buf); + if (fwrite (buf, 1, 8, ofp) != 8) + return 1; + return 0; +} +#endif + +int +gmon_io_write_vma (ofp, val) + FILE *ofp; + bfd_vma val; +{ + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + if (gmon_io_write_32 (ofp, (unsigned int) val)) + return 1; + break; + +#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val)) + return 1; + break; +#endif + } + return 0; +} + +int +gmon_io_write_8 (ofp, val) + FILE *ofp; + unsigned int val; +{ + char buf[1]; + + bfd_put_8 (core_bfd, val, buf); + if (fwrite (buf, 1, 1, ofp) != 1) + return 1; + return 0; +} + +int +gmon_io_write (ofp, buf, n) + FILE *ofp; + char *buf; + size_t n; +{ + if (fwrite (buf, 1, n, ofp) != n) + return 1; + return 0; +} + +static int +gmon_read_raw_arc (ifp, fpc, spc, cnt) + FILE *ifp; + bfd_vma *fpc; + bfd_vma *spc; + unsigned long *cnt; +{ +#ifdef BFD_HOST_U_64_BIT + BFD_HOST_U_64_BIT cnt64; +#endif + unsigned int cnt32; + + if (gmon_io_read_vma (ifp, fpc) + || gmon_io_read_vma (ifp, spc)) + return 1; + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + if (gmon_io_read_32 (ifp, &cnt32)) + return 1; + *cnt = cnt32; + break; + +#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_read_64 (ifp, &cnt64)) + return 1; + *cnt = cnt64; + break; +#endif + } + return 0; +} + +static int +gmon_write_raw_arc (ofp, fpc, spc, cnt) + FILE *ofp; + bfd_vma fpc; + bfd_vma spc; + unsigned long cnt; +{ + + if (gmon_io_write_vma (ofp, fpc) + || gmon_io_write_vma (ofp, spc)) + return 1; + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + if (gmon_io_write_32 (ofp, (unsigned int) cnt)) + return 1; + break; + +#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt)) + return 1; + break; +#endif + } + return 0; +} + +void +gmon_out_read (filename) + const char *filename; +{ + FILE *ifp; + struct gmon_hdr ghdr; + unsigned char tag; + int nhist = 0, narcs = 0, nbbs = 0; + + /* Open gmon.out file. */ + if (strcmp (filename, "-") == 0) + { + ifp = stdin; +#ifdef SET_BINARY + SET_BINARY (fileno (stdin)); +#endif + } + else + { + ifp = fopen (filename, FOPEN_RB); + + if (!ifp) + { + perror (filename); + done (1); + } + } + + if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1) + { + fprintf (stderr, _("%s: file too short to be a gmon file\n"), + filename); + done (1); + } + + if ((file_format == FF_MAGIC) + || (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))) + { + if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)) + { + fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"), + whoami, filename); + done (1); + } + + /* Right magic, so it's probably really a new gmon.out file. */ + gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version); + + if (gmon_file_version != GMON_VERSION && gmon_file_version != 0) + { + fprintf (stderr, + _("%s: file `%s' has unsupported version %d\n"), + whoami, filename, gmon_file_version); + done (1); + } + + /* Read in all the records. */ + while (fread (&tag, sizeof (tag), 1, ifp) == 1) + { + switch (tag) + { + case GMON_TAG_TIME_HIST: + ++nhist; + gmon_input |= INPUT_HISTOGRAM; + hist_read_rec (ifp, filename); + break; + + case GMON_TAG_CG_ARC: + ++narcs; + gmon_input |= INPUT_CALL_GRAPH; + cg_read_rec (ifp, filename); + break; + + case GMON_TAG_BB_COUNT: + ++nbbs; + gmon_input |= INPUT_BB_COUNTS; + bb_read_rec (ifp, filename); + break; + + default: + fprintf (stderr, + _("%s: %s: found bad tag %d (file corrupted?)\n"), + whoami, filename, tag); + done (1); + } + } + } + else if (file_format == FF_AUTO + || file_format == FF_BSD + || file_format == FF_BSD44) + { + struct hdr + { + bfd_vma low_pc; + bfd_vma high_pc; + int ncnt; + }; + int i, samp_bytes, header_size = 0; + unsigned long count; + bfd_vma from_pc, self_pc; + static struct hdr h; + UNIT raw_bin_count; + struct hdr tmp; + int version; + + /* Information from a gmon.out file is in two parts: an array of + sampling hits within pc ranges, and the arcs. */ + gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH; + + /* This fseek() ought to work even on stdin as long as it's + not an interactive device (heck, is there anybody who would + want to type in a gmon.out at the terminal?). */ + if (fseek (ifp, 0, SEEK_SET) < 0) + { + perror (filename); + done (1); + } + + /* The beginning of the old BSD header and the 4.4BSD header + are the same: lowpc, highpc, ncnt */ + if (gmon_io_read_vma (ifp, &tmp.low_pc) + || gmon_io_read_vma (ifp, &tmp.high_pc) + || gmon_io_read_32 (ifp, &tmp.ncnt)) + { + bad_gmon_file: + fprintf (stderr, _("%s: file too short to be a gmon file\n"), + filename); + done (1); + } + + /* Check to see if this a 4.4BSD-style header. */ + if (gmon_io_read_32 (ifp, &version)) + goto bad_gmon_file; + + if (version == GMONVERSION) + { + int profrate; + + /* 4.4BSD format header. */ + if (gmon_io_read_32 (ifp, &profrate)) + goto bad_gmon_file; + + if (!s_highpc) + hz = profrate; + else if (hz != profrate) + { + fprintf (stderr, + _("%s: profiling rate incompatible with first gmon file\n"), + filename); + done (1); + } + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + header_size = GMON_HDRSIZE_BSD44_32; + break; + + case ptr_64bit: + header_size = GMON_HDRSIZE_BSD44_64; + break; + } + } + else + { + /* Old style BSD format. */ + if (file_format == FF_BSD44) + { + fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"), + whoami, filename); + done (1); + } + + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + header_size = GMON_HDRSIZE_OLDBSD_32; + break; + + case ptr_64bit: + header_size = GMON_HDRSIZE_OLDBSD_64; + break; + } + } + + /* Position the file to after the header. */ + if (fseek (ifp, header_size, SEEK_SET) < 0) + { + perror (filename); + done (1); + } + + if (s_highpc && (tmp.low_pc != h.low_pc + || tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt)) + { + fprintf (stderr, _("%s: incompatible with first gmon file\n"), + filename); + done (1); + } + + h = tmp; + s_lowpc = (bfd_vma) h.low_pc; + s_highpc = (bfd_vma) h.high_pc; + lowpc = (bfd_vma) h.low_pc / sizeof (UNIT); + highpc = (bfd_vma) h.high_pc / sizeof (UNIT); + samp_bytes = h.ncnt - header_size; + hist_num_bins = samp_bytes / sizeof (UNIT); + + DBG (SAMPLEDEBUG, + printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n", + (unsigned long) h.low_pc, (unsigned long) h.high_pc, + h.ncnt); + printf ("[gmon_out_read] s_lowpc 0x%lx s_highpc 0x%lx\n", + (unsigned long) s_lowpc, (unsigned long) s_highpc); + printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx\n", + (unsigned long) lowpc, (unsigned long) highpc); + printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n", + samp_bytes, hist_num_bins)); + + /* Make sure that we have sensible values. */ + if (samp_bytes < 0 || lowpc > highpc) + { + fprintf (stderr, + _("%s: file '%s' does not appear to be in gmon.out format\n"), + whoami, filename); + done (1); + } + + if (hist_num_bins) + ++nhist; + + if (!hist_sample) + { + hist_sample = + (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0])); + + memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0])); + } + + for (i = 0; i < hist_num_bins; ++i) + { + if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1) + { + fprintf (stderr, + _("%s: unexpected EOF after reading %d/%d bins\n"), + whoami, --i, hist_num_bins); + done (1); + } + + hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count); + } + + /* The rest of the file consists of a bunch of + <from,self,count> tuples. */ + while (gmon_read_raw_arc (ifp, &from_pc, &self_pc, &count) == 0) + { + ++narcs; + + DBG (SAMPLEDEBUG, + printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n", + (unsigned long) from_pc, (unsigned long) self_pc, count)); + + /* Add this arc. */ + cg_tally (from_pc, self_pc, count); + } + + fclose (ifp); + + if (hz == HZ_WRONG) + { + /* How many ticks per second? If we can't tell, report + time in ticks. */ + hz = hertz (); + + if (hz == HZ_WRONG) + { + hz = 1; + fprintf (stderr, _("time is in ticks, not seconds\n")); + } + } + } + else + { + fprintf (stderr, _("%s: don't know how to deal with file format %d\n"), + whoami, file_format); + done (1); + } + + if (output_style & STYLE_GMON_INFO) + { + printf (_("File `%s' (version %d) contains:\n"), + filename, gmon_file_version); + printf (nhist == 1 ? + _("\t%d histogram record\n") : + _("\t%d histogram records\n"), nhist); + printf (narcs == 1 ? + _("\t%d call-graph record\n") : + _("\t%d call-graph records\n"), narcs); + printf (nbbs == 1 ? + _("\t%d basic-block count record\n") : + _("\t%d basic-block count records\n"), nbbs); + first_output = FALSE; + } +} + + +void +gmon_out_write (filename) + const char *filename; +{ + FILE *ofp; + struct gmon_hdr ghdr; + + ofp = fopen (filename, FOPEN_WB); + if (!ofp) + { + perror (filename); + done (1); + } + + if (file_format == FF_AUTO || file_format == FF_MAGIC) + { + /* Write gmon header. */ + + memcpy (&ghdr.cookie[0], GMON_MAGIC, 4); + bfd_put_32 (core_bfd, (bfd_vma) GMON_VERSION, (bfd_byte *) ghdr.version); + + if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1) + { + perror (filename); + done (1); + } + + /* Write execution time histogram if we have one. */ + if (gmon_input & INPUT_HISTOGRAM) + hist_write_hist (ofp, filename); + + /* Write call graph arcs if we have any. */ + if (gmon_input & INPUT_CALL_GRAPH) + cg_write_arcs (ofp, filename); + + /* Write basic-block info if we have it. */ + if (gmon_input & INPUT_BB_COUNTS) + bb_write_blocks (ofp, filename); + } + else if (file_format == FF_BSD || file_format == FF_BSD44) + { + UNIT raw_bin_count; + int i, hdrsize; + unsigned padsize; + char pad[3*4]; + Arc *arc; + Sym *sym; + + memset (pad, 0, sizeof (pad)); + + hdrsize = 0; + /* Decide how large the header will be. Use the 4.4BSD format + header if explicitly specified, or if the profiling rate is + non-standard. Otherwise, use the old BSD format. */ + if (file_format == FF_BSD44 + || hz != hertz()) + { + padsize = 3*4; + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + hdrsize = GMON_HDRSIZE_BSD44_32; + break; + + case ptr_64bit: + hdrsize = GMON_HDRSIZE_BSD44_64; + break; + } + } + else + { + padsize = 0; + switch (gmon_get_ptr_size ()) + { + case ptr_32bit: + hdrsize = GMON_HDRSIZE_OLDBSD_32; + break; + + case ptr_64bit: + hdrsize = GMON_HDRSIZE_OLDBSD_64; + /* FIXME: Checking host compiler defines here means that we can't + use a cross gprof alpha OSF. */ +#if defined(__alpha__) && defined (__osf__) + padsize = 4; +#endif + break; + } + } + + /* Write the parts of the headers that are common to both the + old BSD and 4.4BSD formats. */ + if (gmon_io_write_vma (ofp, s_lowpc) + || gmon_io_write_vma (ofp, s_highpc) + || gmon_io_write_32 (ofp, hist_num_bins * sizeof (UNIT) + hdrsize)) + { + perror (filename); + done (1); + } + + /* Write out the 4.4BSD header bits, if that's what we're using. */ + if (file_format == FF_BSD44 + || hz != hertz()) + { + if (gmon_io_write_32 (ofp, GMONVERSION) + || gmon_io_write_32 (ofp, (unsigned int) hz)) + { + perror (filename); + done (1); + } + } + + /* Now write out any necessary padding after the meaningful + header bits. */ + if (padsize != 0 + && fwrite (pad, 1, padsize, ofp) != padsize) + { + perror (filename); + done (1); + } + + /* Dump the samples. */ + for (i = 0; i < hist_num_bins; ++i) + { + bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i], + (bfd_byte *) &raw_bin_count[0]); + if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1) + { + perror (filename); + done (1); + } + } + + /* Dump the normalized raw arc information. */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + for (arc = sym->cg.children; arc; arc = arc->next_child) + { + if (gmon_write_raw_arc (ofp, arc->parent->addr, + arc->child->addr, arc->count)) + { + perror (filename); + done (1); + } + DBG (SAMPLEDEBUG, + printf ("[dumpsum] frompc 0x%lx selfpc 0x%lx count %lu\n", + (unsigned long) arc->parent->addr, + (unsigned long) arc->child->addr, arc->count)); + } + } + + fclose (ofp); + } + else + { + fprintf (stderr, _("%s: don't know how to deal with file format %d\n"), + whoami, file_format); + done (1); + } +} diff --git a/gprof/gmon_io.h b/gprof/gmon_io.h new file mode 100644 index 000000000000..b632d758e5c9 --- /dev/null +++ b/gprof/gmon_io.h @@ -0,0 +1,60 @@ +/* gmon_io.h + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef gmon_io_h +#define gmon_io_h + +/* Some platforms need to put stdin into binary mode, to read + binary files. */ +#include "sysdep.h" +#ifdef HAVE_SETMODE +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#define setmode _setmode +#else +#define O_BINARY 0 +#endif +#endif +#if O_BINARY +#include <io.h> +#define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0) +#endif +#endif + +#define INPUT_HISTOGRAM (1 << 0) +#define INPUT_CALL_GRAPH (1 << 1) +#define INPUT_BB_COUNTS (1 << 2) + +extern int gmon_input; /* What input did we see? */ +extern int gmon_file_version; /* File version are we dealing with. */ + +extern int gmon_io_read_vma PARAMS ((FILE *ifp, bfd_vma *valp)); +extern int gmon_io_read_32 PARAMS ((FILE *ifp, unsigned int *valp)); +extern int gmon_io_read PARAMS ((FILE *ifp, char *buf, size_t n)); +extern int gmon_io_write_vma PARAMS ((FILE *ifp, bfd_vma val)); +extern int gmon_io_write_32 PARAMS ((FILE *ifp, unsigned int val)); +extern int gmon_io_write_8 PARAMS ((FILE *ifp, unsigned int val)); +extern int gmon_io_write PARAMS ((FILE *ifp, char *buf, size_t n)); + +extern void gmon_out_read PARAMS ((const char *)); +extern void gmon_out_write PARAMS ((const char *)); + +#endif /* gmon_io_h */ diff --git a/gprof/gmon_out.h b/gprof/gmon_out.h new file mode 100644 index 000000000000..25dce59d93c6 --- /dev/null +++ b/gprof/gmon_out.h @@ -0,0 +1,45 @@ +/* gmon_out.h + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* A gmon.out file consists of a header (defined by gmon_hdr) followed + by a sequence of records. Each record starts with a one-byte tag + identifying the type of records, followed by records specific data. */ +#ifndef gmon_out_h +#define gmon_out_h + +#define GMON_MAGIC "gmon" /* magic cookie */ +#define GMON_VERSION 1 /* version number */ + +/* Raw header as it appears on file (without padding). */ +struct gmon_hdr + { + char cookie[4]; + char version[4]; + char spare[3 * 4]; + }; + +/* Types of records in this file. */ +typedef enum + { + GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2 + } +GMON_Record_Tag; + +#endif /* gmon_out_h */ diff --git a/gprof/gprof.1 b/gprof/gprof.1 new file mode 100644 index 000000000000..820d838763a1 --- /dev/null +++ b/gprof/gprof.1 @@ -0,0 +1,712 @@ +.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14 +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to +.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' +.\" expand to `' in nroff, nothing in troff, for use with C<>. +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.hy 0 +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "GPROF 1" +.TH GPROF 1 "2004-04-09" "binutils-2.14.91" "GNU" +.SH "NAME" +gprof \- display call graph profile data +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +gprof [ \-[abcDhilLsTvwxyz] ] [ \-[ACeEfFJnNOpPqQZ][\fIname\fR] ] + [ \-I \fIdirs\fR ] [ \-d[\fInum\fR] ] [ \-k \fIfrom/to\fR ] + [ \-m \fImin-count\fR ] [ \-t \fItable-length\fR ] + [ \-\-[no\-]annotated\-source[=\fIname\fR] ] + [ \-\-[no\-]exec\-counts[=\fIname\fR] ] + [ \-\-[no\-]flat\-profile[=\fIname\fR] ] [ \-\-[no\-]graph[=\fIname\fR] ] + [ \-\-[no\-]time=\fIname\fR] [ \-\-all\-lines ] [ \-\-brief ] + [ \-\-debug[=\fIlevel\fR] ] [ \-\-function\-ordering ] + [ \-\-file\-ordering ] [ \-\-directory\-path=\fIdirs\fR ] + [ \-\-display\-unused\-functions ] [ \-\-file\-format=\fIname\fR ] + [ \-\-file\-info ] [ \-\-help ] [ \-\-line ] [ \-\-min\-count=\fIn\fR ] + [ \-\-no\-static ] [ \-\-print\-path ] [ \-\-separate\-files ] + [ \-\-static\-call\-graph ] [ \-\-sum ] [ \-\-table\-length=\fIlen\fR ] + [ \-\-traditional ] [ \-\-version ] [ \-\-width=\fIn\fR ] + [ \-\-ignore\-non\-functions ] [ \-\-demangle[=\fI\s-1STYLE\s0\fR] ] + [ \-\-no\-demangle ] [ \fIimage-file\fR ] [ \fIprofile-file\fR ... ] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\f(CW\*(C`gprof\*(C'\fR produces an execution profile of C, Pascal, or Fortran77 +programs. The effect of called routines is incorporated in the profile +of each caller. The profile data is taken from the call graph profile file +(\fIgmon.out\fR default) which is created by programs +that are compiled with the \fB\-pg\fR option of +\&\f(CW\*(C`cc\*(C'\fR, \f(CW\*(C`pc\*(C'\fR, and \f(CW\*(C`f77\*(C'\fR. +The \fB\-pg\fR option also links in versions of the library routines +that are compiled for profiling. \f(CW\*(C`Gprof\*(C'\fR reads the given object +file (the default is \f(CW\*(C`a.out\*(C'\fR) and establishes the relation between +its symbol table and the call graph profile from \fIgmon.out\fR. +If more than one profile file is specified, the \f(CW\*(C`gprof\*(C'\fR +output shows the sum of the profile information in the given profile files. +.PP +\&\f(CW\*(C`Gprof\*(C'\fR calculates the amount of time spent in each routine. +Next, these times are propagated along the edges of the call graph. +Cycles are discovered, and calls into a cycle are made to share the time +of the cycle. +.PP +Several forms of output are available from the analysis. +.PP +The \fIflat profile\fR shows how much time your program spent in each function, +and how many times that function was called. If you simply want to know +which functions burn most of the cycles, it is stated concisely here. +.PP +The \fIcall graph\fR shows, for each function, which functions called it, which +other functions it called, and how many times. There is also an estimate +of how much time was spent in the subroutines of each function. This can +suggest places where you might try to eliminate function calls that use a +lot of time. +.PP +The \fIannotated source\fR listing is a copy of the program's +source code, labeled with the number of times each line of the +program was executed. +.SH "OPTIONS" +.IX Header "OPTIONS" +These options specify which of several output formats +\&\f(CW\*(C`gprof\*(C'\fR should produce. +.PP +Many of these options take an optional \fIsymspec\fR to specify +functions to be included or excluded. These options can be +specified multiple times, with different symspecs, to include +or exclude sets of symbols. +.PP +Specifying any of these options overrides the default (\fB\-p \-q\fR), +which prints a flat profile and call graph analysis +for all functions. +.ie n .IP """\-A[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-A[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-A[symspec]" +.PD 0 +.ie n .IP """\-\-annotated\-source[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-annotated\-source[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--annotated-source[=symspec]" +.PD +The \fB\-A\fR option causes \f(CW\*(C`gprof\*(C'\fR to print annotated source code. +If \fIsymspec\fR is specified, print output only for matching symbols. +.ie n .IP """\-b""" 4 +.el .IP "\f(CW\-b\fR" 4 +.IX Item "-b" +.PD 0 +.ie n .IP """\-\-brief""" 4 +.el .IP "\f(CW\-\-brief\fR" 4 +.IX Item "--brief" +.PD +If the \fB\-b\fR option is given, \f(CW\*(C`gprof\*(C'\fR doesn't print the +verbose blurbs that try to explain the meaning of all of the fields in +the tables. This is useful if you intend to print out the output, or +are tired of seeing the blurbs. +.ie n .IP """\-C[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-C[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-C[symspec]" +.PD 0 +.ie n .IP """\-\-exec\-counts[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-exec\-counts[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--exec-counts[=symspec]" +.PD +The \fB\-C\fR option causes \f(CW\*(C`gprof\*(C'\fR to +print a tally of functions and the number of times each was called. +If \fIsymspec\fR is specified, print tally only for matching symbols. +.Sp +If the profile data file contains basic-block count records, specifying +the \fB\-l\fR option, along with \fB\-C\fR, will cause basic-block +execution counts to be tallied and displayed. +.ie n .IP """\-i""" 4 +.el .IP "\f(CW\-i\fR" 4 +.IX Item "-i" +.PD 0 +.ie n .IP """\-\-file\-info""" 4 +.el .IP "\f(CW\-\-file\-info\fR" 4 +.IX Item "--file-info" +.PD +The \fB\-i\fR option causes \f(CW\*(C`gprof\*(C'\fR to display summary information +about the profile data file(s) and then exit. The number of histogram, +call graph, and basic-block count records is displayed. +.ie n .IP """\-I \f(CIdirs\f(CW""" 4 +.el .IP "\f(CW\-I \f(CIdirs\f(CW\fR" 4 +.IX Item "-I dirs" +.PD 0 +.ie n .IP """\-\-directory\-path=\f(CIdirs\f(CW""" 4 +.el .IP "\f(CW\-\-directory\-path=\f(CIdirs\f(CW\fR" 4 +.IX Item "--directory-path=dirs" +.PD +The \fB\-I\fR option specifies a list of search directories in +which to find source files. Environment variable \fI\s-1GPROF_PATH\s0\fR +can also be used to convey this information. +Used mostly for annotated source output. +.ie n .IP """\-J[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-J[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-J[symspec]" +.PD 0 +.ie n .IP """\-\-no\-annotated\-source[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-no\-annotated\-source[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--no-annotated-source[=symspec]" +.PD +The \fB\-J\fR option causes \f(CW\*(C`gprof\*(C'\fR not to +print annotated source code. +If \fIsymspec\fR is specified, \f(CW\*(C`gprof\*(C'\fR prints annotated source, +but excludes matching symbols. +.ie n .IP """\-L""" 4 +.el .IP "\f(CW\-L\fR" 4 +.IX Item "-L" +.PD 0 +.ie n .IP """\-\-print\-path""" 4 +.el .IP "\f(CW\-\-print\-path\fR" 4 +.IX Item "--print-path" +.PD +Normally, source filenames are printed with the path +component suppressed. The \fB\-L\fR option causes \f(CW\*(C`gprof\*(C'\fR +to print the full pathname of +source filenames, which is determined +from symbolic debugging information in the image file +and is relative to the directory in which the compiler +was invoked. +.ie n .IP """\-p[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-p[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-p[symspec]" +.PD 0 +.ie n .IP """\-\-flat\-profile[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-flat\-profile[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--flat-profile[=symspec]" +.PD +The \fB\-p\fR option causes \f(CW\*(C`gprof\*(C'\fR to print a flat profile. +If \fIsymspec\fR is specified, print flat profile only for matching symbols. +.ie n .IP """\-P[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-P[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-P[symspec]" +.PD 0 +.ie n .IP """\-\-no\-flat\-profile[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-no\-flat\-profile[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--no-flat-profile[=symspec]" +.PD +The \fB\-P\fR option causes \f(CW\*(C`gprof\*(C'\fR to suppress printing a flat profile. +If \fIsymspec\fR is specified, \f(CW\*(C`gprof\*(C'\fR prints a flat profile, +but excludes matching symbols. +.ie n .IP """\-q[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-q[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-q[symspec]" +.PD 0 +.ie n .IP """\-\-graph[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-graph[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--graph[=symspec]" +.PD +The \fB\-q\fR option causes \f(CW\*(C`gprof\*(C'\fR to print the call graph analysis. +If \fIsymspec\fR is specified, print call graph only for matching symbols +and their children. +.ie n .IP """\-Q[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-Q[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-Q[symspec]" +.PD 0 +.ie n .IP """\-\-no\-graph[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-no\-graph[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--no-graph[=symspec]" +.PD +The \fB\-Q\fR option causes \f(CW\*(C`gprof\*(C'\fR to suppress printing the +call graph. +If \fIsymspec\fR is specified, \f(CW\*(C`gprof\*(C'\fR prints a call graph, +but excludes matching symbols. +.ie n .IP """\-y""" 4 +.el .IP "\f(CW\-y\fR" 4 +.IX Item "-y" +.PD 0 +.ie n .IP """\-\-separate\-files""" 4 +.el .IP "\f(CW\-\-separate\-files\fR" 4 +.IX Item "--separate-files" +.PD +This option affects annotated source output only. +Normally, \f(CW\*(C`gprof\*(C'\fR prints annotated source files +to standard\-output. If this option is specified, +annotated source for a file named \fIpath/\fIfilename\fI\fR +is generated in the file \fI\fIfilename\fI\-ann\fR. If the underlying +filesystem would truncate \fI\fIfilename\fI\-ann\fR so that it +overwrites the original \fI\fIfilename\fI\fR, \f(CW\*(C`gprof\*(C'\fR generates +annotated source in the file \fI\fIfilename\fI.ann\fR instead (if the +original file name has an extension, that extension is \fIreplaced\fR +with \fI.ann\fR). +.ie n .IP """\-Z[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-Z[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-Z[symspec]" +.PD 0 +.ie n .IP """\-\-no\-exec\-counts[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-no\-exec\-counts[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--no-exec-counts[=symspec]" +.PD +The \fB\-Z\fR option causes \f(CW\*(C`gprof\*(C'\fR not to +print a tally of functions and the number of times each was called. +If \fIsymspec\fR is specified, print tally, but exclude matching symbols. +.ie n .IP """\-\-function\-ordering""" 4 +.el .IP "\f(CW\-\-function\-ordering\fR" 4 +.IX Item "--function-ordering" +The \fB\-\-function\-ordering\fR option causes \f(CW\*(C`gprof\*(C'\fR to print a +suggested function ordering for the program based on profiling data. +This option suggests an ordering which may improve paging, tlb and +cache behavior for the program on systems which support arbitrary +ordering of functions in an executable. +.Sp +The exact details of how to force the linker to place functions +in a particular order is system dependent and out of the scope of this +manual. +.ie n .IP """\-\-file\-ordering \f(CImap_file\f(CW""" 4 +.el .IP "\f(CW\-\-file\-ordering \f(CImap_file\f(CW\fR" 4 +.IX Item "--file-ordering map_file" +The \fB\-\-file\-ordering\fR option causes \f(CW\*(C`gprof\*(C'\fR to print a +suggested .o link line ordering for the program based on profiling data. +This option suggests an ordering which may improve paging, tlb and +cache behavior for the program on systems which do not support arbitrary +ordering of functions in an executable. +.Sp +Use of the \fB\-a\fR argument is highly recommended with this option. +.Sp +The \fImap_file\fR argument is a pathname to a file which provides +function name to object file mappings. The format of the file is similar to +the output of the program \f(CW\*(C`nm\*(C'\fR. +.Sp +.Vb 8 +\& c-parse.o:00000000 T yyparse +\& c-parse.o:00000004 C yyerrflag +\& c-lang.o:00000000 T maybe_objc_method_name +\& c-lang.o:00000000 T print_lang_statistics +\& c-lang.o:00000000 T recognize_objc_keyword +\& c-decl.o:00000000 T print_lang_identifier +\& c-decl.o:00000000 T print_lang_type +\& ... +.Ve +.Sp +To create a \fImap_file\fR with \s-1GNU\s0 \f(CW\*(C`nm\*(C'\fR, type a command like +\&\f(CW\*(C`nm \-\-extern\-only \-\-defined\-only \-v \-\-print\-file\-name program\-name\*(C'\fR. +.ie n .IP """\-T""" 4 +.el .IP "\f(CW\-T\fR" 4 +.IX Item "-T" +.PD 0 +.ie n .IP """\-\-traditional""" 4 +.el .IP "\f(CW\-\-traditional\fR" 4 +.IX Item "--traditional" +.PD +The \fB\-T\fR option causes \f(CW\*(C`gprof\*(C'\fR to print its output in +``traditional'' \s-1BSD\s0 style. +.ie n .IP """\-w \f(CIwidth\f(CW""" 4 +.el .IP "\f(CW\-w \f(CIwidth\f(CW\fR" 4 +.IX Item "-w width" +.PD 0 +.ie n .IP """\-\-width=\f(CIwidth\f(CW""" 4 +.el .IP "\f(CW\-\-width=\f(CIwidth\f(CW\fR" 4 +.IX Item "--width=width" +.PD +Sets width of output lines to \fIwidth\fR. +Currently only used when printing the function index at the bottom +of the call graph. +.ie n .IP """\-x""" 4 +.el .IP "\f(CW\-x\fR" 4 +.IX Item "-x" +.PD 0 +.ie n .IP """\-\-all\-lines""" 4 +.el .IP "\f(CW\-\-all\-lines\fR" 4 +.IX Item "--all-lines" +.PD +This option affects annotated source output only. +By default, only the lines at the beginning of a basic-block +are annotated. If this option is specified, every line in +a basic-block is annotated by repeating the annotation for the +first line. This behavior is similar to \f(CW\*(C`tcov\*(C'\fR's \fB\-a\fR. +.ie n .IP """\-\-demangle[=\f(CIstyle\f(CW]""" 4 +.el .IP "\f(CW\-\-demangle[=\f(CIstyle\f(CW]\fR" 4 +.IX Item "--demangle[=style]" +.PD 0 +.ie n .IP """\-\-no\-demangle""" 4 +.el .IP "\f(CW\-\-no\-demangle\fR" 4 +.IX Item "--no-demangle" +.PD +These options control whether \*(C+ symbol names should be demangled when +printing output. The default is to demangle symbols. The +\&\f(CW\*(C`\-\-no\-demangle\*(C'\fR option may be used to turn off demangling. Different +compilers have different mangling styles. The optional demangling style +argument can be used to choose an appropriate demangling style for your +compiler. +.Sh "Analysis Options" +.IX Subsection "Analysis Options" +.ie n .IP """\-a""" 4 +.el .IP "\f(CW\-a\fR" 4 +.IX Item "-a" +.PD 0 +.ie n .IP """\-\-no\-static""" 4 +.el .IP "\f(CW\-\-no\-static\fR" 4 +.IX Item "--no-static" +.PD +The \fB\-a\fR option causes \f(CW\*(C`gprof\*(C'\fR to suppress the printing of +statically declared (private) functions. (These are functions whose +names are not listed as global, and which are not visible outside the +file/function/block where they were defined.) Time spent in these +functions, calls to/from them, etc, will all be attributed to the +function that was loaded directly before it in the executable file. +This option affects both the flat profile and the call graph. +.ie n .IP """\-c""" 4 +.el .IP "\f(CW\-c\fR" 4 +.IX Item "-c" +.PD 0 +.ie n .IP """\-\-static\-call\-graph""" 4 +.el .IP "\f(CW\-\-static\-call\-graph\fR" 4 +.IX Item "--static-call-graph" +.PD +The \fB\-c\fR option causes the call graph of the program to be +augmented by a heuristic which examines the text space of the object +file and identifies function calls in the binary machine code. +Since normal call graph records are only generated when functions are +entered, this option identifies children that could have been called, +but never were. Calls to functions that were not compiled with +profiling enabled are also identified, but only if symbol table +entries are present for them. +Calls to dynamic library routines are typically \fInot\fR found +by this option. +Parents or children identified via this heuristic +are indicated in the call graph with call counts of \fB0\fR. +.ie n .IP """\-D""" 4 +.el .IP "\f(CW\-D\fR" 4 +.IX Item "-D" +.PD 0 +.ie n .IP """\-\-ignore\-non\-functions""" 4 +.el .IP "\f(CW\-\-ignore\-non\-functions\fR" 4 +.IX Item "--ignore-non-functions" +.PD +The \fB\-D\fR option causes \f(CW\*(C`gprof\*(C'\fR to ignore symbols which +are not known to be functions. This option will give more accurate +profile data on systems where it is supported (Solaris and \s-1HPUX\s0 for +example). +.ie n .IP """\-k \f(CIfrom\f(CW/\f(CIto\f(CW""" 4 +.el .IP "\f(CW\-k \f(CIfrom\f(CW/\f(CIto\f(CW\fR" 4 +.IX Item "-k from/to" +The \fB\-k\fR option allows you to delete from the call graph any arcs from +symbols matching symspec \fIfrom\fR to those matching symspec \fIto\fR. +.ie n .IP """\-l""" 4 +.el .IP "\f(CW\-l\fR" 4 +.IX Item "-l" +.PD 0 +.ie n .IP """\-\-line""" 4 +.el .IP "\f(CW\-\-line\fR" 4 +.IX Item "--line" +.PD +The \fB\-l\fR option enables line-by-line profiling, which causes +histogram hits to be charged to individual source code lines, +instead of functions. +If the program was compiled with basic-block counting enabled, +this option will also identify how many times each line of +code was executed. +While line-by-line profiling can help isolate where in a large function +a program is spending its time, it also significantly increases +the running time of \f(CW\*(C`gprof\*(C'\fR, and magnifies statistical +inaccuracies. +.ie n .IP """\-m \f(CInum\f(CW""" 4 +.el .IP "\f(CW\-m \f(CInum\f(CW\fR" 4 +.IX Item "-m num" +.PD 0 +.ie n .IP """\-\-min\-count=\f(CInum\f(CW""" 4 +.el .IP "\f(CW\-\-min\-count=\f(CInum\f(CW\fR" 4 +.IX Item "--min-count=num" +.PD +This option affects execution count output only. +Symbols that are executed less than \fInum\fR times are suppressed. +.ie n .IP """\-n[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-n[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-n[symspec]" +.PD 0 +.ie n .IP """\-\-time[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-time[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--time[=symspec]" +.PD +The \fB\-n\fR option causes \f(CW\*(C`gprof\*(C'\fR, in its call graph analysis, +to only propagate times for symbols matching \fIsymspec\fR. +.ie n .IP """\-N[\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-N[\f(CIsymspec\f(CW]\fR" 4 +.IX Item "-N[symspec]" +.PD 0 +.ie n .IP """\-\-no\-time[=\f(CIsymspec\f(CW]""" 4 +.el .IP "\f(CW\-\-no\-time[=\f(CIsymspec\f(CW]\fR" 4 +.IX Item "--no-time[=symspec]" +.PD +The \fB\-n\fR option causes \f(CW\*(C`gprof\*(C'\fR, in its call graph analysis, +not to propagate times for symbols matching \fIsymspec\fR. +.ie n .IP """\-z""" 4 +.el .IP "\f(CW\-z\fR" 4 +.IX Item "-z" +.PD 0 +.ie n .IP """\-\-display\-unused\-functions""" 4 +.el .IP "\f(CW\-\-display\-unused\-functions\fR" 4 +.IX Item "--display-unused-functions" +.PD +If you give the \fB\-z\fR option, \f(CW\*(C`gprof\*(C'\fR will mention all +functions in the flat profile, even those that were never called, and +that had no time spent in them. This is useful in conjunction with the +\&\fB\-c\fR option for discovering which routines were never called. +.Sh "Miscellaneous Options" +.IX Subsection "Miscellaneous Options" +.ie n .IP """\-d[\f(CInum\f(CW]""" 4 +.el .IP "\f(CW\-d[\f(CInum\f(CW]\fR" 4 +.IX Item "-d[num]" +.PD 0 +.ie n .IP """\-\-debug[=\f(CInum\f(CW]""" 4 +.el .IP "\f(CW\-\-debug[=\f(CInum\f(CW]\fR" 4 +.IX Item "--debug[=num]" +.PD +The \fB\-d\fR \fInum\fR option specifies debugging options. +If \fInum\fR is not specified, enable all debugging. +.ie n .IP """\-O\f(CIname\f(CW""" 4 +.el .IP "\f(CW\-O\f(CIname\f(CW\fR" 4 +.IX Item "-Oname" +.PD 0 +.ie n .IP """\-\-file\-format=\f(CIname\f(CW""" 4 +.el .IP "\f(CW\-\-file\-format=\f(CIname\f(CW\fR" 4 +.IX Item "--file-format=name" +.PD +Selects the format of the profile data files. Recognized formats are +\&\fBauto\fR (the default), \fBbsd\fR, \fB4.4bsd\fR, \fBmagic\fR, and +\&\fBprof\fR (not yet supported). +.ie n .IP """\-s""" 4 +.el .IP "\f(CW\-s\fR" 4 +.IX Item "-s" +.PD 0 +.ie n .IP """\-\-sum""" 4 +.el .IP "\f(CW\-\-sum\fR" 4 +.IX Item "--sum" +.PD +The \fB\-s\fR option causes \f(CW\*(C`gprof\*(C'\fR to summarize the information +in the profile data files it read in, and write out a profile data +file called \fIgmon.sum\fR, which contains all the information from +the profile data files that \f(CW\*(C`gprof\*(C'\fR read in. The file \fIgmon.sum\fR +may be one of the specified input files; the effect of this is to +merge the data in the other input files into \fIgmon.sum\fR. +.Sp +Eventually you can run \f(CW\*(C`gprof\*(C'\fR again without \fB\-s\fR to analyze the +cumulative data in the file \fIgmon.sum\fR. +.ie n .IP """\-v""" 4 +.el .IP "\f(CW\-v\fR" 4 +.IX Item "-v" +.PD 0 +.ie n .IP """\-\-version""" 4 +.el .IP "\f(CW\-\-version\fR" 4 +.IX Item "--version" +.PD +The \fB\-v\fR flag causes \f(CW\*(C`gprof\*(C'\fR to print the current version +number, and then exit. +.Sh "Deprecated Options" +.IX Subsection "Deprecated Options" +.RS 4 +These options have been replaced with newer versions that use symspecs. +.RE +.ie n .IP """\-e \f(CIfunction_name\f(CW""" 4 +.el .IP "\f(CW\-e \f(CIfunction_name\f(CW\fR" 4 +.IX Item "-e function_name" +The \fB\-e\fR \fIfunction\fR option tells \f(CW\*(C`gprof\*(C'\fR to not print +information about the function \fIfunction_name\fR (and its +children...) in the call graph. The function will still be listed +as a child of any functions that call it, but its index number will be +shown as \fB[not printed]\fR. More than one \fB\-e\fR option may be +given; only one \fIfunction_name\fR may be indicated with each \fB\-e\fR +option. +.ie n .IP """\-E \f(CIfunction_name\f(CW""" 4 +.el .IP "\f(CW\-E \f(CIfunction_name\f(CW\fR" 4 +.IX Item "-E function_name" +The \f(CW\*(C`\-E \f(CIfunction\f(CW\*(C'\fR option works like the \f(CW\*(C`\-e\*(C'\fR option, but +time spent in the function (and children who were not called from +anywhere else), will not be used to compute the percentages-of-time for +the call graph. More than one \fB\-E\fR option may be given; only one +\&\fIfunction_name\fR may be indicated with each \fB\-E\fR option. +.ie n .IP """\-f \f(CIfunction_name\f(CW""" 4 +.el .IP "\f(CW\-f \f(CIfunction_name\f(CW\fR" 4 +.IX Item "-f function_name" +The \fB\-f\fR \fIfunction\fR option causes \f(CW\*(C`gprof\*(C'\fR to limit the +call graph to the function \fIfunction_name\fR and its children (and +their children...). More than one \fB\-f\fR option may be given; +only one \fIfunction_name\fR may be indicated with each \fB\-f\fR +option. +.ie n .IP """\-F \f(CIfunction_name\f(CW""" 4 +.el .IP "\f(CW\-F \f(CIfunction_name\f(CW\fR" 4 +.IX Item "-F function_name" +The \fB\-F\fR \fIfunction\fR option works like the \f(CW\*(C`\-f\*(C'\fR option, but +only time spent in the function and its children (and their +children...) will be used to determine total-time and +percentages-of-time for the call graph. More than one \fB\-F\fR option +may be given; only one \fIfunction_name\fR may be indicated with each +\&\fB\-F\fR option. The \fB\-F\fR option overrides the \fB\-E\fR option. +.SH "FILES" +.IX Header "FILES" +.ie n .IP """\f(CIa.out\f(CW""" 4 +.el .IP "\f(CW\f(CIa.out\f(CW\fR" 4 +.IX Item "a.out" +the namelist and text space. +.ie n .IP """\f(CIgmon.out\f(CW""" 4 +.el .IP "\f(CW\f(CIgmon.out\f(CW\fR" 4 +.IX Item "gmon.out" +dynamic call graph and profile. +.ie n .IP """\f(CIgmon.sum\f(CW""" 4 +.el .IP "\f(CW\f(CIgmon.sum\f(CW\fR" 4 +.IX Item "gmon.sum" +summarized dynamic call graph and profile. +.SH "BUGS" +.IX Header "BUGS" +The granularity of the sampling is shown, but remains +statistical at best. +We assume that the time for each execution of a function +can be expressed by the total time for the function divided +by the number of times the function is called. +Thus the time propagated along the call graph arcs to the function's +parents is directly proportional to the number of times that +arc is traversed. +.PP +Parents that are not themselves profiled will have the time of +their profiled children propagated to them, but they will appear +to be spontaneously invoked in the call graph listing, and will +not have their time propagated further. +Similarly, signal catchers, even though profiled, will appear +to be spontaneous (although for more obscure reasons). +Any profiled children of signal catchers should have their times +propagated properly, unless the signal catcher was invoked during +the execution of the profiling routine, in which case all is lost. +.PP +The profiled program must call \f(CW\*(C`exit\*(C'\fR(2) +or return normally for the profiling information to be saved +in the \fIgmon.out\fR file. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fImonitor\fR\|(3), \fIprofil\fR\|(2), \fIcc\fR\|(1), \fIprof\fR\|(1), and the Info entry for \fIgprof\fR. +.PP +``An Execution Profiler for Modular Programs'', +by S. Graham, P. Kessler, M. McKusick; +Software \- Practice and Experience, +Vol. 13, pp. 671\-685, 1983. +.PP +``gprof: A Call Graph Execution Profiler'', +by S. Graham, P. Kessler, M. McKusick; +Proceedings of the \s-1SIGPLAN\s0 '82 Symposium on Compiler Construction, +\&\s-1SIGPLAN\s0 Notices, Vol. 17, No 6, pp. 120\-126, June 1982. +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright (C) 1988, 92, 97, 98, 99, 2000, 2001, 2003 Free Software Foundation, Inc. +.PP +Permission is granted to copy, distribute and/or modify this document +under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation; +with no Invariant Sections, with no Front-Cover Texts, and with no +Back-Cover Texts. A copy of the license is included in the +section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gprof/gprof.c b/gprof/gprof.c new file mode 100644 index 000000000000..260dbebb4a78 --- /dev/null +++ b/gprof/gprof.c @@ -0,0 +1,696 @@ +/* + * Copyright (c) 1983, 1993, 1998, 2001, 2002 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "basic_blocks.h" +#include "call_graph.h" +#include "cg_arcs.h" +#include "cg_print.h" +#include "corefile.h" +#include "gmon_io.h" +#include "hertz.h" +#include "hist.h" +#include "sym_ids.h" +#include "demangle.h" +#include "getopt.h" + +static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN; +int main PARAMS ((int, char **)); + +const char *whoami; +const char *function_mapping_file; +const char *a_out_name = A_OUTNAME; +long hz = HZ_WRONG; + +/* + * Default options values: + */ +int debug_level = 0; +int output_style = 0; +int output_width = 80; +bfd_boolean bsd_style_output = FALSE; +bfd_boolean demangle = TRUE; +bfd_boolean discard_underscores = TRUE; +bfd_boolean ignore_direct_calls = FALSE; +bfd_boolean ignore_static_funcs = FALSE; +bfd_boolean ignore_zeros = TRUE; +bfd_boolean line_granularity = FALSE; +bfd_boolean print_descriptions = TRUE; +bfd_boolean print_path = FALSE; +bfd_boolean ignore_non_functions = FALSE; +File_Format file_format = FF_AUTO; + +bfd_boolean first_output = TRUE; + +char copyright[] = + "@(#) Copyright (c) 1983 Regents of the University of California.\n\ + All rights reserved.\n"; + +static char *gmon_name = GMONNAME; /* profile filename */ + +bfd *abfd; + +/* + * Functions that get excluded by default: + */ +static char *default_excluded_list[] = +{ + "_gprof_mcount", "mcount", "_mcount", "__mcount", "__mcount_internal", + "__mcleanup", + "<locore>", "<hicore>", + 0 +}; + +/* Codes used for the long options with no short synonyms. 150 isn't + special; it's just an arbitrary non-ASCII char value. */ + +#define OPTION_DEMANGLE (150) +#define OPTION_NO_DEMANGLE (OPTION_DEMANGLE + 1) + +static struct option long_options[] = +{ + {"line", no_argument, 0, 'l'}, + {"no-static", no_argument, 0, 'a'}, + {"ignore-non-functions", no_argument, 0, 'D'}, + + /* output styles: */ + + {"annotated-source", optional_argument, 0, 'A'}, + {"no-annotated-source", optional_argument, 0, 'J'}, + {"flat-profile", optional_argument, 0, 'p'}, + {"no-flat-profile", optional_argument, 0, 'P'}, + {"graph", optional_argument, 0, 'q'}, + {"no-graph", optional_argument, 0, 'Q'}, + {"exec-counts", optional_argument, 0, 'C'}, + {"no-exec-counts", optional_argument, 0, 'Z'}, + {"function-ordering", no_argument, 0, 'r'}, + {"file-ordering", required_argument, 0, 'R'}, + {"file-info", no_argument, 0, 'i'}, + {"sum", no_argument, 0, 's'}, + + /* various options to affect output: */ + + {"all-lines", no_argument, 0, 'x'}, + {"demangle", optional_argument, 0, OPTION_DEMANGLE}, + {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLE}, + {"directory-path", required_argument, 0, 'I'}, + {"display-unused-functions", no_argument, 0, 'z'}, + {"min-count", required_argument, 0, 'm'}, + {"print-path", no_argument, 0, 'L'}, + {"separate-files", no_argument, 0, 'y'}, + {"static-call-graph", no_argument, 0, 'c'}, + {"table-length", required_argument, 0, 't'}, + {"time", required_argument, 0, 'n'}, + {"no-time", required_argument, 0, 'N'}, + {"width", required_argument, 0, 'w'}, + /* + * These are for backwards-compatibility only. Their functionality + * is provided by the output style options already: + */ + {"", required_argument, 0, 'e'}, + {"", required_argument, 0, 'E'}, + {"", required_argument, 0, 'f'}, + {"", required_argument, 0, 'F'}, + {"", required_argument, 0, 'k'}, + + /* miscellaneous: */ + + {"brief", no_argument, 0, 'b'}, + {"debug", optional_argument, 0, 'd'}, + {"help", no_argument, 0, 'h'}, + {"file-format", required_argument, 0, 'O'}, + {"traditional", no_argument, 0, 'T'}, + {"version", no_argument, 0, 'v'}, + {0, no_argument, 0, 0} +}; + + +static void +usage (stream, status) + FILE *stream; + int status; +{ + fprintf (stream, _("\ +Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\ + [-d[num]] [-k from/to] [-m min-count] [-t table-length]\n\ + [--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n\ + [--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n\ + [--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n\ + [--function-ordering] [--file-ordering]\n\ + [--directory-path=dirs] [--display-unused-functions]\n\ + [--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n\ + [--no-static] [--print-path] [--separate-files]\n\ + [--static-call-graph] [--sum] [--table-length=len] [--traditional]\n\ + [--version] [--width=n] [--ignore-non-functions]\n\ + [--demangle[=STYLE]] [--no-demangle]\n\ + [image-file] [profile-file...]\n"), + whoami); + if (status == 0) + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); + done (status); +} + + +int +main (argc, argv) + int argc; + char **argv; +{ + char **sp, *str; + Sym **cg = 0; + int ch, user_specified = 0; + +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_MESSAGES, ""); +#endif +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + whoami = argv[0]; + xmalloc_set_program_name (whoami); + + while ((ch = getopt_long (argc, argv, + "aA::bBcCd::De:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::", + long_options, 0)) + != EOF) + { + switch (ch) + { + case 'a': + ignore_static_funcs = TRUE; + break; + case 'A': + if (optarg) + { + sym_id_add (optarg, INCL_ANNO); + } + output_style |= STYLE_ANNOTATED_SOURCE; + user_specified |= STYLE_ANNOTATED_SOURCE; + break; + case 'b': + print_descriptions = FALSE; + break; + case 'B': + output_style |= STYLE_CALL_GRAPH; + user_specified |= STYLE_CALL_GRAPH; + break; + case 'c': + ignore_direct_calls = TRUE; + break; + case 'C': + if (optarg) + { + sym_id_add (optarg, INCL_EXEC); + } + output_style |= STYLE_EXEC_COUNTS; + user_specified |= STYLE_EXEC_COUNTS; + break; + case 'd': + if (optarg) + { + debug_level |= atoi (optarg); + debug_level |= ANYDEBUG; + } + else + { + debug_level = ~0; + } + DBG (ANYDEBUG, printf ("[main] debug-level=0x%x\n", debug_level)); +#ifndef DEBUG + printf (_("%s: debugging not supported; -d ignored\n"), whoami); +#endif /* DEBUG */ + break; + case 'D': + ignore_non_functions = TRUE; + break; + case 'E': + sym_id_add (optarg, EXCL_TIME); + case 'e': + sym_id_add (optarg, EXCL_GRAPH); + break; + case 'F': + sym_id_add (optarg, INCL_TIME); + case 'f': + sym_id_add (optarg, INCL_GRAPH); + break; + case 'g': + sym_id_add (optarg, EXCL_FLAT); + break; + case 'G': + sym_id_add (optarg, INCL_FLAT); + break; + case 'h': + usage (stdout, 0); + case 'i': + output_style |= STYLE_GMON_INFO; + user_specified |= STYLE_GMON_INFO; + break; + case 'I': + search_list_append (&src_search_list, optarg); + break; + case 'J': + if (optarg) + { + sym_id_add (optarg, EXCL_ANNO); + output_style |= STYLE_ANNOTATED_SOURCE; + } + else + { + output_style &= ~STYLE_ANNOTATED_SOURCE; + } + user_specified |= STYLE_ANNOTATED_SOURCE; + break; + case 'k': + sym_id_add (optarg, EXCL_ARCS); + break; + case 'l': + line_granularity = TRUE; + break; + case 'L': + print_path = TRUE; + break; + case 'm': + bb_min_calls = (unsigned long) strtoul (optarg, (char **) NULL, 10); + break; + case 'n': + sym_id_add (optarg, INCL_TIME); + break; + case 'N': + sym_id_add (optarg, EXCL_TIME); + break; + case 'O': + switch (optarg[0]) + { + case 'a': + file_format = FF_AUTO; + break; + case 'm': + file_format = FF_MAGIC; + break; + case 'b': + file_format = FF_BSD; + break; + case '4': + file_format = FF_BSD44; + break; + case 'p': + file_format = FF_PROF; + break; + default: + fprintf (stderr, _("%s: unknown file format %s\n"), + optarg, whoami); + done (1); + } + break; + case 'p': + if (optarg) + { + sym_id_add (optarg, INCL_FLAT); + } + output_style |= STYLE_FLAT_PROFILE; + user_specified |= STYLE_FLAT_PROFILE; + break; + case 'P': + if (optarg) + { + sym_id_add (optarg, EXCL_FLAT); + output_style |= STYLE_FLAT_PROFILE; + } + else + { + output_style &= ~STYLE_FLAT_PROFILE; + } + user_specified |= STYLE_FLAT_PROFILE; + break; + case 'q': + if (optarg) + { + if (strchr (optarg, '/')) + { + sym_id_add (optarg, INCL_ARCS); + } + else + { + sym_id_add (optarg, INCL_GRAPH); + } + } + output_style |= STYLE_CALL_GRAPH; + user_specified |= STYLE_CALL_GRAPH; + break; + case 'r': + output_style |= STYLE_FUNCTION_ORDER; + user_specified |= STYLE_FUNCTION_ORDER; + break; + case 'R': + output_style |= STYLE_FILE_ORDER; + user_specified |= STYLE_FILE_ORDER; + function_mapping_file = optarg; + break; + case 'Q': + if (optarg) + { + if (strchr (optarg, '/')) + { + sym_id_add (optarg, EXCL_ARCS); + } + else + { + sym_id_add (optarg, EXCL_GRAPH); + } + output_style |= STYLE_CALL_GRAPH; + } + else + { + output_style &= ~STYLE_CALL_GRAPH; + } + user_specified |= STYLE_CALL_GRAPH; + break; + case 's': + output_style |= STYLE_SUMMARY_FILE; + user_specified |= STYLE_SUMMARY_FILE; + break; + case 't': + bb_table_length = atoi (optarg); + if (bb_table_length < 0) + { + bb_table_length = 0; + } + break; + case 'T': + bsd_style_output = TRUE; + break; + case 'v': + /* This output is intended to follow the GNU standards document. */ + printf (_("GNU gprof %s\n"), VERSION); + printf (_("Based on BSD gprof, copyright 1983 Regents of the University of California.\n")); + printf (_("\ +This program is free software. This program has absolutely no warranty.\n")); + done (0); + case 'w': + output_width = atoi (optarg); + if (output_width < 1) + { + output_width = 1; + } + break; + case 'x': + bb_annotate_all_lines = TRUE; + break; + case 'y': + create_annotation_files = TRUE; + break; + case 'z': + ignore_zeros = FALSE; + break; + case 'Z': + if (optarg) + { + sym_id_add (optarg, EXCL_EXEC); + output_style |= STYLE_EXEC_COUNTS; + } + else + { + output_style &= ~STYLE_EXEC_COUNTS; + } + user_specified |= STYLE_ANNOTATED_SOURCE; + break; + case OPTION_DEMANGLE: + demangle = TRUE; + if (optarg != NULL) + { + enum demangling_styles style; + + style = cplus_demangle_name_to_style (optarg); + if (style == unknown_demangling) + { + fprintf (stderr, + _("%s: unknown demangling style `%s'\n"), + whoami, optarg); + xexit (1); + } + + cplus_demangle_set_style (style); + } + break; + case OPTION_NO_DEMANGLE: + demangle = FALSE; + break; + default: + usage (stderr, 1); + } + } + + /* Don't allow both ordering options, they modify the arc data in-place. */ + if ((user_specified & STYLE_FUNCTION_ORDER) + && (user_specified & STYLE_FILE_ORDER)) + { + fprintf (stderr,_("\ +%s: Only one of --function-ordering and --file-ordering may be specified.\n"), + whoami); + done (1); + } + + /* --sum implies --line, otherwise we'd lose b-b counts in gmon.sum */ + if (output_style & STYLE_SUMMARY_FILE) + { + line_granularity = 1; + } + + /* append value of GPROF_PATH to source search list if set: */ + str = (char *) getenv ("GPROF_PATH"); + if (str) + { + search_list_append (&src_search_list, str); + } + + if (optind < argc) + { + a_out_name = argv[optind++]; + } + if (optind < argc) + { + gmon_name = argv[optind++]; + } + + /* + * Turn off default functions: + */ + for (sp = &default_excluded_list[0]; *sp; sp++) + { + sym_id_add (*sp, EXCL_TIME); + sym_id_add (*sp, EXCL_GRAPH); + sym_id_add (*sp, EXCL_FLAT); + } + + /* + * For line-by-line profiling, also want to keep those + * functions off the flat profile: + */ + if (line_granularity) + { + for (sp = &default_excluded_list[0]; *sp; sp++) + { + sym_id_add (*sp, EXCL_FLAT); + } + } + + /* + * Read symbol table from core file: + */ + core_init (a_out_name); + + /* + * If we should ignore direct function calls, we need to load + * to core's text-space: + */ + if (ignore_direct_calls) + { + core_get_text_space (core_bfd); + } + + /* + * Create symbols from core image: + */ + if (line_granularity) + { + core_create_line_syms (core_bfd); + } + else + { + core_create_function_syms (core_bfd); + } + + /* + * Translate sym specs into syms: + */ + sym_id_parse (); + + if (file_format == FF_PROF) + { +#ifdef PROF_SUPPORT_IMPLEMENTED + /* + * Get information about mon.out file(s): + */ + do + { + mon_out_read (gmon_name); + if (optind < argc) + { + gmon_name = argv[optind]; + } + } + while (optind++ < argc); +#else + fprintf (stderr, + _("%s: sorry, file format `prof' is not yet supported\n"), + whoami); + done (1); +#endif + } + else + { + /* + * Get information about gmon.out file(s): + */ + do + { + gmon_out_read (gmon_name); + if (optind < argc) + { + gmon_name = argv[optind]; + } + } + while (optind++ < argc); + } + + /* + * If user did not specify output style, try to guess something + * reasonable: + */ + if (output_style == 0) + { + if (gmon_input & (INPUT_HISTOGRAM | INPUT_CALL_GRAPH)) + { + output_style = STYLE_FLAT_PROFILE | STYLE_CALL_GRAPH; + } + else + { + output_style = STYLE_EXEC_COUNTS; + } + output_style &= ~user_specified; + } + + /* + * Dump a gmon.sum file if requested (before any other processing!): + */ + if (output_style & STYLE_SUMMARY_FILE) + { + gmon_out_write (GMONSUM); + } + + if (gmon_input & INPUT_HISTOGRAM) + { + hist_assign_samples (); + } + + if (gmon_input & INPUT_CALL_GRAPH) + { + cg = cg_assemble (); + } + + /* do some simple sanity checks: */ + + if ((output_style & STYLE_FLAT_PROFILE) + && !(gmon_input & INPUT_HISTOGRAM)) + { + fprintf (stderr, _("%s: gmon.out file is missing histogram\n"), whoami); + done (1); + } + + if ((output_style & STYLE_CALL_GRAPH) && !(gmon_input & INPUT_CALL_GRAPH)) + { + fprintf (stderr, + _("%s: gmon.out file is missing call-graph data\n"), whoami); + done (1); + } + + /* output whatever user whishes to see: */ + + if (cg && (output_style & STYLE_CALL_GRAPH) && bsd_style_output) + { + cg_print (cg); /* print the dynamic profile */ + } + + if (output_style & STYLE_FLAT_PROFILE) + { + hist_print (); /* print the flat profile */ + } + + if (cg && (output_style & STYLE_CALL_GRAPH)) + { + if (!bsd_style_output) + { + cg_print (cg); /* print the dynamic profile */ + } + cg_print_index (); + } + + if (output_style & STYLE_EXEC_COUNTS) + { + print_exec_counts (); + } + + if (output_style & STYLE_ANNOTATED_SOURCE) + { + print_annotated_source (); + } + if (output_style & STYLE_FUNCTION_ORDER) + { + cg_print_function_ordering (); + } + if (output_style & STYLE_FILE_ORDER) + { + cg_print_file_ordering (); + } + return 0; +} + +void +done (status) + int status; +{ + exit (status); +} diff --git a/gprof/gprof.h b/gprof/gprof.h new file mode 100644 index 000000000000..b0679ff61d10 --- /dev/null +++ b/gprof/gprof.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef gprof_h +#define gprof_h + +/* Include the BFD sysdep.h file. */ +#include "sysdep.h" +#include "bfd.h" + +/* Undefine the BFD PACKAGE and VERSION macros before including the + gprof config.h file. */ +#undef PACKAGE +#undef VERSION + +#include "gconfig.h" + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/* AIX defines hz as a macro. */ +#undef hz + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#define A_OUTNAME "a.out" /* default core filename */ +#define GMONNAME "gmon.out" /* default profile filename */ +#define GMONSUM "gmon.sum" /* profile summary filename */ + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef ENABLE_NLS +/* Undefine BFD's `_' macro - it uses dgetext() and we want to use gettext(). */ +#undef _ +#define _(String) gettext (String) +#endif + +#include "bin-bugs.h" + +#define STYLE_FLAT_PROFILE (1<<0) +#define STYLE_CALL_GRAPH (1<<1) +#define STYLE_SUMMARY_FILE (1<<2) +#define STYLE_EXEC_COUNTS (1<<3) +#define STYLE_ANNOTATED_SOURCE (1<<4) +#define STYLE_GMON_INFO (1<<5) +#define STYLE_FUNCTION_ORDER (1<<6) +#define STYLE_FILE_ORDER (1<<7) + +#define ANYDEBUG (1<<0) /* 1 */ +#define DFNDEBUG (1<<1) /* 2 */ +#define CYCLEDEBUG (1<<2) /* 4 */ +#define ARCDEBUG (1<<3) /* 8 */ +#define TALLYDEBUG (1<<4) /* 16 */ +#define TIMEDEBUG (1<<5) /* 32 */ +#define SAMPLEDEBUG (1<<6) /* 64 */ +#define AOUTDEBUG (1<<7) /* 128 */ +#define CALLDEBUG (1<<8) /* 256 */ +#define LOOKUPDEBUG (1<<9) /* 512 */ +#define PROPDEBUG (1<<10) /* 1024 */ +#define BBDEBUG (1<<11) /* 2048 */ +#define IDDEBUG (1<<12) /* 4096 */ +#define SRCDEBUG (1<<13) /* 8192 */ + +#ifdef DEBUG +#define DBG(l,s) if (debug_level & (l)) {s;} +#else +#define DBG(l,s) +#endif + +typedef enum + { + FF_AUTO = 0, FF_MAGIC, FF_BSD, FF_BSD44, FF_PROF + } +File_Format; + +typedef unsigned char UNIT[2]; /* unit of profiling */ + +extern const char *whoami; /* command-name, for error messages */ +extern const char *function_mapping_file; /* file mapping functions to files */ +extern const char *a_out_name; /* core filename */ +extern long hz; /* ticks per second */ + +/* + * Command-line options: + */ +extern int debug_level; /* debug level */ +extern int output_style; +extern int output_width; /* controls column width in index */ +extern bfd_boolean bsd_style_output; /* as opposed to FSF style output */ +extern bfd_boolean demangle; /* demangle symbol names? */ +extern bfd_boolean discard_underscores; /* discard leading underscores? */ +extern bfd_boolean ignore_direct_calls; /* don't count direct calls */ +extern bfd_boolean ignore_static_funcs; /* suppress static functions */ +extern bfd_boolean ignore_zeros; /* ignore unused symbols/files */ +extern bfd_boolean line_granularity; /* function or line granularity? */ +extern bfd_boolean print_descriptions; /* output profile description */ +extern bfd_boolean print_path; /* print path or just filename? */ +extern bfd_boolean ignore_non_functions; /* Ignore non-function symbols. */ + +extern File_Format file_format; /* requested file format */ + +extern bfd_boolean first_output; /* no output so far? */ + +extern void done PARAMS ((int status)) ATTRIBUTE_NORETURN; + +#endif /* gprof_h */ diff --git a/gprof/gprof.info b/gprof/gprof.info new file mode 100644 index 000000000000..74e42d986e2e --- /dev/null +++ b/gprof/gprof.info @@ -0,0 +1,2300 @@ +This is gprof.info, produced by makeinfo version 4.6 from gprof.texi. + +START-INFO-DIR-ENTRY +* gprof: (gprof). Profiling your program's execution +END-INFO-DIR-ENTRY + + This file documents the gprof profiler of the GNU system. + + Copyright (C) 1988, 92, 97, 98, 99, 2000, 2001, 2003 Free Software +Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". + + +File: gprof.info, Node: Top, Next: Introduction, Up: (dir) + +Profiling a Program: Where Does It Spend Its Time? +************************************************** + +This manual describes the GNU profiler, `gprof', and how you can use it +to determine which parts of a program are taking most of the execution +time. We assume that you know how to write, compile, and execute +programs. GNU `gprof' was written by Jay Fenlason. + + This document is distributed under the terms of the GNU Free +Documentation License. A copy of the license is included in the +section entitled "GNU Free Documentation License". + +* Menu: + +* Introduction:: What profiling means, and why it is useful. + +* Compiling:: How to compile your program for profiling. +* Executing:: Executing your program to generate profile data +* Invoking:: How to run `gprof', and its options + +* Output:: Interpreting `gprof''s output + +* Inaccuracy:: Potential problems you should be aware of +* How do I?:: Answers to common questions +* Incompatibilities:: (between GNU `gprof' and Unix `gprof'.) +* Details:: Details of how profiling is done +* GNU Free Documentation License:: GNU Free Documentation License + + +File: gprof.info, Node: Introduction, Next: Compiling, Prev: Top, Up: Top + +Introduction to Profiling +************************* + +Profiling allows you to learn where your program spent its time and +which functions called which other functions while it was executing. +This information can show you which pieces of your program are slower +than you expected, and might be candidates for rewriting to make your +program execute faster. It can also tell you which functions are being +called more or less often than you expected. This may help you spot +bugs that had otherwise been unnoticed. + + Since the profiler uses information collected during the actual +execution of your program, it can be used on programs that are too +large or too complex to analyze by reading the source. However, how +your program is run will affect the information that shows up in the +profile data. If you don't use some feature of your program while it +is being profiled, no profile information will be generated for that +feature. + + Profiling has several steps: + + * You must compile and link your program with profiling enabled. + *Note Compiling::. + + * You must execute your program to generate a profile data file. + *Note Executing::. + + * You must run `gprof' to analyze the profile data. *Note + Invoking::. + + The next three chapters explain these steps in greater detail. + + Several forms of output are available from the analysis. + + The "flat profile" shows how much time your program spent in each +function, and how many times that function was called. If you simply +want to know which functions burn most of the cycles, it is stated +concisely here. *Note Flat Profile::. + + The "call graph" shows, for each function, which functions called +it, which other functions it called, and how many times. There is also +an estimate of how much time was spent in the subroutines of each +function. This can suggest places where you might try to eliminate +function calls that use a lot of time. *Note Call Graph::. + + The "annotated source" listing is a copy of the program's source +code, labeled with the number of times each line of the program was +executed. *Note Annotated Source::. + + To better understand how profiling works, you may wish to read a +description of its implementation. *Note Implementation::. + + +File: gprof.info, Node: Compiling, Next: Executing, Prev: Introduction, Up: Top + +Compiling a Program for Profiling +********************************* + +The first step in generating profile information for your program is to +compile and link it with profiling enabled. + + To compile a source file for profiling, specify the `-pg' option when +you run the compiler. (This is in addition to the options you normally +use.) + + To link the program for profiling, if you use a compiler such as `cc' +to do the linking, simply specify `-pg' in addition to your usual +options. The same option, `-pg', alters either compilation or linking +to do what is necessary for profiling. Here are examples: + + cc -g -c myprog.c utils.c -pg + cc -o myprog myprog.o utils.o -pg + + The `-pg' option also works with a command that both compiles and +links: + + cc -o myprog myprog.c utils.c -g -pg + + Note: The `-pg' option must be part of your compilation options as +well as your link options. If it is not then no call-graph data will +be gathered and when you run `gprof' you will get an error message like +this: + + gprof: gmon.out file is missing call-graph data + + If you add the `-Q' switch to suppress the printing of the call +graph data you will still be able to see the time samples: + + Flat profile: + + Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls Ts/call Ts/call name + 44.12 0.07 0.07 zazLoop + 35.29 0.14 0.06 main + 20.59 0.17 0.04 bazMillion + + % the percentage of the total running time of the + + If you run the linker `ld' directly instead of through a compiler +such as `cc', you may have to specify a profiling startup file +`gcrt0.o' as the first input file instead of the usual startup file +`crt0.o'. In addition, you would probably want to specify the +profiling C library, `libc_p.a', by writing `-lc_p' instead of the +usual `-lc'. This is not absolutely necessary, but doing this gives +you number-of-calls information for standard library functions such as +`read' and `open'. For example: + + ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p + + If you compile only some of the modules of the program with `-pg', +you can still profile the program, but you won't get complete +information about the modules that were compiled without `-pg'. The +only information you get for the functions in those modules is the +total time spent in them; there is no record of how many times they +were called, or from where. This will not affect the flat profile +(except that the `calls' field for the functions will be blank), but +will greatly reduce the usefulness of the call graph. + + If you wish to perform line-by-line profiling, you will also need to +specify the `-g' option, instructing the compiler to insert debugging +symbols into the program that match program addresses to source code +lines. *Note Line-by-line::. + + In addition to the `-pg' and `-g' options, older versions of GCC +required you to specify the `-a' option when compiling in order to +instrument it to perform basic-block counting. Newer versions do not +require this option and will not accept it; basic-block counting is +always enabled when `-pg' is on. + + When basic-block counting is enabled, as the program runs it will +count how many times it executed each branch of each `if' statement, +each iteration of each `do' loop, etc. This will enable `gprof' to +construct an annotated source code listing showing how many times each +line of code was executed. + + It also worth noting that GCC supports a different profiling method +which is enabled by the `-fprofile-arcs', `-ftest-coverage' and +`-fprofile-values' switches. These switches do not produce data which +is useful to `gprof' however, so they are not discussed further here. +There is also the `-finstrument-functions' switch which will cause GCC +to insert calls to special user supplied instrumentation routines at +the entry and exit of every function in their program. This can be +used to implement an alternative profiling scheme. + + +File: gprof.info, Node: Executing, Next: Invoking, Prev: Compiling, Up: Top + +Executing the Program +********************* + +Once the program is compiled for profiling, you must run it in order to +generate the information that `gprof' needs. Simply run the program as +usual, using the normal arguments, file names, etc. The program should +run normally, producing the same output as usual. It will, however, run +somewhat slower than normal because of the time spent collecting and the +writing the profile data. + + The way you run the program--the arguments and input that you give +it--may have a dramatic effect on what the profile information shows. +The profile data will describe the parts of the program that were +activated for the particular input you use. For example, if the first +command you give to your program is to quit, the profile data will show +the time used in initialization and in cleanup, but not much else. + + Your program will write the profile data into a file called +`gmon.out' just before exiting. If there is already a file called +`gmon.out', its contents are overwritten. There is currently no way to +tell the program to write the profile data under a different name, but +you can rename the file afterwards if you are concerned that it may be +overwritten. + + In order to write the `gmon.out' file properly, your program must +exit normally: by returning from `main' or by calling `exit'. Calling +the low-level function `_exit' does not write the profile data, and +neither does abnormal termination due to an unhandled signal. + + The `gmon.out' file is written in the program's _current working +directory_ at the time it exits. This means that if your program calls +`chdir', the `gmon.out' file will be left in the last directory your +program `chdir''d to. If you don't have permission to write in this +directory, the file is not written, and you will get an error message. + + Older versions of the GNU profiling library may also write a file +called `bb.out'. This file, if present, contains an human-readable +listing of the basic-block execution counts. Unfortunately, the +appearance of a human-readable `bb.out' means the basic-block counts +didn't get written into `gmon.out'. The Perl script `bbconv.pl', +included with the `gprof' source distribution, will convert a `bb.out' +file into a format readable by `gprof'. Invoke it like this: + + bbconv.pl < bb.out > BH-DATA + + This translates the information in `bb.out' into a form that `gprof' +can understand. But you still need to tell `gprof' about the existence +of this translated information. To do that, include BB-DATA on the +`gprof' command line, _along with `gmon.out'_, like this: + + gprof OPTIONS EXECUTABLE-FILE gmon.out BB-DATA [YET-MORE-PROFILE-DATA-FILES...] [> OUTFILE] + + +File: gprof.info, Node: Invoking, Next: Output, Prev: Executing, Up: Top + +`gprof' Command Summary +*********************** + +After you have a profile data file `gmon.out', you can run `gprof' to +interpret the information in it. The `gprof' program prints a flat +profile and a call graph on standard output. Typically you would +redirect the output of `gprof' into a file with `>'. + + You run `gprof' like this: + + gprof OPTIONS [EXECUTABLE-FILE [PROFILE-DATA-FILES...]] [> OUTFILE] + +Here square-brackets indicate optional arguments. + + If you omit the executable file name, the file `a.out' is used. If +you give no profile data file name, the file `gmon.out' is used. If +any file is not in the proper format, or if the profile data file does +not appear to belong to the executable file, an error message is +printed. + + You can give more than one profile data file by entering all their +names after the executable file name; then the statistics in all the +data files are summed together. + + The order of these options does not matter. + +* Menu: + +* Output Options:: Controlling `gprof''s output style +* Analysis Options:: Controlling how `gprof' analyses its data +* Miscellaneous Options:: +* Deprecated Options:: Options you no longer need to use, but which + have been retained for compatibility +* Symspecs:: Specifying functions to include or exclude + + +File: gprof.info, Node: Output Options, Next: Analysis Options, Up: Invoking + +Output Options +============== + +These options specify which of several output formats `gprof' should +produce. + + Many of these options take an optional "symspec" to specify +functions to be included or excluded. These options can be specified +multiple times, with different symspecs, to include or exclude sets of +symbols. *Note Symspecs::. + + Specifying any of these options overrides the default (`-p -q'), +which prints a flat profile and call graph analysis for all functions. + +`-A[SYMSPEC]' +`--annotated-source[=SYMSPEC]' + The `-A' option causes `gprof' to print annotated source code. If + SYMSPEC is specified, print output only for matching symbols. + *Note Annotated Source::. + +`-b' +`--brief' + If the `-b' option is given, `gprof' doesn't print the verbose + blurbs that try to explain the meaning of all of the fields in the + tables. This is useful if you intend to print out the output, or + are tired of seeing the blurbs. + +`-C[SYMSPEC]' +`--exec-counts[=SYMSPEC]' + The `-C' option causes `gprof' to print a tally of functions and + the number of times each was called. If SYMSPEC is specified, + print tally only for matching symbols. + + If the profile data file contains basic-block count records, + specifying the `-l' option, along with `-C', will cause basic-block + execution counts to be tallied and displayed. + +`-i' +`--file-info' + The `-i' option causes `gprof' to display summary information + about the profile data file(s) and then exit. The number of + histogram, call graph, and basic-block count records is displayed. + +`-I DIRS' +`--directory-path=DIRS' + The `-I' option specifies a list of search directories in which to + find source files. Environment variable GPROF_PATH can also be + used to convey this information. Used mostly for annotated source + output. + +`-J[SYMSPEC]' +`--no-annotated-source[=SYMSPEC]' + The `-J' option causes `gprof' not to print annotated source code. + If SYMSPEC is specified, `gprof' prints annotated source, but + excludes matching symbols. + +`-L' +`--print-path' + Normally, source filenames are printed with the path component + suppressed. The `-L' option causes `gprof' to print the full + pathname of source filenames, which is determined from symbolic + debugging information in the image file and is relative to the + directory in which the compiler was invoked. + +`-p[SYMSPEC]' +`--flat-profile[=SYMSPEC]' + The `-p' option causes `gprof' to print a flat profile. If + SYMSPEC is specified, print flat profile only for matching symbols. + *Note Flat Profile::. + +`-P[SYMSPEC]' +`--no-flat-profile[=SYMSPEC]' + The `-P' option causes `gprof' to suppress printing a flat profile. + If SYMSPEC is specified, `gprof' prints a flat profile, but + excludes matching symbols. + +`-q[SYMSPEC]' +`--graph[=SYMSPEC]' + The `-q' option causes `gprof' to print the call graph analysis. + If SYMSPEC is specified, print call graph only for matching symbols + and their children. *Note Call Graph::. + +`-Q[SYMSPEC]' +`--no-graph[=SYMSPEC]' + The `-Q' option causes `gprof' to suppress printing the call graph. + If SYMSPEC is specified, `gprof' prints a call graph, but excludes + matching symbols. + +`-y' +`--separate-files' + This option affects annotated source output only. Normally, + `gprof' prints annotated source files to standard-output. If this + option is specified, annotated source for a file named + `path/FILENAME' is generated in the file `FILENAME-ann'. If the + underlying filesystem would truncate `FILENAME-ann' so that it + overwrites the original `FILENAME', `gprof' generates annotated + source in the file `FILENAME.ann' instead (if the original file + name has an extension, that extension is _replaced_ with `.ann'). + +`-Z[SYMSPEC]' +`--no-exec-counts[=SYMSPEC]' + The `-Z' option causes `gprof' not to print a tally of functions + and the number of times each was called. If SYMSPEC is specified, + print tally, but exclude matching symbols. + +`--function-ordering' + The `--function-ordering' option causes `gprof' to print a + suggested function ordering for the program based on profiling + data. This option suggests an ordering which may improve paging, + tlb and cache behavior for the program on systems which support + arbitrary ordering of functions in an executable. + + The exact details of how to force the linker to place functions in + a particular order is system dependent and out of the scope of this + manual. + +`--file-ordering MAP_FILE' + The `--file-ordering' option causes `gprof' to print a suggested + .o link line ordering for the program based on profiling data. + This option suggests an ordering which may improve paging, tlb and + cache behavior for the program on systems which do not support + arbitrary ordering of functions in an executable. + + Use of the `-a' argument is highly recommended with this option. + + The MAP_FILE argument is a pathname to a file which provides + function name to object file mappings. The format of the file is + similar to the output of the program `nm'. + + c-parse.o:00000000 T yyparse + c-parse.o:00000004 C yyerrflag + c-lang.o:00000000 T maybe_objc_method_name + c-lang.o:00000000 T print_lang_statistics + c-lang.o:00000000 T recognize_objc_keyword + c-decl.o:00000000 T print_lang_identifier + c-decl.o:00000000 T print_lang_type + ... + + To create a MAP_FILE with GNU `nm', type a command like `nm + --extern-only --defined-only -v --print-file-name program-name'. + +`-T' +`--traditional' + The `-T' option causes `gprof' to print its output in + "traditional" BSD style. + +`-w WIDTH' +`--width=WIDTH' + Sets width of output lines to WIDTH. Currently only used when + printing the function index at the bottom of the call graph. + +`-x' +`--all-lines' + This option affects annotated source output only. By default, + only the lines at the beginning of a basic-block are annotated. + If this option is specified, every line in a basic-block is + annotated by repeating the annotation for the first line. This + behavior is similar to `tcov''s `-a'. + +`--demangle[=STYLE]' +`--no-demangle' + These options control whether C++ symbol names should be demangled + when printing output. The default is to demangle symbols. The + `--no-demangle' option may be used to turn off demangling. + Different compilers have different mangling styles. The optional + demangling style argument can be used to choose an appropriate + demangling style for your compiler. + + +File: gprof.info, Node: Analysis Options, Next: Miscellaneous Options, Prev: Output Options, Up: Invoking + +Analysis Options +================ + +`-a' +`--no-static' + The `-a' option causes `gprof' to suppress the printing of + statically declared (private) functions. (These are functions + whose names are not listed as global, and which are not visible + outside the file/function/block where they were defined.) Time + spent in these functions, calls to/from them, etc, will all be + attributed to the function that was loaded directly before it in + the executable file. This option affects both the flat profile + and the call graph. + +`-c' +`--static-call-graph' + The `-c' option causes the call graph of the program to be + augmented by a heuristic which examines the text space of the + object file and identifies function calls in the binary machine + code. Since normal call graph records are only generated when + functions are entered, this option identifies children that could + have been called, but never were. Calls to functions that were + not compiled with profiling enabled are also identified, but only + if symbol table entries are present for them. Calls to dynamic + library routines are typically _not_ found by this option. + Parents or children identified via this heuristic are indicated in + the call graph with call counts of `0'. + +`-D' +`--ignore-non-functions' + The `-D' option causes `gprof' to ignore symbols which are not + known to be functions. This option will give more accurate + profile data on systems where it is supported (Solaris and HPUX for + example). + +`-k FROM/TO' + The `-k' option allows you to delete from the call graph any arcs + from symbols matching symspec FROM to those matching symspec TO. + +`-l' +`--line' + The `-l' option enables line-by-line profiling, which causes + histogram hits to be charged to individual source code lines, + instead of functions. If the program was compiled with + basic-block counting enabled, this option will also identify how + many times each line of code was executed. While line-by-line + profiling can help isolate where in a large function a program is + spending its time, it also significantly increases the running + time of `gprof', and magnifies statistical inaccuracies. *Note + Sampling Error::. + +`-m NUM' +`--min-count=NUM' + This option affects execution count output only. Symbols that are + executed less than NUM times are suppressed. + +`-n[SYMSPEC]' +`--time[=SYMSPEC]' + The `-n' option causes `gprof', in its call graph analysis, to + only propagate times for symbols matching SYMSPEC. + +`-N[SYMSPEC]' +`--no-time[=SYMSPEC]' + The `-n' option causes `gprof', in its call graph analysis, not to + propagate times for symbols matching SYMSPEC. + +`-z' +`--display-unused-functions' + If you give the `-z' option, `gprof' will mention all functions in + the flat profile, even those that were never called, and that had + no time spent in them. This is useful in conjunction with the + `-c' option for discovering which routines were never called. + + + +File: gprof.info, Node: Miscellaneous Options, Next: Deprecated Options, Prev: Analysis Options, Up: Invoking + +Miscellaneous Options +===================== + +`-d[NUM]' +`--debug[=NUM]' + The `-d NUM' option specifies debugging options. If NUM is not + specified, enable all debugging. *Note Debugging::. + +`-ONAME' +`--file-format=NAME' + Selects the format of the profile data files. Recognized formats + are `auto' (the default), `bsd', `4.4bsd', `magic', and `prof' + (not yet supported). + +`-s' +`--sum' + The `-s' option causes `gprof' to summarize the information in the + profile data files it read in, and write out a profile data file + called `gmon.sum', which contains all the information from the + profile data files that `gprof' read in. The file `gmon.sum' may + be one of the specified input files; the effect of this is to + merge the data in the other input files into `gmon.sum'. + + Eventually you can run `gprof' again without `-s' to analyze the + cumulative data in the file `gmon.sum'. + +`-v' +`--version' + The `-v' flag causes `gprof' to print the current version number, + and then exit. + + + +File: gprof.info, Node: Deprecated Options, Next: Symspecs, Prev: Miscellaneous Options, Up: Invoking + +Deprecated Options +================== + + These options have been replaced with newer versions that use + symspecs. + +`-e FUNCTION_NAME' + The `-e FUNCTION' option tells `gprof' to not print information + about the function FUNCTION_NAME (and its children...) in the call + graph. The function will still be listed as a child of any + functions that call it, but its index number will be shown as + `[not printed]'. More than one `-e' option may be given; only one + FUNCTION_NAME may be indicated with each `-e' option. + +`-E FUNCTION_NAME' + The `-E FUNCTION' option works like the `-e' option, but time + spent in the function (and children who were not called from + anywhere else), will not be used to compute the + percentages-of-time for the call graph. More than one `-E' option + may be given; only one FUNCTION_NAME may be indicated with each + `-E' option. + +`-f FUNCTION_NAME' + The `-f FUNCTION' option causes `gprof' to limit the call graph to + the function FUNCTION_NAME and its children (and their + children...). More than one `-f' option may be given; only one + FUNCTION_NAME may be indicated with each `-f' option. + +`-F FUNCTION_NAME' + The `-F FUNCTION' option works like the `-f' option, but only time + spent in the function and its children (and their children...) + will be used to determine total-time and percentages-of-time for + the call graph. More than one `-F' option may be given; only one + FUNCTION_NAME may be indicated with each `-F' option. The `-F' + option overrides the `-E' option. + + + Note that only one function can be specified with each `-e', `-E', +`-f' or `-F' option. To specify more than one function, use multiple +options. For example, this command: + + gprof -e boring -f foo -f bar myprogram > gprof.output + +lists in the call graph all functions that were reached from either +`foo' or `bar' and were not reachable from `boring'. + + +File: gprof.info, Node: Symspecs, Prev: Deprecated Options, Up: Invoking + +Symspecs +======== + +Many of the output options allow functions to be included or excluded +using "symspecs" (symbol specifications), which observe the following +syntax: + + filename_containing_a_dot + | funcname_not_containing_a_dot + | linenumber + | ( [ any_filename ] `:' ( any_funcname | linenumber ) ) + + Here are some sample symspecs: + +`main.c' + Selects everything in file `main.c'--the dot in the string tells + `gprof' to interpret the string as a filename, rather than as a + function name. To select a file whose name does not contain a + dot, a trailing colon should be specified. For example, `odd:' is + interpreted as the file named `odd'. + +`main' + Selects all functions named `main'. + + Note that there may be multiple instances of the same function name + because some of the definitions may be local (i.e., static). + Unless a function name is unique in a program, you must use the + colon notation explained below to specify a function from a + specific source file. + + Sometimes, function names contain dots. In such cases, it is + necessary to add a leading colon to the name. For example, + `:.mul' selects function `.mul'. + + In some object file formats, symbols have a leading underscore. + `gprof' will normally not print these underscores. When you name a + symbol in a symspec, you should type it exactly as `gprof' prints + it in its output. For example, if the compiler produces a symbol + `_main' from your `main' function, `gprof' still prints it as + `main' in its output, so you should use `main' in symspecs. + +`main.c:main' + Selects function `main' in file `main.c'. + +`main.c:134' + Selects line 134 in file `main.c'. + + +File: gprof.info, Node: Output, Next: Inaccuracy, Prev: Invoking, Up: Top + +Interpreting `gprof''s Output +***************************** + +`gprof' can produce several different output styles, the most important +of which are described below. The simplest output styles (file +information, execution count, and function and file ordering) are not +described here, but are documented with the respective options that +trigger them. *Note Output Options::. + +* Menu: + +* Flat Profile:: The flat profile shows how much time was spent + executing directly in each function. +* Call Graph:: The call graph shows which functions called which + others, and how much time each function used + when its subroutine calls are included. +* Line-by-line:: `gprof' can analyze individual source code lines +* Annotated Source:: The annotated source listing displays source code + labeled with execution counts + + +File: gprof.info, Node: Flat Profile, Next: Call Graph, Up: Output + +The Flat Profile +================ + +The "flat profile" shows the total amount of time your program spent +executing each function. Unless the `-z' option is given, functions +with no apparent time spent in them, and no apparent calls to them, are +not mentioned. Note that if a function was not compiled for profiling, +and didn't run long enough to show up on the program counter histogram, +it will be indistinguishable from a function that was never called. + + This is part of a flat profile for a small program: + + Flat profile: + + Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 33.34 0.02 0.02 7208 0.00 0.00 open + 16.67 0.03 0.01 244 0.04 0.12 offtime + 16.67 0.04 0.01 8 1.25 1.25 memccpy + 16.67 0.05 0.01 7 1.43 1.43 write + 16.67 0.06 0.01 mcount + 0.00 0.06 0.00 236 0.00 0.00 tzset + 0.00 0.06 0.00 192 0.00 0.00 tolower + 0.00 0.06 0.00 47 0.00 0.00 strlen + 0.00 0.06 0.00 45 0.00 0.00 strchr + 0.00 0.06 0.00 1 0.00 50.00 main + 0.00 0.06 0.00 1 0.00 0.00 memcpy + 0.00 0.06 0.00 1 0.00 10.11 print + 0.00 0.06 0.00 1 0.00 0.00 profil + 0.00 0.06 0.00 1 0.00 50.00 report + ... + +The functions are sorted by first by decreasing run-time spent in them, +then by decreasing number of calls, then alphabetically by name. The +functions `mcount' and `profil' are part of the profiling apparatus and +appear in every flat profile; their time gives a measure of the amount +of overhead due to profiling. + + Just before the column headers, a statement appears indicating how +much time each sample counted as. This "sampling period" estimates the +margin of error in each of the time figures. A time figure that is not +much larger than this is not reliable. In this example, each sample +counted as 0.01 seconds, suggesting a 100 Hz sampling rate. The +program's total execution time was 0.06 seconds, as indicated by the +`cumulative seconds' field. Since each sample counted for 0.01 +seconds, this means only six samples were taken during the run. Two of +the samples occurred while the program was in the `open' function, as +indicated by the `self seconds' field. Each of the other four samples +occurred one each in `offtime', `memccpy', `write', and `mcount'. +Since only six samples were taken, none of these values can be regarded +as particularly reliable. In another run, the `self seconds' field for +`mcount' might well be `0.00' or `0.02'. *Note Sampling Error::, for a +complete discussion. + + The remaining functions in the listing (those whose `self seconds' +field is `0.00') didn't appear in the histogram samples at all. +However, the call graph indicated that they were called, so therefore +they are listed, sorted in decreasing order by the `calls' field. +Clearly some time was spent executing these functions, but the paucity +of histogram samples prevents any determination of how much time each +took. + + Here is what the fields in each line mean: + +`% time' + This is the percentage of the total execution time your program + spent in this function. These should all add up to 100%. + +`cumulative seconds' + This is the cumulative total number of seconds the computer spent + executing this functions, plus the time spent in all the functions + above this one in this table. + +`self seconds' + This is the number of seconds accounted for by this function alone. + The flat profile listing is sorted first by this number. + +`calls' + This is the total number of times the function was called. If the + function was never called, or the number of times it was called + cannot be determined (probably because the function was not + compiled with profiling enabled), the "calls" field is blank. + +`self ms/call' + This represents the average number of milliseconds spent in this + function per call, if this function is profiled. Otherwise, this + field is blank for this function. + +`total ms/call' + This represents the average number of milliseconds spent in this + function and its descendants per call, if this function is + profiled. Otherwise, this field is blank for this function. This + is the only field in the flat profile that uses call graph + analysis. + +`name' + This is the name of the function. The flat profile is sorted by + this field alphabetically after the "self seconds" and "calls" + fields are sorted. + + +File: gprof.info, Node: Call Graph, Next: Line-by-line, Prev: Flat Profile, Up: Output + +The Call Graph +============== + +The "call graph" shows how much time was spent in each function and its +children. From this information, you can find functions that, while +they themselves may not have used much time, called other functions +that did use unusual amounts of time. + + Here is a sample call from a small program. This call came from the +same `gprof' run as the flat profile example in the previous chapter. + + granularity: each sample hit covers 2 byte(s) for 20.00% of 0.05 seconds + + index % time self children called name + <spontaneous> + [1] 100.0 0.00 0.05 start [1] + 0.00 0.05 1/1 main [2] + 0.00 0.00 1/2 on_exit [28] + 0.00 0.00 1/1 exit [59] + ----------------------------------------------- + 0.00 0.05 1/1 start [1] + [2] 100.0 0.00 0.05 1 main [2] + 0.00 0.05 1/1 report [3] + ----------------------------------------------- + 0.00 0.05 1/1 main [2] + [3] 100.0 0.00 0.05 1 report [3] + 0.00 0.03 8/8 timelocal [6] + 0.00 0.01 1/1 print [9] + 0.00 0.01 9/9 fgets [12] + 0.00 0.00 12/34 strncmp <cycle 1> [40] + 0.00 0.00 8/8 lookup [20] + 0.00 0.00 1/1 fopen [21] + 0.00 0.00 8/8 chewtime [24] + 0.00 0.00 8/16 skipspace [44] + ----------------------------------------------- + [4] 59.8 0.01 0.02 8+472 <cycle 2 as a whole> [4] + 0.01 0.02 244+260 offtime <cycle 2> [7] + 0.00 0.00 236+1 tzset <cycle 2> [26] + ----------------------------------------------- + + The lines full of dashes divide this table into "entries", one for +each function. Each entry has one or more lines. + + In each entry, the primary line is the one that starts with an index +number in square brackets. The end of this line says which function +the entry is for. The preceding lines in the entry describe the +callers of this function and the following lines describe its +subroutines (also called "children" when we speak of the call graph). + + The entries are sorted by time spent in the function and its +subroutines. + + The internal profiling function `mcount' (*note Flat Profile::) is +never mentioned in the call graph. + +* Menu: + +* Primary:: Details of the primary line's contents. +* Callers:: Details of caller-lines' contents. +* Subroutines:: Details of subroutine-lines' contents. +* Cycles:: When there are cycles of recursion, + such as `a' calls `b' calls `a'... + + +File: gprof.info, Node: Primary, Next: Callers, Up: Call Graph + +The Primary Line +---------------- + +The "primary line" in a call graph entry is the line that describes the +function which the entry is about and gives the overall statistics for +this function. + + For reference, we repeat the primary line from the entry for function +`report' in our main example, together with the heading line that shows +the names of the fields: + + index % time self children called name + ... + [3] 100.0 0.00 0.05 1 report [3] + + Here is what the fields in the primary line mean: + +`index' + Entries are numbered with consecutive integers. Each function + therefore has an index number, which appears at the beginning of + its primary line. + + Each cross-reference to a function, as a caller or subroutine of + another, gives its index number as well as its name. The index + number guides you if you wish to look for the entry for that + function. + +`% time' + This is the percentage of the total time that was spent in this + function, including time spent in subroutines called from this + function. + + The time spent in this function is counted again for the callers of + this function. Therefore, adding up these percentages is + meaningless. + +`self' + This is the total amount of time spent in this function. This + should be identical to the number printed in the `seconds' field + for this function in the flat profile. + +`children' + This is the total amount of time spent in the subroutine calls + made by this function. This should be equal to the sum of all the + `self' and `children' entries of the children listed directly + below this function. + +`called' + This is the number of times the function was called. + + If the function called itself recursively, there are two numbers, + separated by a `+'. The first number counts non-recursive calls, + and the second counts recursive calls. + + In the example above, the function `report' was called once from + `main'. + +`name' + This is the name of the current function. The index number is + repeated after it. + + If the function is part of a cycle of recursion, the cycle number + is printed between the function's name and the index number (*note + Cycles::). For example, if function `gnurr' is part of cycle + number one, and has index number twelve, its primary line would be + end like this: + + gnurr <cycle 1> [12] + + +File: gprof.info, Node: Callers, Next: Subroutines, Prev: Primary, Up: Call Graph + +Lines for a Function's Callers +------------------------------ + +A function's entry has a line for each function it was called by. +These lines' fields correspond to the fields of the primary line, but +their meanings are different because of the difference in context. + + For reference, we repeat two lines from the entry for the function +`report', the primary line and one caller-line preceding it, together +with the heading line that shows the names of the fields: + + index % time self children called name + ... + 0.00 0.05 1/1 main [2] + [3] 100.0 0.00 0.05 1 report [3] + + Here are the meanings of the fields in the caller-line for `report' +called from `main': + +`self' + An estimate of the amount of time spent in `report' itself when it + was called from `main'. + +`children' + An estimate of the amount of time spent in subroutines of `report' + when `report' was called from `main'. + + The sum of the `self' and `children' fields is an estimate of the + amount of time spent within calls to `report' from `main'. + +`called' + Two numbers: the number of times `report' was called from `main', + followed by the total number of non-recursive calls to `report' + from all its callers. + +`name and index number' + The name of the caller of `report' to which this line applies, + followed by the caller's index number. + + Not all functions have entries in the call graph; some options to + `gprof' request the omission of certain functions. When a caller + has no entry of its own, it still has caller-lines in the entries + of the functions it calls. + + If the caller is part of a recursion cycle, the cycle number is + printed between the name and the index number. + + If the identity of the callers of a function cannot be determined, a +dummy caller-line is printed which has `<spontaneous>' as the "caller's +name" and all other fields blank. This can happen for signal handlers. + + +File: gprof.info, Node: Subroutines, Next: Cycles, Prev: Callers, Up: Call Graph + +Lines for a Function's Subroutines +---------------------------------- + +A function's entry has a line for each of its subroutines--in other +words, a line for each other function that it called. These lines' +fields correspond to the fields of the primary line, but their meanings +are different because of the difference in context. + + For reference, we repeat two lines from the entry for the function +`main', the primary line and a line for a subroutine, together with the +heading line that shows the names of the fields: + + index % time self children called name + ... + [2] 100.0 0.00 0.05 1 main [2] + 0.00 0.05 1/1 report [3] + + Here are the meanings of the fields in the subroutine-line for `main' +calling `report': + +`self' + An estimate of the amount of time spent directly within `report' + when `report' was called from `main'. + +`children' + An estimate of the amount of time spent in subroutines of `report' + when `report' was called from `main'. + + The sum of the `self' and `children' fields is an estimate of the + total time spent in calls to `report' from `main'. + +`called' + Two numbers, the number of calls to `report' from `main' followed + by the total number of non-recursive calls to `report'. This + ratio is used to determine how much of `report''s `self' and + `children' time gets credited to `main'. *Note Assumptions::. + +`name' + The name of the subroutine of `main' to which this line applies, + followed by the subroutine's index number. + + If the caller is part of a recursion cycle, the cycle number is + printed between the name and the index number. + + +File: gprof.info, Node: Cycles, Prev: Subroutines, Up: Call Graph + +How Mutually Recursive Functions Are Described +---------------------------------------------- + +The graph may be complicated by the presence of "cycles of recursion" +in the call graph. A cycle exists if a function calls another function +that (directly or indirectly) calls (or appears to call) the original +function. For example: if `a' calls `b', and `b' calls `a', then `a' +and `b' form a cycle. + + Whenever there are call paths both ways between a pair of functions, +they belong to the same cycle. If `a' and `b' call each other and `b' +and `c' call each other, all three make one cycle. Note that even if +`b' only calls `a' if it was not called from `a', `gprof' cannot +determine this, so `a' and `b' are still considered a cycle. + + The cycles are numbered with consecutive integers. When a function +belongs to a cycle, each time the function name appears in the call +graph it is followed by `<cycle NUMBER>'. + + The reason cycles matter is that they make the time values in the +call graph paradoxical. The "time spent in children" of `a' should +include the time spent in its subroutine `b' and in `b''s +subroutines--but one of `b''s subroutines is `a'! How much of `a''s +time should be included in the children of `a', when `a' is indirectly +recursive? + + The way `gprof' resolves this paradox is by creating a single entry +for the cycle as a whole. The primary line of this entry describes the +total time spent directly in the functions of the cycle. The +"subroutines" of the cycle are the individual functions of the cycle, +and all other functions that were called directly by them. The +"callers" of the cycle are the functions, outside the cycle, that +called functions in the cycle. + + Here is an example portion of a call graph which shows a cycle +containing functions `a' and `b'. The cycle was entered by a call to +`a' from `main'; both `a' and `b' called `c'. + + index % time self children called name + ---------------------------------------- + 1.77 0 1/1 main [2] + [3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3] + 1.02 0 3 b <cycle 1> [4] + 0.75 0 2 a <cycle 1> [5] + ---------------------------------------- + 3 a <cycle 1> [5] + [4] 52.85 1.02 0 0 b <cycle 1> [4] + 2 a <cycle 1> [5] + 0 0 3/6 c [6] + ---------------------------------------- + 1.77 0 1/1 main [2] + 2 b <cycle 1> [4] + [5] 38.86 0.75 0 1 a <cycle 1> [5] + 3 b <cycle 1> [4] + 0 0 3/6 c [6] + ---------------------------------------- + +(The entire call graph for this program contains in addition an entry +for `main', which calls `a', and an entry for `c', with callers `a' and +`b'.) + + index % time self children called name + <spontaneous> + [1] 100.00 0 1.93 0 start [1] + 0.16 1.77 1/1 main [2] + ---------------------------------------- + 0.16 1.77 1/1 start [1] + [2] 100.00 0.16 1.77 1 main [2] + 1.77 0 1/1 a <cycle 1> [5] + ---------------------------------------- + 1.77 0 1/1 main [2] + [3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3] + 1.02 0 3 b <cycle 1> [4] + 0.75 0 2 a <cycle 1> [5] + 0 0 6/6 c [6] + ---------------------------------------- + 3 a <cycle 1> [5] + [4] 52.85 1.02 0 0 b <cycle 1> [4] + 2 a <cycle 1> [5] + 0 0 3/6 c [6] + ---------------------------------------- + 1.77 0 1/1 main [2] + 2 b <cycle 1> [4] + [5] 38.86 0.75 0 1 a <cycle 1> [5] + 3 b <cycle 1> [4] + 0 0 3/6 c [6] + ---------------------------------------- + 0 0 3/6 b <cycle 1> [4] + 0 0 3/6 a <cycle 1> [5] + [6] 0.00 0 0 6 c [6] + ---------------------------------------- + + The `self' field of the cycle's primary line is the total time spent +in all the functions of the cycle. It equals the sum of the `self' +fields for the individual functions in the cycle, found in the entry in +the subroutine lines for these functions. + + The `children' fields of the cycle's primary line and subroutine +lines count only subroutines outside the cycle. Even though `a' calls +`b', the time spent in those calls to `b' is not counted in `a''s +`children' time. Thus, we do not encounter the problem of what to do +when the time in those calls to `b' includes indirect recursive calls +back to `a'. + + The `children' field of a caller-line in the cycle's entry estimates +the amount of time spent _in the whole cycle_, and its other +subroutines, on the times when that caller called a function in the +cycle. + + The `calls' field in the primary line for the cycle has two numbers: +first, the number of times functions in the cycle were called by +functions outside the cycle; second, the number of times they were +called by functions in the cycle (including times when a function in +the cycle calls itself). This is a generalization of the usual split +into non-recursive and recursive calls. + + The `calls' field of a subroutine-line for a cycle member in the +cycle's entry says how many time that function was called from +functions in the cycle. The total of all these is the second number in +the primary line's `calls' field. + + In the individual entry for a function in a cycle, the other +functions in the same cycle can appear as subroutines and as callers. +These lines show how many times each function in the cycle called or +was called from each other function in the cycle. The `self' and +`children' fields in these lines are blank because of the difficulty of +defining meanings for them when recursion is going on. + + +File: gprof.info, Node: Line-by-line, Next: Annotated Source, Prev: Call Graph, Up: Output + +Line-by-line Profiling +====================== + +`gprof''s `-l' option causes the program to perform "line-by-line" +profiling. In this mode, histogram samples are assigned not to +functions, but to individual lines of source code. The program usually +must be compiled with a `-g' option, in addition to `-pg', in order to +generate debugging symbols for tracking source code lines. + + The flat profile is the most useful output table in line-by-line +mode. The call graph isn't as useful as normal, since the current +version of `gprof' does not propagate call graph arcs from source code +lines to the enclosing function. The call graph does, however, show +each line of code that called each function, along with a count. + + Here is a section of `gprof''s output, without line-by-line +profiling. Note that `ct_init' accounted for four histogram hits, and +13327 calls to `init_block'. + + Flat profile: + + Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls us/call us/call name + 30.77 0.13 0.04 6335 6.31 6.31 ct_init + + + Call graph (explanation follows) + + + granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds + + index % time self children called name + + 0.00 0.00 1/13496 name_too_long + 0.00 0.00 40/13496 deflate + 0.00 0.00 128/13496 deflate_fast + 0.00 0.00 13327/13496 ct_init + [7] 0.0 0.00 0.00 13496 init_block + + Now let's look at some of `gprof''s output from the same program run, +this time with line-by-line profiling enabled. Note that `ct_init''s +four histogram hits are broken down into four lines of source code - +one hit occurred on each of lines 349, 351, 382 and 385. In the call +graph, note how `ct_init''s 13327 calls to `init_block' are broken down +into one call from line 396, 3071 calls from line 384, 3730 calls from +line 385, and 6525 calls from 387. + + Flat profile: + + Each sample counts as 0.01 seconds. + % cumulative self + time seconds seconds calls name + 7.69 0.10 0.01 ct_init (trees.c:349) + 7.69 0.11 0.01 ct_init (trees.c:351) + 7.69 0.12 0.01 ct_init (trees.c:382) + 7.69 0.13 0.01 ct_init (trees.c:385) + + + Call graph (explanation follows) + + + granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds + + % time self children called name + + 0.00 0.00 1/13496 name_too_long (gzip.c:1440) + 0.00 0.00 1/13496 deflate (deflate.c:763) + 0.00 0.00 1/13496 ct_init (trees.c:396) + 0.00 0.00 2/13496 deflate (deflate.c:727) + 0.00 0.00 4/13496 deflate (deflate.c:686) + 0.00 0.00 5/13496 deflate (deflate.c:675) + 0.00 0.00 12/13496 deflate (deflate.c:679) + 0.00 0.00 16/13496 deflate (deflate.c:730) + 0.00 0.00 128/13496 deflate_fast (deflate.c:654) + 0.00 0.00 3071/13496 ct_init (trees.c:384) + 0.00 0.00 3730/13496 ct_init (trees.c:385) + 0.00 0.00 6525/13496 ct_init (trees.c:387) + [6] 0.0 0.00 0.00 13496 init_block (trees.c:408) + + +File: gprof.info, Node: Annotated Source, Prev: Line-by-line, Up: Output + +The Annotated Source Listing +============================ + +`gprof''s `-A' option triggers an annotated source listing, which lists +the program's source code, each function labeled with the number of +times it was called. You may also need to specify the `-I' option, if +`gprof' can't find the source code files. + + Compiling with `gcc ... -g -pg -a' augments your program with +basic-block counting code, in addition to function counting code. This +enables `gprof' to determine how many times each line of code was +executed. For example, consider the following function, taken from +gzip, with line numbers added: + + 1 ulg updcrc(s, n) + 2 uch *s; + 3 unsigned n; + 4 { + 5 register ulg c; + 6 + 7 static ulg crc = (ulg)0xffffffffL; + 8 + 9 if (s == NULL) { + 10 c = 0xffffffffL; + 11 } else { + 12 c = crc; + 13 if (n) do { + 14 c = crc_32_tab[...]; + 15 } while (--n); + 16 } + 17 crc = c; + 18 return c ^ 0xffffffffL; + 19 } + + `updcrc' has at least five basic-blocks. One is the function +itself. The `if' statement on line 9 generates two more basic-blocks, +one for each branch of the `if'. A fourth basic-block results from the +`if' on line 13, and the contents of the `do' loop form the fifth +basic-block. The compiler may also generate additional basic-blocks to +handle various special cases. + + A program augmented for basic-block counting can be analyzed with +`gprof -l -A'. I also suggest use of the `-x' option, which ensures +that each line of code is labeled at least once. Here is `updcrc''s +annotated source listing for a sample `gzip' run: + + ulg updcrc(s, n) + uch *s; + unsigned n; + 2 ->{ + register ulg c; + + static ulg crc = (ulg)0xffffffffL; + + 2 -> if (s == NULL) { + 1 -> c = 0xffffffffL; + 1 -> } else { + 1 -> c = crc; + 1 -> if (n) do { + 26312 -> c = crc_32_tab[...]; + 26312,1,26311 -> } while (--n); + } + 2 -> crc = c; + 2 -> return c ^ 0xffffffffL; + 2 ->} + + In this example, the function was called twice, passing once through +each branch of the `if' statement. The body of the `do' loop was +executed a total of 26312 times. Note how the `while' statement is +annotated. It began execution 26312 times, once for each iteration +through the loop. One of those times (the last time) it exited, while +it branched back to the beginning of the loop 26311 times. + + +File: gprof.info, Node: Inaccuracy, Next: How do I?, Prev: Output, Up: Top + +Inaccuracy of `gprof' Output +**************************** + +* Menu: + +* Sampling Error:: Statistical margins of error +* Assumptions:: Estimating children times + + +File: gprof.info, Node: Sampling Error, Next: Assumptions, Up: Inaccuracy + +Statistical Sampling Error +========================== + +The run-time figures that `gprof' gives you are based on a sampling +process, so they are subject to statistical inaccuracy. If a function +runs only a small amount of time, so that on the average the sampling +process ought to catch that function in the act only once, there is a +pretty good chance it will actually find that function zero times, or +twice. + + By contrast, the number-of-calls and basic-block figures are derived +by counting, not sampling. They are completely accurate and will not +vary from run to run if your program is deterministic. + + The "sampling period" that is printed at the beginning of the flat +profile says how often samples are taken. The rule of thumb is that a +run-time figure is accurate if it is considerably bigger than the +sampling period. + + The actual amount of error can be predicted. For N samples, the +_expected_ error is the square-root of N. For example, if the sampling +period is 0.01 seconds and `foo''s run-time is 1 second, N is 100 +samples (1 second/0.01 seconds), sqrt(N) is 10 samples, so the expected +error in `foo''s run-time is 0.1 seconds (10*0.01 seconds), or ten +percent of the observed value. Again, if the sampling period is 0.01 +seconds and `bar''s run-time is 100 seconds, N is 10000 samples, +sqrt(N) is 100 samples, so the expected error in `bar''s run-time is 1 +second, or one percent of the observed value. It is likely to vary +this much _on the average_ from one profiling run to the next. +(_Sometimes_ it will vary more.) + + This does not mean that a small run-time figure is devoid of +information. If the program's _total_ run-time is large, a small +run-time for one function does tell you that that function used an +insignificant fraction of the whole program's time. Usually this means +it is not worth optimizing. + + One way to get more accuracy is to give your program more (but +similar) input data so it will take longer. Another way is to combine +the data from several runs, using the `-s' option of `gprof'. Here is +how: + + 1. Run your program once. + + 2. Issue the command `mv gmon.out gmon.sum'. + + 3. Run your program again, the same as before. + + 4. Merge the new data in `gmon.out' into `gmon.sum' with this command: + + gprof -s EXECUTABLE-FILE gmon.out gmon.sum + + 5. Repeat the last two steps as often as you wish. + + 6. Analyze the cumulative data using this command: + + gprof EXECUTABLE-FILE gmon.sum > OUTPUT-FILE + + +File: gprof.info, Node: Assumptions, Prev: Sampling Error, Up: Inaccuracy + +Estimating `children' Times +=========================== + +Some of the figures in the call graph are estimates--for example, the +`children' time values and all the time figures in caller and +subroutine lines. + + There is no direct information about these measurements in the +profile data itself. Instead, `gprof' estimates them by making an +assumption about your program that might or might not be true. + + The assumption made is that the average time spent in each call to +any function `foo' is not correlated with who called `foo'. If `foo' +used 5 seconds in all, and 2/5 of the calls to `foo' came from `a', +then `foo' contributes 2 seconds to `a''s `children' time, by +assumption. + + This assumption is usually true enough, but for some programs it is +far from true. Suppose that `foo' returns very quickly when its +argument is zero; suppose that `a' always passes zero as an argument, +while other callers of `foo' pass other arguments. In this program, +all the time spent in `foo' is in the calls from callers other than `a'. +But `gprof' has no way of knowing this; it will blindly and incorrectly +charge 2 seconds of time in `foo' to the children of `a'. + + We hope some day to put more complete data into `gmon.out', so that +this assumption is no longer needed, if we can figure out how. For the +nonce, the estimated figures are usually more useful than misleading. + + +File: gprof.info, Node: How do I?, Next: Incompatibilities, Prev: Inaccuracy, Up: Top + +Answers to Common Questions +*************************** + +How can I get more exact information about hot spots in my program? + Looking at the per-line call counts only tells part of the story. + Because `gprof' can only report call times and counts by function, + the best way to get finer-grained information on where the program + is spending its time is to re-factor large functions into sequences + of calls to smaller ones. Beware however that this can introduce + artifical hot spots since compiling with `-pg' adds a significant + overhead to function calls. An alternative solution is to use a + non-intrusive profiler, e.g. oprofile. + +How do I find which lines in my program were executed the most times? + Compile your program with basic-block counting enabled, run it, + then use the following pipeline: + + gprof -l -C OBJFILE | sort -k 3 -n -r + + This listing will show you the lines in your code executed most + often, but not necessarily those that consumed the most time. + +How do I find which lines in my program called a particular function? + Use `gprof -l' and lookup the function in the call graph. The + callers will be broken down by function and line number. + +How do I analyze a program that runs for less than a second? + Try using a shell script like this one: + + for i in `seq 1 100`; do + fastprog + mv gmon.out gmon.out.$i + done + + gprof -s fastprog gmon.out.* + + gprof fastprog gmon.sum + + If your program is completely deterministic, all the call counts + will be simple multiples of 100 (i.e. a function called once in + each run will appear with a call count of 100). + + + +File: gprof.info, Node: Incompatibilities, Next: Details, Prev: How do I?, Up: Top + +Incompatibilities with Unix `gprof' +*********************************** + +GNU `gprof' and Berkeley Unix `gprof' use the same data file +`gmon.out', and provide essentially the same information. But there +are a few differences. + + * GNU `gprof' uses a new, generalized file format with support for + basic-block execution counts and non-realtime histograms. A magic + cookie and version number allows `gprof' to easily identify new + style files. Old BSD-style files can still be read. *Note File + Format::. + + * For a recursive function, Unix `gprof' lists the function as a + parent and as a child, with a `calls' field that lists the number + of recursive calls. GNU `gprof' omits these lines and puts the + number of recursive calls in the primary line. + + * When a function is suppressed from the call graph with `-e', GNU + `gprof' still lists it as a subroutine of functions that call it. + + * GNU `gprof' accepts the `-k' with its argument in the form + `from/to', instead of `from to'. + + * In the annotated source listing, if there are multiple basic + blocks on the same line, GNU `gprof' prints all of their counts, + separated by commas. + + * The blurbs, field widths, and output formats are different. GNU + `gprof' prints blurbs after the tables, so that you can see the + tables without skipping the blurbs. + + +File: gprof.info, Node: Details, Next: GNU Free Documentation License, Prev: Incompatibilities, Up: Top + +Details of Profiling +******************** + +* Menu: + +* Implementation:: How a program collects profiling information +* File Format:: Format of `gmon.out' files +* Internals:: `gprof''s internal operation +* Debugging:: Using `gprof''s `-d' option + + +File: gprof.info, Node: Implementation, Next: File Format, Up: Details + +Implementation of Profiling +=========================== + +Profiling works by changing how every function in your program is +compiled so that when it is called, it will stash away some information +about where it was called from. From this, the profiler can figure out +what function called it, and can count how many times it was called. +This change is made by the compiler when your program is compiled with +the `-pg' option, which causes every function to call `mcount' (or +`_mcount', or `__mcount', depending on the OS and compiler) as one of +its first operations. + + The `mcount' routine, included in the profiling library, is +responsible for recording in an in-memory call graph table both its +parent routine (the child) and its parent's parent. This is typically +done by examining the stack frame to find both the address of the +child, and the return address in the original parent. Since this is a +very machine-dependent operation, `mcount' itself is typically a short +assembly-language stub routine that extracts the required information, +and then calls `__mcount_internal' (a normal C function) with two +arguments - `frompc' and `selfpc'. `__mcount_internal' is responsible +for maintaining the in-memory call graph, which records `frompc', +`selfpc', and the number of times each of these call arcs was traversed. + + GCC Version 2 provides a magical function +(`__builtin_return_address'), which allows a generic `mcount' function +to extract the required information from the stack frame. However, on +some architectures, most notably the SPARC, using this builtin can be +very computationally expensive, and an assembly language version of +`mcount' is used for performance reasons. + + Number-of-calls information for library routines is collected by +using a special version of the C library. The programs in it are the +same as in the usual C library, but they were compiled with `-pg'. If +you link your program with `gcc ... -pg', it automatically uses the +profiling version of the library. + + Profiling also involves watching your program as it runs, and +keeping a histogram of where the program counter happens to be every +now and then. Typically the program counter is looked at around 100 +times per second of run time, but the exact frequency may vary from +system to system. + + This is done is one of two ways. Most UNIX-like operating systems +provide a `profil()' system call, which registers a memory array with +the kernel, along with a scale factor that determines how the program's +address space maps into the array. Typical scaling values cause every +2 to 8 bytes of address space to map into a single array slot. On +every tick of the system clock (assuming the profiled program is +running), the value of the program counter is examined and the +corresponding slot in the memory array is incremented. Since this is +done in the kernel, which had to interrupt the process anyway to handle +the clock interrupt, very little additional system overhead is required. + + However, some operating systems, most notably Linux 2.0 (and +earlier), do not provide a `profil()' system call. On such a system, +arrangements are made for the kernel to periodically deliver a signal +to the process (typically via `setitimer()'), which then performs the +same operation of examining the program counter and incrementing a slot +in the memory array. Since this method requires a signal to be +delivered to user space every time a sample is taken, it uses +considerably more overhead than kernel-based profiling. Also, due to +the added delay required to deliver the signal, this method is less +accurate as well. + + A special startup routine allocates memory for the histogram and +either calls `profil()' or sets up a clock signal handler. This +routine (`monstartup') can be invoked in several ways. On Linux +systems, a special profiling startup file `gcrt0.o', which invokes +`monstartup' before `main', is used instead of the default `crt0.o'. +Use of this special startup file is one of the effects of using `gcc +... -pg' to link. On SPARC systems, no special startup files are used. +Rather, the `mcount' routine, when it is invoked for the first time +(typically when `main' is called), calls `monstartup'. + + If the compiler's `-a' option was used, basic-block counting is also +enabled. Each object file is then compiled with a static array of +counts, initially zero. In the executable code, every time a new +basic-block begins (i.e. when an `if' statement appears), an extra +instruction is inserted to increment the corresponding count in the +array. At compile time, a paired array was constructed that recorded +the starting address of each basic-block. Taken together, the two +arrays record the starting address of every basic-block, along with the +number of times it was executed. + + The profiling library also includes a function (`mcleanup') which is +typically registered using `atexit()' to be called as the program +exits, and is responsible for writing the file `gmon.out'. Profiling +is turned off, various headers are output, and the histogram is +written, followed by the call-graph arcs and the basic-block counts. + + The output from `gprof' gives no indication of parts of your program +that are limited by I/O or swapping bandwidth. This is because samples +of the program counter are taken at fixed intervals of the program's +run time. Therefore, the time measurements in `gprof' output say +nothing about time that your program was not running. For example, a +part of the program that creates so much data that it cannot all fit in +physical memory at once may run very slowly due to thrashing, but +`gprof' will say it uses little time. On the other hand, sampling by +run time has the advantage that the amount of load due to other users +won't directly affect the output you get. + + +File: gprof.info, Node: File Format, Next: Internals, Prev: Implementation, Up: Details + +Profiling Data File Format +========================== + +The old BSD-derived file format used for profile data does not contain a +magic cookie that allows to check whether a data file really is a +`gprof' file. Furthermore, it does not provide a version number, thus +rendering changes to the file format almost impossible. GNU `gprof' +uses a new file format that provides these features. For backward +compatibility, GNU `gprof' continues to support the old BSD-derived +format, but not all features are supported with it. For example, +basic-block execution counts cannot be accommodated by the old file +format. + + The new file format is defined in header file `gmon_out.h'. It +consists of a header containing the magic cookie and a version number, +as well as some spare bytes available for future extensions. All data +in a profile data file is in the native format of the target for which +the profile was collected. GNU `gprof' adapts automatically to the +byte-order in use. + + In the new file format, the header is followed by a sequence of +records. Currently, there are three different record types: histogram +records, call-graph arc records, and basic-block execution count +records. Each file can contain any number of each record type. When +reading a file, GNU `gprof' will ensure records of the same type are +compatible with each other and compute the union of all records. For +example, for basic-block execution counts, the union is simply the sum +of all execution counts for each basic-block. + +Histogram Records +----------------- + +Histogram records consist of a header that is followed by an array of +bins. The header contains the text-segment range that the histogram +spans, the size of the histogram in bytes (unlike in the old BSD +format, this does not include the size of the header), the rate of the +profiling clock, and the physical dimension that the bin counts +represent after being scaled by the profiling clock rate. The physical +dimension is specified in two parts: a long name of up to 15 characters +and a single character abbreviation. For example, a histogram +representing real-time would specify the long name as "seconds" and the +abbreviation as "s". This feature is useful for architectures that +support performance monitor hardware (which, fortunately, is becoming +increasingly common). For example, under DEC OSF/1, the "uprofile" +command can be used to produce a histogram of, say, instruction cache +misses. In this case, the dimension in the histogram header could be +set to "i-cache misses" and the abbreviation could be set to "1" +(because it is simply a count, not a physical dimension). Also, the +profiling rate would have to be set to 1 in this case. + + Histogram bins are 16-bit numbers and each bin represent an equal +amount of text-space. For example, if the text-segment is one thousand +bytes long and if there are ten bins in the histogram, each bin +represents one hundred bytes. + +Call-Graph Records +------------------ + +Call-graph records have a format that is identical to the one used in +the BSD-derived file format. It consists of an arc in the call graph +and a count indicating the number of times the arc was traversed during +program execution. Arcs are specified by a pair of addresses: the +first must be within caller's function and the second must be within +the callee's function. When performing profiling at the function +level, these addresses can point anywhere within the respective +function. However, when profiling at the line-level, it is better if +the addresses are as close to the call-site/entry-point as possible. +This will ensure that the line-level call-graph is able to identify +exactly which line of source code performed calls to a function. + +Basic-Block Execution Count Records +----------------------------------- + +Basic-block execution count records consist of a header followed by a +sequence of address/count pairs. The header simply specifies the +length of the sequence. In an address/count pair, the address +identifies a basic-block and the count specifies the number of times +that basic-block was executed. Any address within the basic-address can +be used. + + +File: gprof.info, Node: Internals, Next: Debugging, Prev: File Format, Up: Details + +`gprof''s Internal Operation +============================ + +Like most programs, `gprof' begins by processing its options. During +this stage, it may building its symspec list (`sym_ids.c:sym_id_add'), +if options are specified which use symspecs. `gprof' maintains a +single linked list of symspecs, which will eventually get turned into +12 symbol tables, organized into six include/exclude pairs - one pair +each for the flat profile (INCL_FLAT/EXCL_FLAT), the call graph arcs +(INCL_ARCS/EXCL_ARCS), printing in the call graph +(INCL_GRAPH/EXCL_GRAPH), timing propagation in the call graph +(INCL_TIME/EXCL_TIME), the annotated source listing +(INCL_ANNO/EXCL_ANNO), and the execution count listing +(INCL_EXEC/EXCL_EXEC). + + After option processing, `gprof' finishes building the symspec list +by adding all the symspecs in `default_excluded_list' to the exclude +lists EXCL_TIME and EXCL_GRAPH, and if line-by-line profiling is +specified, EXCL_FLAT as well. These default excludes are not added to +EXCL_ANNO, EXCL_ARCS, and EXCL_EXEC. + + Next, the BFD library is called to open the object file, verify that +it is an object file, and read its symbol table (`core.c:core_init'), +using `bfd_canonicalize_symtab' after mallocing an appropriately sized +array of symbols. At this point, function mappings are read (if the +`--file-ordering' option has been specified), and the core text space +is read into memory (if the `-c' option was given). + + `gprof''s own symbol table, an array of Sym structures, is now built. +This is done in one of two ways, by one of two routines, depending on +whether line-by-line profiling (`-l' option) has been enabled. For +normal profiling, the BFD canonical symbol table is scanned. For +line-by-line profiling, every text space address is examined, and a new +symbol table entry gets created every time the line number changes. In +either case, two passes are made through the symbol table - one to +count the size of the symbol table required, and the other to actually +read the symbols. In between the two passes, a single array of type +`Sym' is created of the appropriate length. Finally, +`symtab.c:symtab_finalize' is called to sort the symbol table and +remove duplicate entries (entries with the same memory address). + + The symbol table must be a contiguous array for two reasons. First, +the `qsort' library function (which sorts an array) will be used to +sort the symbol table. Also, the symbol lookup routine +(`symtab.c:sym_lookup'), which finds symbols based on memory address, +uses a binary search algorithm which requires the symbol table to be a +sorted array. Function symbols are indicated with an `is_func' flag. +Line number symbols have no special flags set. Additionally, a symbol +can have an `is_static' flag to indicate that it is a local symbol. + + With the symbol table read, the symspecs can now be translated into +Syms (`sym_ids.c:sym_id_parse'). Remember that a single symspec can +match multiple symbols. An array of symbol tables (`syms') is created, +each entry of which is a symbol table of Syms to be included or +excluded from a particular listing. The master symbol table and the +symspecs are examined by nested loops, and every symbol that matches a +symspec is inserted into the appropriate syms table. This is done +twice, once to count the size of each required symbol table, and again +to build the tables, which have been malloced between passes. From now +on, to determine whether a symbol is on an include or exclude symspec +list, `gprof' simply uses its standard symbol lookup routine on the +appropriate table in the `syms' array. + + Now the profile data file(s) themselves are read +(`gmon_io.c:gmon_out_read'), first by checking for a new-style +`gmon.out' header, then assuming this is an old-style BSD `gmon.out' if +the magic number test failed. + + New-style histogram records are read by `hist.c:hist_read_rec'. For +the first histogram record, allocate a memory array to hold all the +bins, and read them in. When multiple profile data files (or files +with multiple histogram records) are read, the starting address, ending +address, number of bins and sampling rate must match between the +various histograms, or a fatal error will result. If everything +matches, just sum the additional histograms into the existing in-memory +array. + + As each call graph record is read (`call_graph.c:cg_read_rec'), the +parent and child addresses are matched to symbol table entries, and a +call graph arc is created by `cg_arcs.c:arc_add', unless the arc fails +a symspec check against INCL_ARCS/EXCL_ARCS. As each arc is added, a +linked list is maintained of the parent's child arcs, and of the child's +parent arcs. Both the child's call count and the arc's call count are +incremented by the record's call count. + + Basic-block records are read (`basic_blocks.c:bb_read_rec'), but +only if line-by-line profiling has been selected. Each basic-block +address is matched to a corresponding line symbol in the symbol table, +and an entry made in the symbol's bb_addr and bb_calls arrays. Again, +if multiple basic-block records are present for the same address, the +call counts are cumulative. + + A gmon.sum file is dumped, if requested (`gmon_io.c:gmon_out_write'). + + If histograms were present in the data files, assign them to symbols +(`hist.c:hist_assign_samples') by iterating over all the sample bins +and assigning them to symbols. Since the symbol table is sorted in +order of ascending memory addresses, we can simple follow along in the +symbol table as we make our pass over the sample bins. This step +includes a symspec check against INCL_FLAT/EXCL_FLAT. Depending on the +histogram scale factor, a sample bin may span multiple symbols, in +which case a fraction of the sample count is allocated to each symbol, +proportional to the degree of overlap. This effect is rare for normal +profiling, but overlaps are more common during line-by-line profiling, +and can cause each of two adjacent lines to be credited with half a +hit, for example. + + If call graph data is present, `cg_arcs.c:cg_assemble' is called. +First, if `-c' was specified, a machine-dependent routine (`find_call') +scans through each symbol's machine code, looking for subroutine call +instructions, and adding them to the call graph with a zero call count. +A topological sort is performed by depth-first numbering all the +symbols (`cg_dfn.c:cg_dfn'), so that children are always numbered less +than their parents, then making a array of pointers into the symbol +table and sorting it into numerical order, which is reverse topological +order (children appear before parents). Cycles are also detected at +this point, all members of which are assigned the same topological +number. Two passes are now made through this sorted array of symbol +pointers. The first pass, from end to beginning (parents to children), +computes the fraction of child time to propagate to each parent and a +print flag. The print flag reflects symspec handling of +INCL_GRAPH/EXCL_GRAPH, with a parent's include or exclude (print or no +print) property being propagated to its children, unless they +themselves explicitly appear in INCL_GRAPH or EXCL_GRAPH. A second +pass, from beginning to end (children to parents) actually propagates +the timings along the call graph, subject to a check against +INCL_TIME/EXCL_TIME. With the print flag, fractions, and timings now +stored in the symbol structures, the topological sort array is now +discarded, and a new array of pointers is assembled, this time sorted +by propagated time. + + Finally, print the various outputs the user requested, which is now +fairly straightforward. The call graph (`cg_print.c:cg_print') and +flat profile (`hist.c:hist_print') are regurgitations of values already +computed. The annotated source listing +(`basic_blocks.c:print_annotated_source') uses basic-block information, +if present, to label each line of code with call counts, otherwise only +the function call counts are presented. + + The function ordering code is marginally well documented in the +source code itself (`cg_print.c'). Basically, the functions with the +most use and the most parents are placed first, followed by other +functions with the most use, followed by lower use functions, followed +by unused functions at the end. + + +File: gprof.info, Node: Debugging, Prev: Internals, Up: Details + +Debugging `gprof' +----------------- + +If `gprof' was compiled with debugging enabled, the `-d' option +triggers debugging output (to stdout) which can be helpful in +understanding its operation. The debugging number specified is +interpreted as a sum of the following options: + +2 - Topological sort + Monitor depth-first numbering of symbols during call graph analysis + +4 - Cycles + Shows symbols as they are identified as cycle heads + +16 - Tallying + As the call graph arcs are read, show each arc and how the total + calls to each function are tallied + +32 - Call graph arc sorting + Details sorting individual parents/children within each call graph + entry + +64 - Reading histogram and call graph records + Shows address ranges of histograms as they are read, and each call + graph arc + +128 - Symbol table + Reading, classifying, and sorting the symbol table from the object + file. For line-by-line profiling (`-l' option), also shows line + numbers being assigned to memory addresses. + +256 - Static call graph + Trace operation of `-c' option + +512 - Symbol table and arc table lookups + Detail operation of lookup routines + +1024 - Call graph propagation + Shows how function times are propagated along the call graph + +2048 - Basic-blocks + Shows basic-block records as they are read from profile data (only + meaningful with `-l' option) + +4096 - Symspecs + Shows symspec-to-symbol pattern matching operation + +8192 - Annotate source + Tracks operation of `-A' option + + +File: gprof.info, Node: GNU Free Documentation License, Prev: Details, Up: Top + +GNU Free Documentation License +****************************** + +GNU Free Documentation License + + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies of +this license document, but changing it is not allowed. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone the +effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get credit +for their work, while not being considered responsible for +modifications made by others. + + This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft license +designed for free software. + + We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; it +can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + + A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + + A "Secondary Section" is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding them. + + The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + + The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + + A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the general +public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input to +text formatters. A copy made in an otherwise Transparent file format +whose markup has been designed to thwart or discourage subsequent +modification by readers is not Transparent. A copy that is not +"Transparent" is called "Opaque". + + Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML or +XML using a publicly available DTD, and standard-conforming simple HTML +designed for human modification. Opaque formats include PostScript, +PDF, proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the machine-generated +HTML produced by some word processors for output purposes only. + + The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + + You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies of the Document numbering more than +100, and the Document's license notice requires Cover Texts, you must +enclose the copies in covers that carry, clearly and legibly, all these +Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts +on the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present the +full title with all words of the title equally prominent and visible. +You may add other material on the covers in addition. Copying with +changes limited to the covers, as long as they preserve the title of +the Document and satisfy these conditions, can be treated as verbatim +copying in other respects. + + If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + + If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + + It is requested, but not required, that you contact the authors of +the Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release the +Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy of +it. In addition, you must do these things in the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. B. List on +the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has less than five). C. +State on the Title page the name of the publisher of the Modified +Version, as the publisher. D. Preserve all the copyright notices of +the Document. E. Add an appropriate copyright notice for your +modifications adjacent to the other copyright notices. F. Include, +immediately after the copyright notices, a license notice giving the +public permission to use the Modified Version under the terms of +this License, in the form shown in the Addendum below. G. Preserve in +that license notice the full lists of Invariant Sections and +required Cover Texts given in the Document's license notice. H. +Include an unaltered copy of this License. I. Preserve the section +entitled "History", and its title, and add to it an item stating at +least the title, year, new authors, and publisher of the Modified +Version as given on the Title Page. If there is no section entitled +"History" in the Document, create one stating the title, year, +authors, and publisher of the Document as given on its Title Page, +then add an item describing the Modified Version as stated in the +previous sentence. J. Preserve the network location, if any, given in +the Document for public access to a Transparent copy of the +Document, and likewise the network locations given in the Document +for previous versions it was based on. These may be placed in the +"History" section. You may omit a network location for a work that +was published at least four years before the Document itself, or if +the original publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", +preserve the section's title, and preserve in the section all the +substance and tone of each of the contributor acknowledgements +and/or dedications given therein. L. Preserve all the Invariant +Sections of the Document, unaltered in their text and in their +titles. Section numbers or the equivalent are not considered part +of the section titles. M. Delete any section entitled "Endorsements". +Such a section may not be included in the Modified Version. N. Do +not retitle any existing section as "Endorsements" or to conflict in +title with any Invariant Section. + + If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + + You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties-for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + + You may add a passage of up to five words as a Front-Cover Text, and +a passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or through +arrangements made by) any one entity. If the Document already includes +a cover text for the same cover, previously added by you or by +arrangement made by the same entity you are acting on behalf of, you +may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + + The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + + The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of Invariant +Sections in the license notice of the combined work. + + In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy that +is included in the collection, provided that you follow the rules of +this License for verbatim copying of each of the documents in all other +respects. + + You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version of +the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they are +not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. Otherwise +they must appear on covers around the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the original +English version of this License. In case of a disagreement between the +translation and the original English version of this License, the +original English version will prevail. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document +except as expressly provided for under this License. Any other attempt +to copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of +the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + + Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + ADDENDUM: How to use this License for your documents + + To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + + If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no Front-Cover +Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being +LIST"; likewise for Back-Cover Texts. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, to +permit their use in free software. + + + +Tag Table: +Node: Top713 +Node: Introduction1952 +Node: Compiling4278 +Node: Executing8502 +Node: Invoking11290 +Node: Output Options12701 +Node: Analysis Options19510 +Node: Miscellaneous Options22704 +Node: Deprecated Options23866 +Node: Symspecs25937 +Node: Output27755 +Node: Flat Profile28777 +Node: Call Graph33704 +Node: Primary36916 +Node: Callers39445 +Node: Subroutines41550 +Node: Cycles43347 +Node: Line-by-line50109 +Node: Annotated Source53905 +Node: Inaccuracy56763 +Node: Sampling Error57017 +Node: Assumptions59579 +Node: How do I?61040 +Node: Incompatibilities62872 +Node: Details64336 +Node: Implementation64725 +Node: File Format70614 +Node: Internals74860 +Node: Debugging83229 +Node: GNU Free Documentation License84822 + +End Tag Table diff --git a/gprof/gprof.texi b/gprof/gprof.texi new file mode 100644 index 000000000000..d77d12da3bb5 --- /dev/null +++ b/gprof/gprof.texi @@ -0,0 +1,2556 @@ +\input texinfo @c -*-texinfo-*- +@setfilename gprof.info +@c Copyright 1988, 1992, 1993, 1998, 1999, 2000, 2001, 2003 +@c Free Software Foundation, Inc. +@settitle GNU gprof +@setchapternewpage odd + +@ifinfo +@c This is a dir.info fragment to support semi-automated addition of +@c manuals to an info tree. zoo@cygnus.com is developing this facility. +@format +START-INFO-DIR-ENTRY +* gprof: (gprof). Profiling your program's execution +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@ifinfo +This file documents the gprof profiler of the GNU system. + +@c man begin COPYRIGHT +Copyright (C) 1988, 92, 97, 98, 99, 2000, 2001, 2003 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation; +with no Invariant Sections, with no Front-Cover Texts, and with no +Back-Cover Texts. A copy of the license is included in the +section entitled "GNU Free Documentation License". + +@c man end + +@ignore +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +@end ifinfo + +@finalout +@smallbook + +@titlepage +@title GNU gprof +@subtitle The @sc{gnu} Profiler +@author Jay Fenlason and Richard Stallman + +@page + +This manual describes the @sc{gnu} profiler, @code{gprof}, and how you +can use it to determine which parts of a program are taking most of the +execution time. We assume that you know how to write, compile, and +execute programs. @sc{gnu} @code{gprof} was written by Jay Fenlason. +Eric S. Raymond made some minor corrections and additions in 2003. + +@vskip 0pt plus 1filll +Copyright @copyright{} 1988, 92, 97, 98, 99, 2000, 2003 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with no Invariant Sections, with no Front-Cover Texts, and with no + Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". + +@end titlepage + +@ifnottex +@node Top +@top Profiling a Program: Where Does It Spend Its Time? + +This manual describes the @sc{gnu} profiler, @code{gprof}, and how you +can use it to determine which parts of a program are taking most of the +execution time. We assume that you know how to write, compile, and +execute programs. @sc{gnu} @code{gprof} was written by Jay Fenlason. + +This document is distributed under the terms of the GNU Free +Documentation License. A copy of the license is included in the +section entitled "GNU Free Documentation License". + +@menu +* Introduction:: What profiling means, and why it is useful. + +* Compiling:: How to compile your program for profiling. +* Executing:: Executing your program to generate profile data +* Invoking:: How to run @code{gprof}, and its options + +* Output:: Interpreting @code{gprof}'s output + +* Inaccuracy:: Potential problems you should be aware of +* How do I?:: Answers to common questions +* Incompatibilities:: (between @sc{gnu} @code{gprof} and Unix @code{gprof}.) +* Details:: Details of how profiling is done +* GNU Free Documentation License:: GNU Free Documentation License +@end menu +@end ifnottex + +@node Introduction +@chapter Introduction to Profiling + +@ifset man +@c man title gprof display call graph profile data + +@smallexample +@c man begin SYNOPSIS +gprof [ -[abcDhilLsTvwxyz] ] [ -[ACeEfFJnNOpPqQZ][@var{name}] ] + [ -I @var{dirs} ] [ -d[@var{num}] ] [ -k @var{from/to} ] + [ -m @var{min-count} ] [ -t @var{table-length} ] + [ --[no-]annotated-source[=@var{name}] ] + [ --[no-]exec-counts[=@var{name}] ] + [ --[no-]flat-profile[=@var{name}] ] [ --[no-]graph[=@var{name}] ] + [ --[no-]time=@var{name}] [ --all-lines ] [ --brief ] + [ --debug[=@var{level}] ] [ --function-ordering ] + [ --file-ordering ] [ --directory-path=@var{dirs} ] + [ --display-unused-functions ] [ --file-format=@var{name} ] + [ --file-info ] [ --help ] [ --line ] [ --min-count=@var{n} ] + [ --no-static ] [ --print-path ] [ --separate-files ] + [ --static-call-graph ] [ --sum ] [ --table-length=@var{len} ] + [ --traditional ] [ --version ] [ --width=@var{n} ] + [ --ignore-non-functions ] [ --demangle[=@var{STYLE}] ] + [ --no-demangle ] [ @var{image-file} ] [ @var{profile-file} @dots{} ] +@c man end +@end smallexample + +@c man begin DESCRIPTION +@code{gprof} produces an execution profile of C, Pascal, or Fortran77 +programs. The effect of called routines is incorporated in the profile +of each caller. The profile data is taken from the call graph profile file +(@file{gmon.out} default) which is created by programs +that are compiled with the @samp{-pg} option of +@code{cc}, @code{pc}, and @code{f77}. +The @samp{-pg} option also links in versions of the library routines +that are compiled for profiling. @code{Gprof} reads the given object +file (the default is @code{a.out}) and establishes the relation between +its symbol table and the call graph profile from @file{gmon.out}. +If more than one profile file is specified, the @code{gprof} +output shows the sum of the profile information in the given profile files. + +@code{Gprof} calculates the amount of time spent in each routine. +Next, these times are propagated along the edges of the call graph. +Cycles are discovered, and calls into a cycle are made to share the time +of the cycle. + +@c man end + +@c man begin BUGS +The granularity of the sampling is shown, but remains +statistical at best. +We assume that the time for each execution of a function +can be expressed by the total time for the function divided +by the number of times the function is called. +Thus the time propagated along the call graph arcs to the function's +parents is directly proportional to the number of times that +arc is traversed. + +Parents that are not themselves profiled will have the time of +their profiled children propagated to them, but they will appear +to be spontaneously invoked in the call graph listing, and will +not have their time propagated further. +Similarly, signal catchers, even though profiled, will appear +to be spontaneous (although for more obscure reasons). +Any profiled children of signal catchers should have their times +propagated properly, unless the signal catcher was invoked during +the execution of the profiling routine, in which case all is lost. + +The profiled program must call @code{exit}(2) +or return normally for the profiling information to be saved +in the @file{gmon.out} file. +@c man end + +@c man begin FILES +@table @code +@item @file{a.out} +the namelist and text space. +@item @file{gmon.out} +dynamic call graph and profile. +@item @file{gmon.sum} +summarized dynamic call graph and profile. +@end table +@c man end + +@c man begin SEEALSO +monitor(3), profil(2), cc(1), prof(1), and the Info entry for @file{gprof}. + +``An Execution Profiler for Modular Programs'', +by S. Graham, P. Kessler, M. McKusick; +Software - Practice and Experience, +Vol. 13, pp. 671-685, 1983. + +``gprof: A Call Graph Execution Profiler'', +by S. Graham, P. Kessler, M. McKusick; +Proceedings of the SIGPLAN '82 Symposium on Compiler Construction, +SIGPLAN Notices, Vol. 17, No 6, pp. 120-126, June 1982. +@c man end +@end ifset + +Profiling allows you to learn where your program spent its time and which +functions called which other functions while it was executing. This +information can show you which pieces of your program are slower than you +expected, and might be candidates for rewriting to make your program +execute faster. It can also tell you which functions are being called more +or less often than you expected. This may help you spot bugs that had +otherwise been unnoticed. + +Since the profiler uses information collected during the actual execution +of your program, it can be used on programs that are too large or too +complex to analyze by reading the source. However, how your program is run +will affect the information that shows up in the profile data. If you +don't use some feature of your program while it is being profiled, no +profile information will be generated for that feature. + +Profiling has several steps: + +@itemize @bullet +@item +You must compile and link your program with profiling enabled. +@xref{Compiling}. + +@item +You must execute your program to generate a profile data file. +@xref{Executing}. + +@item +You must run @code{gprof} to analyze the profile data. +@xref{Invoking}. +@end itemize + +The next three chapters explain these steps in greater detail. + +@c man begin DESCRIPTION + +Several forms of output are available from the analysis. + +The @dfn{flat profile} shows how much time your program spent in each function, +and how many times that function was called. If you simply want to know +which functions burn most of the cycles, it is stated concisely here. +@xref{Flat Profile}. + +The @dfn{call graph} shows, for each function, which functions called it, which +other functions it called, and how many times. There is also an estimate +of how much time was spent in the subroutines of each function. This can +suggest places where you might try to eliminate function calls that use a +lot of time. @xref{Call Graph}. + +The @dfn{annotated source} listing is a copy of the program's +source code, labeled with the number of times each line of the +program was executed. @xref{Annotated Source}. +@c man end + +To better understand how profiling works, you may wish to read +a description of its implementation. +@xref{Implementation}. + +@node Compiling +@chapter Compiling a Program for Profiling + +The first step in generating profile information for your program is +to compile and link it with profiling enabled. + +To compile a source file for profiling, specify the @samp{-pg} option when +you run the compiler. (This is in addition to the options you normally +use.) + +To link the program for profiling, if you use a compiler such as @code{cc} +to do the linking, simply specify @samp{-pg} in addition to your usual +options. The same option, @samp{-pg}, alters either compilation or linking +to do what is necessary for profiling. Here are examples: + +@example +cc -g -c myprog.c utils.c -pg +cc -o myprog myprog.o utils.o -pg +@end example + +The @samp{-pg} option also works with a command that both compiles and links: + +@example +cc -o myprog myprog.c utils.c -g -pg +@end example + +Note: The @samp{-pg} option must be part of your compilation options +as well as your link options. If it is not then no call-graph data +will be gathered and when you run @code{gprof} you will get an error +message like this: + +@example +gprof: gmon.out file is missing call-graph data +@end example + +If you add the @samp{-Q} switch to suppress the printing of the call +graph data you will still be able to see the time samples: + +@example +Flat profile: + +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls Ts/call Ts/call name + 44.12 0.07 0.07 zazLoop + 35.29 0.14 0.06 main + 20.59 0.17 0.04 bazMillion + + % the percentage of the total running time of the +@end example + +If you run the linker @code{ld} directly instead of through a compiler +such as @code{cc}, you may have to specify a profiling startup file +@file{gcrt0.o} as the first input file instead of the usual startup +file @file{crt0.o}. In addition, you would probably want to +specify the profiling C library, @file{libc_p.a}, by writing +@samp{-lc_p} instead of the usual @samp{-lc}. This is not absolutely +necessary, but doing this gives you number-of-calls information for +standard library functions such as @code{read} and @code{open}. For +example: + +@example +ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p +@end example + +If you compile only some of the modules of the program with @samp{-pg}, you +can still profile the program, but you won't get complete information about +the modules that were compiled without @samp{-pg}. The only information +you get for the functions in those modules is the total time spent in them; +there is no record of how many times they were called, or from where. This +will not affect the flat profile (except that the @code{calls} field for +the functions will be blank), but will greatly reduce the usefulness of the +call graph. + +If you wish to perform line-by-line profiling, +you will also need to specify the @samp{-g} option, +instructing the compiler to insert debugging symbols into the program +that match program addresses to source code lines. +@xref{Line-by-line}. + +In addition to the @samp{-pg} and @samp{-g} options, older versions of +GCC required you to specify the @samp{-a} option when compiling in +order to instrument it to perform basic-block counting. Newer +versions do not require this option and will not accept it; +basic-block counting is always enabled when @samp{-pg} is on. + +When basic-block counting is enabled, as the program runs +it will count how many times it executed each branch of each @samp{if} +statement, each iteration of each @samp{do} loop, etc. This will +enable @code{gprof} to construct an annotated source code +listing showing how many times each line of code was executed. + +It also worth noting that GCC supports a different profiling method +which is enabled by the @samp{-fprofile-arcs}, @samp{-ftest-coverage} +and @samp{-fprofile-values} switches. These switches do not produce +data which is useful to @code{gprof} however, so they are not +discussed further here. There is also the +@samp{-finstrument-functions} switch which will cause GCC to insert +calls to special user supplied instrumentation routines at the entry +and exit of every function in their program. This can be used to +implement an alternative profiling scheme. + +@node Executing +@chapter Executing the Program + +Once the program is compiled for profiling, you must run it in order to +generate the information that @code{gprof} needs. Simply run the program +as usual, using the normal arguments, file names, etc. The program should +run normally, producing the same output as usual. It will, however, run +somewhat slower than normal because of the time spent collecting and the +writing the profile data. + +The way you run the program---the arguments and input that you give +it---may have a dramatic effect on what the profile information shows. The +profile data will describe the parts of the program that were activated for +the particular input you use. For example, if the first command you give +to your program is to quit, the profile data will show the time used in +initialization and in cleanup, but not much else. + +Your program will write the profile data into a file called @file{gmon.out} +just before exiting. If there is already a file called @file{gmon.out}, +its contents are overwritten. There is currently no way to tell the +program to write the profile data under a different name, but you can rename +the file afterwards if you are concerned that it may be overwritten. + +In order to write the @file{gmon.out} file properly, your program must exit +normally: by returning from @code{main} or by calling @code{exit}. Calling +the low-level function @code{_exit} does not write the profile data, and +neither does abnormal termination due to an unhandled signal. + +The @file{gmon.out} file is written in the program's @emph{current working +directory} at the time it exits. This means that if your program calls +@code{chdir}, the @file{gmon.out} file will be left in the last directory +your program @code{chdir}'d to. If you don't have permission to write in +this directory, the file is not written, and you will get an error message. + +Older versions of the @sc{gnu} profiling library may also write a file +called @file{bb.out}. This file, if present, contains an human-readable +listing of the basic-block execution counts. Unfortunately, the +appearance of a human-readable @file{bb.out} means the basic-block +counts didn't get written into @file{gmon.out}. +The Perl script @code{bbconv.pl}, included with the @code{gprof} +source distribution, will convert a @file{bb.out} file into +a format readable by @code{gprof}. Invoke it like this: + +@smallexample +bbconv.pl < bb.out > @var{bh-data} +@end smallexample + +This translates the information in @file{bb.out} into a form that +@code{gprof} can understand. But you still need to tell @code{gprof} +about the existence of this translated information. To do that, include +@var{bb-data} on the @code{gprof} command line, @emph{along with +@file{gmon.out}}, like this: + +@smallexample +gprof @var{options} @var{executable-file} gmon.out @var{bb-data} [@var{yet-more-profile-data-files}@dots{}] [> @var{outfile}] +@end smallexample + +@node Invoking +@chapter @code{gprof} Command Summary + +After you have a profile data file @file{gmon.out}, you can run @code{gprof} +to interpret the information in it. The @code{gprof} program prints a +flat profile and a call graph on standard output. Typically you would +redirect the output of @code{gprof} into a file with @samp{>}. + +You run @code{gprof} like this: + +@smallexample +gprof @var{options} [@var{executable-file} [@var{profile-data-files}@dots{}]] [> @var{outfile}] +@end smallexample + +@noindent +Here square-brackets indicate optional arguments. + +If you omit the executable file name, the file @file{a.out} is used. If +you give no profile data file name, the file @file{gmon.out} is used. If +any file is not in the proper format, or if the profile data file does not +appear to belong to the executable file, an error message is printed. + +You can give more than one profile data file by entering all their names +after the executable file name; then the statistics in all the data files +are summed together. + +The order of these options does not matter. + +@menu +* Output Options:: Controlling @code{gprof}'s output style +* Analysis Options:: Controlling how @code{gprof} analyses its data +* Miscellaneous Options:: +* Deprecated Options:: Options you no longer need to use, but which + have been retained for compatibility +* Symspecs:: Specifying functions to include or exclude +@end menu + +@node Output Options,Analysis Options,,Invoking +@section Output Options + +@c man begin OPTIONS +These options specify which of several output formats +@code{gprof} should produce. + +Many of these options take an optional @dfn{symspec} to specify +functions to be included or excluded. These options can be +specified multiple times, with different symspecs, to include +or exclude sets of symbols. @xref{Symspecs}. + +Specifying any of these options overrides the default (@samp{-p -q}), +which prints a flat profile and call graph analysis +for all functions. + +@table @code + +@item -A[@var{symspec}] +@itemx --annotated-source[=@var{symspec}] +The @samp{-A} option causes @code{gprof} to print annotated source code. +If @var{symspec} is specified, print output only for matching symbols. +@xref{Annotated Source}. + +@item -b +@itemx --brief +If the @samp{-b} option is given, @code{gprof} doesn't print the +verbose blurbs that try to explain the meaning of all of the fields in +the tables. This is useful if you intend to print out the output, or +are tired of seeing the blurbs. + +@item -C[@var{symspec}] +@itemx --exec-counts[=@var{symspec}] +The @samp{-C} option causes @code{gprof} to +print a tally of functions and the number of times each was called. +If @var{symspec} is specified, print tally only for matching symbols. + +If the profile data file contains basic-block count records, specifying +the @samp{-l} option, along with @samp{-C}, will cause basic-block +execution counts to be tallied and displayed. + +@item -i +@itemx --file-info +The @samp{-i} option causes @code{gprof} to display summary information +about the profile data file(s) and then exit. The number of histogram, +call graph, and basic-block count records is displayed. + +@item -I @var{dirs} +@itemx --directory-path=@var{dirs} +The @samp{-I} option specifies a list of search directories in +which to find source files. Environment variable @var{GPROF_PATH} +can also be used to convey this information. +Used mostly for annotated source output. + +@item -J[@var{symspec}] +@itemx --no-annotated-source[=@var{symspec}] +The @samp{-J} option causes @code{gprof} not to +print annotated source code. +If @var{symspec} is specified, @code{gprof} prints annotated source, +but excludes matching symbols. + +@item -L +@itemx --print-path +Normally, source filenames are printed with the path +component suppressed. The @samp{-L} option causes @code{gprof} +to print the full pathname of +source filenames, which is determined +from symbolic debugging information in the image file +and is relative to the directory in which the compiler +was invoked. + +@item -p[@var{symspec}] +@itemx --flat-profile[=@var{symspec}] +The @samp{-p} option causes @code{gprof} to print a flat profile. +If @var{symspec} is specified, print flat profile only for matching symbols. +@xref{Flat Profile}. + +@item -P[@var{symspec}] +@itemx --no-flat-profile[=@var{symspec}] +The @samp{-P} option causes @code{gprof} to suppress printing a flat profile. +If @var{symspec} is specified, @code{gprof} prints a flat profile, +but excludes matching symbols. + +@item -q[@var{symspec}] +@itemx --graph[=@var{symspec}] +The @samp{-q} option causes @code{gprof} to print the call graph analysis. +If @var{symspec} is specified, print call graph only for matching symbols +and their children. +@xref{Call Graph}. + +@item -Q[@var{symspec}] +@itemx --no-graph[=@var{symspec}] +The @samp{-Q} option causes @code{gprof} to suppress printing the +call graph. +If @var{symspec} is specified, @code{gprof} prints a call graph, +but excludes matching symbols. + +@item -y +@itemx --separate-files +This option affects annotated source output only. +Normally, @code{gprof} prints annotated source files +to standard-output. If this option is specified, +annotated source for a file named @file{path/@var{filename}} +is generated in the file @file{@var{filename}-ann}. If the underlying +filesystem would truncate @file{@var{filename}-ann} so that it +overwrites the original @file{@var{filename}}, @code{gprof} generates +annotated source in the file @file{@var{filename}.ann} instead (if the +original file name has an extension, that extension is @emph{replaced} +with @file{.ann}). + +@item -Z[@var{symspec}] +@itemx --no-exec-counts[=@var{symspec}] +The @samp{-Z} option causes @code{gprof} not to +print a tally of functions and the number of times each was called. +If @var{symspec} is specified, print tally, but exclude matching symbols. + +@item --function-ordering +The @samp{--function-ordering} option causes @code{gprof} to print a +suggested function ordering for the program based on profiling data. +This option suggests an ordering which may improve paging, tlb and +cache behavior for the program on systems which support arbitrary +ordering of functions in an executable. + +The exact details of how to force the linker to place functions +in a particular order is system dependent and out of the scope of this +manual. + +@item --file-ordering @var{map_file} +The @samp{--file-ordering} option causes @code{gprof} to print a +suggested .o link line ordering for the program based on profiling data. +This option suggests an ordering which may improve paging, tlb and +cache behavior for the program on systems which do not support arbitrary +ordering of functions in an executable. + +Use of the @samp{-a} argument is highly recommended with this option. + +The @var{map_file} argument is a pathname to a file which provides +function name to object file mappings. The format of the file is similar to +the output of the program @code{nm}. + +@smallexample +@group +c-parse.o:00000000 T yyparse +c-parse.o:00000004 C yyerrflag +c-lang.o:00000000 T maybe_objc_method_name +c-lang.o:00000000 T print_lang_statistics +c-lang.o:00000000 T recognize_objc_keyword +c-decl.o:00000000 T print_lang_identifier +c-decl.o:00000000 T print_lang_type +@dots{} + +@end group +@end smallexample + +To create a @var{map_file} with @sc{gnu} @code{nm}, type a command like +@kbd{nm --extern-only --defined-only -v --print-file-name program-name}. + +@item -T +@itemx --traditional +The @samp{-T} option causes @code{gprof} to print its output in +``traditional'' BSD style. + +@item -w @var{width} +@itemx --width=@var{width} +Sets width of output lines to @var{width}. +Currently only used when printing the function index at the bottom +of the call graph. + +@item -x +@itemx --all-lines +This option affects annotated source output only. +By default, only the lines at the beginning of a basic-block +are annotated. If this option is specified, every line in +a basic-block is annotated by repeating the annotation for the +first line. This behavior is similar to @code{tcov}'s @samp{-a}. + +@item --demangle[=@var{style}] +@itemx --no-demangle +These options control whether C++ symbol names should be demangled when +printing output. The default is to demangle symbols. The +@code{--no-demangle} option may be used to turn off demangling. Different +compilers have different mangling styles. The optional demangling style +argument can be used to choose an appropriate demangling style for your +compiler. +@end table + +@node Analysis Options,Miscellaneous Options,Output Options,Invoking +@section Analysis Options + +@table @code + +@item -a +@itemx --no-static +The @samp{-a} option causes @code{gprof} to suppress the printing of +statically declared (private) functions. (These are functions whose +names are not listed as global, and which are not visible outside the +file/function/block where they were defined.) Time spent in these +functions, calls to/from them, etc, will all be attributed to the +function that was loaded directly before it in the executable file. +@c This is compatible with Unix @code{gprof}, but a bad idea. +This option affects both the flat profile and the call graph. + +@item -c +@itemx --static-call-graph +The @samp{-c} option causes the call graph of the program to be +augmented by a heuristic which examines the text space of the object +file and identifies function calls in the binary machine code. +Since normal call graph records are only generated when functions are +entered, this option identifies children that could have been called, +but never were. Calls to functions that were not compiled with +profiling enabled are also identified, but only if symbol table +entries are present for them. +Calls to dynamic library routines are typically @emph{not} found +by this option. +Parents or children identified via this heuristic +are indicated in the call graph with call counts of @samp{0}. + +@item -D +@itemx --ignore-non-functions +The @samp{-D} option causes @code{gprof} to ignore symbols which +are not known to be functions. This option will give more accurate +profile data on systems where it is supported (Solaris and HPUX for +example). + +@item -k @var{from}/@var{to} +The @samp{-k} option allows you to delete from the call graph any arcs from +symbols matching symspec @var{from} to those matching symspec @var{to}. + +@item -l +@itemx --line +The @samp{-l} option enables line-by-line profiling, which causes +histogram hits to be charged to individual source code lines, +instead of functions. +If the program was compiled with basic-block counting enabled, +this option will also identify how many times each line of +code was executed. +While line-by-line profiling can help isolate where in a large function +a program is spending its time, it also significantly increases +the running time of @code{gprof}, and magnifies statistical +inaccuracies. +@xref{Sampling Error}. + +@item -m @var{num} +@itemx --min-count=@var{num} +This option affects execution count output only. +Symbols that are executed less than @var{num} times are suppressed. + +@item -n[@var{symspec}] +@itemx --time[=@var{symspec}] +The @samp{-n} option causes @code{gprof}, in its call graph analysis, +to only propagate times for symbols matching @var{symspec}. + +@item -N[@var{symspec}] +@itemx --no-time[=@var{symspec}] +The @samp{-n} option causes @code{gprof}, in its call graph analysis, +not to propagate times for symbols matching @var{symspec}. + +@item -z +@itemx --display-unused-functions +If you give the @samp{-z} option, @code{gprof} will mention all +functions in the flat profile, even those that were never called, and +that had no time spent in them. This is useful in conjunction with the +@samp{-c} option for discovering which routines were never called. + +@end table + +@node Miscellaneous Options,Deprecated Options,Analysis Options,Invoking +@section Miscellaneous Options + +@table @code + +@item -d[@var{num}] +@itemx --debug[=@var{num}] +The @samp{-d @var{num}} option specifies debugging options. +If @var{num} is not specified, enable all debugging. +@xref{Debugging}. + +@item -O@var{name} +@itemx --file-format=@var{name} +Selects the format of the profile data files. Recognized formats are +@samp{auto} (the default), @samp{bsd}, @samp{4.4bsd}, @samp{magic}, and +@samp{prof} (not yet supported). + +@item -s +@itemx --sum +The @samp{-s} option causes @code{gprof} to summarize the information +in the profile data files it read in, and write out a profile data +file called @file{gmon.sum}, which contains all the information from +the profile data files that @code{gprof} read in. The file @file{gmon.sum} +may be one of the specified input files; the effect of this is to +merge the data in the other input files into @file{gmon.sum}. + +Eventually you can run @code{gprof} again without @samp{-s} to analyze the +cumulative data in the file @file{gmon.sum}. + +@item -v +@itemx --version +The @samp{-v} flag causes @code{gprof} to print the current version +number, and then exit. + +@end table + +@node Deprecated Options,Symspecs,Miscellaneous Options,Invoking +@section Deprecated Options + +@table @code + +These options have been replaced with newer versions that use symspecs. + +@item -e @var{function_name} +The @samp{-e @var{function}} option tells @code{gprof} to not print +information about the function @var{function_name} (and its +children@dots{}) in the call graph. The function will still be listed +as a child of any functions that call it, but its index number will be +shown as @samp{[not printed]}. More than one @samp{-e} option may be +given; only one @var{function_name} may be indicated with each @samp{-e} +option. + +@item -E @var{function_name} +The @code{-E @var{function}} option works like the @code{-e} option, but +time spent in the function (and children who were not called from +anywhere else), will not be used to compute the percentages-of-time for +the call graph. More than one @samp{-E} option may be given; only one +@var{function_name} may be indicated with each @samp{-E} option. + +@item -f @var{function_name} +The @samp{-f @var{function}} option causes @code{gprof} to limit the +call graph to the function @var{function_name} and its children (and +their children@dots{}). More than one @samp{-f} option may be given; +only one @var{function_name} may be indicated with each @samp{-f} +option. + +@item -F @var{function_name} +The @samp{-F @var{function}} option works like the @code{-f} option, but +only time spent in the function and its children (and their +children@dots{}) will be used to determine total-time and +percentages-of-time for the call graph. More than one @samp{-F} option +may be given; only one @var{function_name} may be indicated with each +@samp{-F} option. The @samp{-F} option overrides the @samp{-E} option. + +@end table + +@c man end + +Note that only one function can be specified with each @code{-e}, +@code{-E}, @code{-f} or @code{-F} option. To specify more than one +function, use multiple options. For example, this command: + +@example +gprof -e boring -f foo -f bar myprogram > gprof.output +@end example + +@noindent +lists in the call graph all functions that were reached from either +@code{foo} or @code{bar} and were not reachable from @code{boring}. + +@node Symspecs,,Deprecated Options,Invoking +@section Symspecs + +Many of the output options allow functions to be included or excluded +using @dfn{symspecs} (symbol specifications), which observe the +following syntax: + +@example + filename_containing_a_dot +| funcname_not_containing_a_dot +| linenumber +| ( [ any_filename ] `:' ( any_funcname | linenumber ) ) +@end example + +Here are some sample symspecs: + +@table @samp +@item main.c +Selects everything in file @file{main.c}---the +dot in the string tells @code{gprof} to interpret +the string as a filename, rather than as +a function name. To select a file whose +name does not contain a dot, a trailing colon +should be specified. For example, @samp{odd:} is +interpreted as the file named @file{odd}. + +@item main +Selects all functions named @samp{main}. + +Note that there may be multiple instances of the same function name +because some of the definitions may be local (i.e., static). Unless a +function name is unique in a program, you must use the colon notation +explained below to specify a function from a specific source file. + +Sometimes, function names contain dots. In such cases, it is necessary +to add a leading colon to the name. For example, @samp{:.mul} selects +function @samp{.mul}. + +In some object file formats, symbols have a leading underscore. +@code{gprof} will normally not print these underscores. When you name a +symbol in a symspec, you should type it exactly as @code{gprof} prints +it in its output. For example, if the compiler produces a symbol +@samp{_main} from your @code{main} function, @code{gprof} still prints +it as @samp{main} in its output, so you should use @samp{main} in +symspecs. + +@item main.c:main +Selects function @samp{main} in file @file{main.c}. + +@item main.c:134 +Selects line 134 in file @file{main.c}. +@end table + +@node Output +@chapter Interpreting @code{gprof}'s Output + +@code{gprof} can produce several different output styles, the +most important of which are described below. The simplest output +styles (file information, execution count, and function and file ordering) +are not described here, but are documented with the respective options +that trigger them. +@xref{Output Options}. + +@menu +* Flat Profile:: The flat profile shows how much time was spent + executing directly in each function. +* Call Graph:: The call graph shows which functions called which + others, and how much time each function used + when its subroutine calls are included. +* Line-by-line:: @code{gprof} can analyze individual source code lines +* Annotated Source:: The annotated source listing displays source code + labeled with execution counts +@end menu + + +@node Flat Profile,Call Graph,,Output +@section The Flat Profile +@cindex flat profile + +The @dfn{flat profile} shows the total amount of time your program +spent executing each function. Unless the @samp{-z} option is given, +functions with no apparent time spent in them, and no apparent calls +to them, are not mentioned. Note that if a function was not compiled +for profiling, and didn't run long enough to show up on the program +counter histogram, it will be indistinguishable from a function that +was never called. + +This is part of a flat profile for a small program: + +@smallexample +@group +Flat profile: + +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 33.34 0.02 0.02 7208 0.00 0.00 open + 16.67 0.03 0.01 244 0.04 0.12 offtime + 16.67 0.04 0.01 8 1.25 1.25 memccpy + 16.67 0.05 0.01 7 1.43 1.43 write + 16.67 0.06 0.01 mcount + 0.00 0.06 0.00 236 0.00 0.00 tzset + 0.00 0.06 0.00 192 0.00 0.00 tolower + 0.00 0.06 0.00 47 0.00 0.00 strlen + 0.00 0.06 0.00 45 0.00 0.00 strchr + 0.00 0.06 0.00 1 0.00 50.00 main + 0.00 0.06 0.00 1 0.00 0.00 memcpy + 0.00 0.06 0.00 1 0.00 10.11 print + 0.00 0.06 0.00 1 0.00 0.00 profil + 0.00 0.06 0.00 1 0.00 50.00 report +@dots{} +@end group +@end smallexample + +@noindent +The functions are sorted by first by decreasing run-time spent in them, +then by decreasing number of calls, then alphabetically by name. The +functions @samp{mcount} and @samp{profil} are part of the profiling +apparatus and appear in every flat profile; their time gives a measure of +the amount of overhead due to profiling. + +Just before the column headers, a statement appears indicating +how much time each sample counted as. +This @dfn{sampling period} estimates the margin of error in each of the time +figures. A time figure that is not much larger than this is not +reliable. In this example, each sample counted as 0.01 seconds, +suggesting a 100 Hz sampling rate. +The program's total execution time was 0.06 +seconds, as indicated by the @samp{cumulative seconds} field. Since +each sample counted for 0.01 seconds, this means only six samples +were taken during the run. Two of the samples occurred while the +program was in the @samp{open} function, as indicated by the +@samp{self seconds} field. Each of the other four samples +occurred one each in @samp{offtime}, @samp{memccpy}, @samp{write}, +and @samp{mcount}. +Since only six samples were taken, none of these values can +be regarded as particularly reliable. +In another run, +the @samp{self seconds} field for +@samp{mcount} might well be @samp{0.00} or @samp{0.02}. +@xref{Sampling Error}, for a complete discussion. + +The remaining functions in the listing (those whose +@samp{self seconds} field is @samp{0.00}) didn't appear +in the histogram samples at all. However, the call graph +indicated that they were called, so therefore they are listed, +sorted in decreasing order by the @samp{calls} field. +Clearly some time was spent executing these functions, +but the paucity of histogram samples prevents any +determination of how much time each took. + +Here is what the fields in each line mean: + +@table @code +@item % time +This is the percentage of the total execution time your program spent +in this function. These should all add up to 100%. + +@item cumulative seconds +This is the cumulative total number of seconds the computer spent +executing this functions, plus the time spent in all the functions +above this one in this table. + +@item self seconds +This is the number of seconds accounted for by this function alone. +The flat profile listing is sorted first by this number. + +@item calls +This is the total number of times the function was called. If the +function was never called, or the number of times it was called cannot +be determined (probably because the function was not compiled with +profiling enabled), the @dfn{calls} field is blank. + +@item self ms/call +This represents the average number of milliseconds spent in this +function per call, if this function is profiled. Otherwise, this field +is blank for this function. + +@item total ms/call +This represents the average number of milliseconds spent in this +function and its descendants per call, if this function is profiled. +Otherwise, this field is blank for this function. +This is the only field in the flat profile that uses call graph analysis. + +@item name +This is the name of the function. The flat profile is sorted by this +field alphabetically after the @dfn{self seconds} and @dfn{calls} +fields are sorted. +@end table + +@node Call Graph,Line-by-line,Flat Profile,Output +@section The Call Graph +@cindex call graph + +The @dfn{call graph} shows how much time was spent in each function +and its children. From this information, you can find functions that, +while they themselves may not have used much time, called other +functions that did use unusual amounts of time. + +Here is a sample call from a small program. This call came from the +same @code{gprof} run as the flat profile example in the previous +chapter. + +@smallexample +@group +granularity: each sample hit covers 2 byte(s) for 20.00% of 0.05 seconds + +index % time self children called name + <spontaneous> +[1] 100.0 0.00 0.05 start [1] + 0.00 0.05 1/1 main [2] + 0.00 0.00 1/2 on_exit [28] + 0.00 0.00 1/1 exit [59] +----------------------------------------------- + 0.00 0.05 1/1 start [1] +[2] 100.0 0.00 0.05 1 main [2] + 0.00 0.05 1/1 report [3] +----------------------------------------------- + 0.00 0.05 1/1 main [2] +[3] 100.0 0.00 0.05 1 report [3] + 0.00 0.03 8/8 timelocal [6] + 0.00 0.01 1/1 print [9] + 0.00 0.01 9/9 fgets [12] + 0.00 0.00 12/34 strncmp <cycle 1> [40] + 0.00 0.00 8/8 lookup [20] + 0.00 0.00 1/1 fopen [21] + 0.00 0.00 8/8 chewtime [24] + 0.00 0.00 8/16 skipspace [44] +----------------------------------------------- +[4] 59.8 0.01 0.02 8+472 <cycle 2 as a whole> [4] + 0.01 0.02 244+260 offtime <cycle 2> [7] + 0.00 0.00 236+1 tzset <cycle 2> [26] +----------------------------------------------- +@end group +@end smallexample + +The lines full of dashes divide this table into @dfn{entries}, one for each +function. Each entry has one or more lines. + +In each entry, the primary line is the one that starts with an index number +in square brackets. The end of this line says which function the entry is +for. The preceding lines in the entry describe the callers of this +function and the following lines describe its subroutines (also called +@dfn{children} when we speak of the call graph). + +The entries are sorted by time spent in the function and its subroutines. + +The internal profiling function @code{mcount} (@pxref{Flat Profile}) +is never mentioned in the call graph. + +@menu +* Primary:: Details of the primary line's contents. +* Callers:: Details of caller-lines' contents. +* Subroutines:: Details of subroutine-lines' contents. +* Cycles:: When there are cycles of recursion, + such as @code{a} calls @code{b} calls @code{a}@dots{} +@end menu + +@node Primary +@subsection The Primary Line + +The @dfn{primary line} in a call graph entry is the line that +describes the function which the entry is about and gives the overall +statistics for this function. + +For reference, we repeat the primary line from the entry for function +@code{report} in our main example, together with the heading line that +shows the names of the fields: + +@smallexample +@group +index % time self children called name +@dots{} +[3] 100.0 0.00 0.05 1 report [3] +@end group +@end smallexample + +Here is what the fields in the primary line mean: + +@table @code +@item index +Entries are numbered with consecutive integers. Each function +therefore has an index number, which appears at the beginning of its +primary line. + +Each cross-reference to a function, as a caller or subroutine of +another, gives its index number as well as its name. The index number +guides you if you wish to look for the entry for that function. + +@item % time +This is the percentage of the total time that was spent in this +function, including time spent in subroutines called from this +function. + +The time spent in this function is counted again for the callers of +this function. Therefore, adding up these percentages is meaningless. + +@item self +This is the total amount of time spent in this function. This +should be identical to the number printed in the @code{seconds} field +for this function in the flat profile. + +@item children +This is the total amount of time spent in the subroutine calls made by +this function. This should be equal to the sum of all the @code{self} +and @code{children} entries of the children listed directly below this +function. + +@item called +This is the number of times the function was called. + +If the function called itself recursively, there are two numbers, +separated by a @samp{+}. The first number counts non-recursive calls, +and the second counts recursive calls. + +In the example above, the function @code{report} was called once from +@code{main}. + +@item name +This is the name of the current function. The index number is +repeated after it. + +If the function is part of a cycle of recursion, the cycle number is +printed between the function's name and the index number +(@pxref{Cycles}). For example, if function @code{gnurr} is part of +cycle number one, and has index number twelve, its primary line would +be end like this: + +@example +gnurr <cycle 1> [12] +@end example +@end table + +@node Callers, Subroutines, Primary, Call Graph +@subsection Lines for a Function's Callers + +A function's entry has a line for each function it was called by. +These lines' fields correspond to the fields of the primary line, but +their meanings are different because of the difference in context. + +For reference, we repeat two lines from the entry for the function +@code{report}, the primary line and one caller-line preceding it, together +with the heading line that shows the names of the fields: + +@smallexample +index % time self children called name +@dots{} + 0.00 0.05 1/1 main [2] +[3] 100.0 0.00 0.05 1 report [3] +@end smallexample + +Here are the meanings of the fields in the caller-line for @code{report} +called from @code{main}: + +@table @code +@item self +An estimate of the amount of time spent in @code{report} itself when it was +called from @code{main}. + +@item children +An estimate of the amount of time spent in subroutines of @code{report} +when @code{report} was called from @code{main}. + +The sum of the @code{self} and @code{children} fields is an estimate +of the amount of time spent within calls to @code{report} from @code{main}. + +@item called +Two numbers: the number of times @code{report} was called from @code{main}, +followed by the total number of non-recursive calls to @code{report} from +all its callers. + +@item name and index number +The name of the caller of @code{report} to which this line applies, +followed by the caller's index number. + +Not all functions have entries in the call graph; some +options to @code{gprof} request the omission of certain functions. +When a caller has no entry of its own, it still has caller-lines +in the entries of the functions it calls. + +If the caller is part of a recursion cycle, the cycle number is +printed between the name and the index number. +@end table + +If the identity of the callers of a function cannot be determined, a +dummy caller-line is printed which has @samp{<spontaneous>} as the +``caller's name'' and all other fields blank. This can happen for +signal handlers. +@c What if some calls have determinable callers' names but not all? +@c FIXME - still relevant? + +@node Subroutines, Cycles, Callers, Call Graph +@subsection Lines for a Function's Subroutines + +A function's entry has a line for each of its subroutines---in other +words, a line for each other function that it called. These lines' +fields correspond to the fields of the primary line, but their meanings +are different because of the difference in context. + +For reference, we repeat two lines from the entry for the function +@code{main}, the primary line and a line for a subroutine, together +with the heading line that shows the names of the fields: + +@smallexample +index % time self children called name +@dots{} +[2] 100.0 0.00 0.05 1 main [2] + 0.00 0.05 1/1 report [3] +@end smallexample + +Here are the meanings of the fields in the subroutine-line for @code{main} +calling @code{report}: + +@table @code +@item self +An estimate of the amount of time spent directly within @code{report} +when @code{report} was called from @code{main}. + +@item children +An estimate of the amount of time spent in subroutines of @code{report} +when @code{report} was called from @code{main}. + +The sum of the @code{self} and @code{children} fields is an estimate +of the total time spent in calls to @code{report} from @code{main}. + +@item called +Two numbers, the number of calls to @code{report} from @code{main} +followed by the total number of non-recursive calls to @code{report}. +This ratio is used to determine how much of @code{report}'s @code{self} +and @code{children} time gets credited to @code{main}. +@xref{Assumptions}. + +@item name +The name of the subroutine of @code{main} to which this line applies, +followed by the subroutine's index number. + +If the caller is part of a recursion cycle, the cycle number is +printed between the name and the index number. +@end table + +@node Cycles,, Subroutines, Call Graph +@subsection How Mutually Recursive Functions Are Described +@cindex cycle +@cindex recursion cycle + +The graph may be complicated by the presence of @dfn{cycles of +recursion} in the call graph. A cycle exists if a function calls +another function that (directly or indirectly) calls (or appears to +call) the original function. For example: if @code{a} calls @code{b}, +and @code{b} calls @code{a}, then @code{a} and @code{b} form a cycle. + +Whenever there are call paths both ways between a pair of functions, they +belong to the same cycle. If @code{a} and @code{b} call each other and +@code{b} and @code{c} call each other, all three make one cycle. Note that +even if @code{b} only calls @code{a} if it was not called from @code{a}, +@code{gprof} cannot determine this, so @code{a} and @code{b} are still +considered a cycle. + +The cycles are numbered with consecutive integers. When a function +belongs to a cycle, each time the function name appears in the call graph +it is followed by @samp{<cycle @var{number}>}. + +The reason cycles matter is that they make the time values in the call +graph paradoxical. The ``time spent in children'' of @code{a} should +include the time spent in its subroutine @code{b} and in @code{b}'s +subroutines---but one of @code{b}'s subroutines is @code{a}! How much of +@code{a}'s time should be included in the children of @code{a}, when +@code{a} is indirectly recursive? + +The way @code{gprof} resolves this paradox is by creating a single entry +for the cycle as a whole. The primary line of this entry describes the +total time spent directly in the functions of the cycle. The +``subroutines'' of the cycle are the individual functions of the cycle, and +all other functions that were called directly by them. The ``callers'' of +the cycle are the functions, outside the cycle, that called functions in +the cycle. + +Here is an example portion of a call graph which shows a cycle containing +functions @code{a} and @code{b}. The cycle was entered by a call to +@code{a} from @code{main}; both @code{a} and @code{b} called @code{c}. + +@smallexample +index % time self children called name +---------------------------------------- + 1.77 0 1/1 main [2] +[3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3] + 1.02 0 3 b <cycle 1> [4] + 0.75 0 2 a <cycle 1> [5] +---------------------------------------- + 3 a <cycle 1> [5] +[4] 52.85 1.02 0 0 b <cycle 1> [4] + 2 a <cycle 1> [5] + 0 0 3/6 c [6] +---------------------------------------- + 1.77 0 1/1 main [2] + 2 b <cycle 1> [4] +[5] 38.86 0.75 0 1 a <cycle 1> [5] + 3 b <cycle 1> [4] + 0 0 3/6 c [6] +---------------------------------------- +@end smallexample + +@noindent +(The entire call graph for this program contains in addition an entry for +@code{main}, which calls @code{a}, and an entry for @code{c}, with callers +@code{a} and @code{b}.) + +@smallexample +index % time self children called name + <spontaneous> +[1] 100.00 0 1.93 0 start [1] + 0.16 1.77 1/1 main [2] +---------------------------------------- + 0.16 1.77 1/1 start [1] +[2] 100.00 0.16 1.77 1 main [2] + 1.77 0 1/1 a <cycle 1> [5] +---------------------------------------- + 1.77 0 1/1 main [2] +[3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3] + 1.02 0 3 b <cycle 1> [4] + 0.75 0 2 a <cycle 1> [5] + 0 0 6/6 c [6] +---------------------------------------- + 3 a <cycle 1> [5] +[4] 52.85 1.02 0 0 b <cycle 1> [4] + 2 a <cycle 1> [5] + 0 0 3/6 c [6] +---------------------------------------- + 1.77 0 1/1 main [2] + 2 b <cycle 1> [4] +[5] 38.86 0.75 0 1 a <cycle 1> [5] + 3 b <cycle 1> [4] + 0 0 3/6 c [6] +---------------------------------------- + 0 0 3/6 b <cycle 1> [4] + 0 0 3/6 a <cycle 1> [5] +[6] 0.00 0 0 6 c [6] +---------------------------------------- +@end smallexample + +The @code{self} field of the cycle's primary line is the total time +spent in all the functions of the cycle. It equals the sum of the +@code{self} fields for the individual functions in the cycle, found +in the entry in the subroutine lines for these functions. + +The @code{children} fields of the cycle's primary line and subroutine lines +count only subroutines outside the cycle. Even though @code{a} calls +@code{b}, the time spent in those calls to @code{b} is not counted in +@code{a}'s @code{children} time. Thus, we do not encounter the problem of +what to do when the time in those calls to @code{b} includes indirect +recursive calls back to @code{a}. + +The @code{children} field of a caller-line in the cycle's entry estimates +the amount of time spent @emph{in the whole cycle}, and its other +subroutines, on the times when that caller called a function in the cycle. + +The @code{calls} field in the primary line for the cycle has two numbers: +first, the number of times functions in the cycle were called by functions +outside the cycle; second, the number of times they were called by +functions in the cycle (including times when a function in the cycle calls +itself). This is a generalization of the usual split into non-recursive and +recursive calls. + +The @code{calls} field of a subroutine-line for a cycle member in the +cycle's entry says how many time that function was called from functions in +the cycle. The total of all these is the second number in the primary line's +@code{calls} field. + +In the individual entry for a function in a cycle, the other functions in +the same cycle can appear as subroutines and as callers. These lines show +how many times each function in the cycle called or was called from each other +function in the cycle. The @code{self} and @code{children} fields in these +lines are blank because of the difficulty of defining meanings for them +when recursion is going on. + +@node Line-by-line,Annotated Source,Call Graph,Output +@section Line-by-line Profiling + +@code{gprof}'s @samp{-l} option causes the program to perform +@dfn{line-by-line} profiling. In this mode, histogram +samples are assigned not to functions, but to individual +lines of source code. The program usually must be compiled +with a @samp{-g} option, in addition to @samp{-pg}, in order +to generate debugging symbols for tracking source code lines. + +The flat profile is the most useful output table +in line-by-line mode. +The call graph isn't as useful as normal, since +the current version of @code{gprof} does not propagate +call graph arcs from source code lines to the enclosing function. +The call graph does, however, show each line of code +that called each function, along with a count. + +Here is a section of @code{gprof}'s output, without line-by-line profiling. +Note that @code{ct_init} accounted for four histogram hits, and +13327 calls to @code{init_block}. + +@smallexample +Flat profile: + +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls us/call us/call name + 30.77 0.13 0.04 6335 6.31 6.31 ct_init + + + Call graph (explanation follows) + + +granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds + +index % time self children called name + + 0.00 0.00 1/13496 name_too_long + 0.00 0.00 40/13496 deflate + 0.00 0.00 128/13496 deflate_fast + 0.00 0.00 13327/13496 ct_init +[7] 0.0 0.00 0.00 13496 init_block + +@end smallexample + +Now let's look at some of @code{gprof}'s output from the same program run, +this time with line-by-line profiling enabled. Note that @code{ct_init}'s +four histogram hits are broken down into four lines of source code - one hit +occurred on each of lines 349, 351, 382 and 385. In the call graph, +note how +@code{ct_init}'s 13327 calls to @code{init_block} are broken down +into one call from line 396, 3071 calls from line 384, 3730 calls +from line 385, and 6525 calls from 387. + +@smallexample +Flat profile: + +Each sample counts as 0.01 seconds. + % cumulative self + time seconds seconds calls name + 7.69 0.10 0.01 ct_init (trees.c:349) + 7.69 0.11 0.01 ct_init (trees.c:351) + 7.69 0.12 0.01 ct_init (trees.c:382) + 7.69 0.13 0.01 ct_init (trees.c:385) + + + Call graph (explanation follows) + + +granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds + + % time self children called name + + 0.00 0.00 1/13496 name_too_long (gzip.c:1440) + 0.00 0.00 1/13496 deflate (deflate.c:763) + 0.00 0.00 1/13496 ct_init (trees.c:396) + 0.00 0.00 2/13496 deflate (deflate.c:727) + 0.00 0.00 4/13496 deflate (deflate.c:686) + 0.00 0.00 5/13496 deflate (deflate.c:675) + 0.00 0.00 12/13496 deflate (deflate.c:679) + 0.00 0.00 16/13496 deflate (deflate.c:730) + 0.00 0.00 128/13496 deflate_fast (deflate.c:654) + 0.00 0.00 3071/13496 ct_init (trees.c:384) + 0.00 0.00 3730/13496 ct_init (trees.c:385) + 0.00 0.00 6525/13496 ct_init (trees.c:387) +[6] 0.0 0.00 0.00 13496 init_block (trees.c:408) + +@end smallexample + + +@node Annotated Source,,Line-by-line,Output +@section The Annotated Source Listing + +@code{gprof}'s @samp{-A} option triggers an annotated source listing, +which lists the program's source code, each function labeled with the +number of times it was called. You may also need to specify the +@samp{-I} option, if @code{gprof} can't find the source code files. + +Compiling with @samp{gcc @dots{} -g -pg -a} augments your program +with basic-block counting code, in addition to function counting code. +This enables @code{gprof} to determine how many times each line +of code was executed. +For example, consider the following function, taken from gzip, +with line numbers added: + +@smallexample + 1 ulg updcrc(s, n) + 2 uch *s; + 3 unsigned n; + 4 @{ + 5 register ulg c; + 6 + 7 static ulg crc = (ulg)0xffffffffL; + 8 + 9 if (s == NULL) @{ +10 c = 0xffffffffL; +11 @} else @{ +12 c = crc; +13 if (n) do @{ +14 c = crc_32_tab[...]; +15 @} while (--n); +16 @} +17 crc = c; +18 return c ^ 0xffffffffL; +19 @} + +@end smallexample + +@code{updcrc} has at least five basic-blocks. +One is the function itself. The +@code{if} statement on line 9 generates two more basic-blocks, one +for each branch of the @code{if}. A fourth basic-block results from +the @code{if} on line 13, and the contents of the @code{do} loop form +the fifth basic-block. The compiler may also generate additional +basic-blocks to handle various special cases. + +A program augmented for basic-block counting can be analyzed with +@samp{gprof -l -A}. I also suggest use of the @samp{-x} option, +which ensures that each line of code is labeled at least once. +Here is @code{updcrc}'s +annotated source listing for a sample @code{gzip} run: + +@smallexample + ulg updcrc(s, n) + uch *s; + unsigned n; + 2 ->@{ + register ulg c; + + static ulg crc = (ulg)0xffffffffL; + + 2 -> if (s == NULL) @{ + 1 -> c = 0xffffffffL; + 1 -> @} else @{ + 1 -> c = crc; + 1 -> if (n) do @{ + 26312 -> c = crc_32_tab[...]; +26312,1,26311 -> @} while (--n); + @} + 2 -> crc = c; + 2 -> return c ^ 0xffffffffL; + 2 ->@} +@end smallexample + +In this example, the function was called twice, passing once through +each branch of the @code{if} statement. The body of the @code{do} +loop was executed a total of 26312 times. Note how the @code{while} +statement is annotated. It began execution 26312 times, once for +each iteration through the loop. One of those times (the last time) +it exited, while it branched back to the beginning of the loop 26311 times. + +@node Inaccuracy +@chapter Inaccuracy of @code{gprof} Output + +@menu +* Sampling Error:: Statistical margins of error +* Assumptions:: Estimating children times +@end menu + +@node Sampling Error,Assumptions,,Inaccuracy +@section Statistical Sampling Error + +The run-time figures that @code{gprof} gives you are based on a sampling +process, so they are subject to statistical inaccuracy. If a function runs +only a small amount of time, so that on the average the sampling process +ought to catch that function in the act only once, there is a pretty good +chance it will actually find that function zero times, or twice. + +By contrast, the number-of-calls and basic-block figures +are derived by counting, not +sampling. They are completely accurate and will not vary from run to run +if your program is deterministic. + +The @dfn{sampling period} that is printed at the beginning of the flat +profile says how often samples are taken. The rule of thumb is that a +run-time figure is accurate if it is considerably bigger than the sampling +period. + +The actual amount of error can be predicted. +For @var{n} samples, the @emph{expected} error +is the square-root of @var{n}. For example, +if the sampling period is 0.01 seconds and @code{foo}'s run-time is 1 second, +@var{n} is 100 samples (1 second/0.01 seconds), sqrt(@var{n}) is 10 samples, so +the expected error in @code{foo}'s run-time is 0.1 seconds (10*0.01 seconds), +or ten percent of the observed value. +Again, if the sampling period is 0.01 seconds and @code{bar}'s run-time is +100 seconds, @var{n} is 10000 samples, sqrt(@var{n}) is 100 samples, so +the expected error in @code{bar}'s run-time is 1 second, +or one percent of the observed value. +It is likely to +vary this much @emph{on the average} from one profiling run to the next. +(@emph{Sometimes} it will vary more.) + +This does not mean that a small run-time figure is devoid of information. +If the program's @emph{total} run-time is large, a small run-time for one +function does tell you that that function used an insignificant fraction of +the whole program's time. Usually this means it is not worth optimizing. + +One way to get more accuracy is to give your program more (but similar) +input data so it will take longer. Another way is to combine the data from +several runs, using the @samp{-s} option of @code{gprof}. Here is how: + +@enumerate +@item +Run your program once. + +@item +Issue the command @samp{mv gmon.out gmon.sum}. + +@item +Run your program again, the same as before. + +@item +Merge the new data in @file{gmon.out} into @file{gmon.sum} with this command: + +@example +gprof -s @var{executable-file} gmon.out gmon.sum +@end example + +@item +Repeat the last two steps as often as you wish. + +@item +Analyze the cumulative data using this command: + +@example +gprof @var{executable-file} gmon.sum > @var{output-file} +@end example +@end enumerate + +@node Assumptions,,Sampling Error,Inaccuracy +@section Estimating @code{children} Times + +Some of the figures in the call graph are estimates---for example, the +@code{children} time values and all the time figures in caller and +subroutine lines. + +There is no direct information about these measurements in the profile +data itself. Instead, @code{gprof} estimates them by making an assumption +about your program that might or might not be true. + +The assumption made is that the average time spent in each call to any +function @code{foo} is not correlated with who called @code{foo}. If +@code{foo} used 5 seconds in all, and 2/5 of the calls to @code{foo} came +from @code{a}, then @code{foo} contributes 2 seconds to @code{a}'s +@code{children} time, by assumption. + +This assumption is usually true enough, but for some programs it is far +from true. Suppose that @code{foo} returns very quickly when its argument +is zero; suppose that @code{a} always passes zero as an argument, while +other callers of @code{foo} pass other arguments. In this program, all the +time spent in @code{foo} is in the calls from callers other than @code{a}. +But @code{gprof} has no way of knowing this; it will blindly and +incorrectly charge 2 seconds of time in @code{foo} to the children of +@code{a}. + +@c FIXME - has this been fixed? +We hope some day to put more complete data into @file{gmon.out}, so that +this assumption is no longer needed, if we can figure out how. For the +nonce, the estimated figures are usually more useful than misleading. + +@node How do I? +@chapter Answers to Common Questions + +@table @asis +@item How can I get more exact information about hot spots in my program? + +Looking at the per-line call counts only tells part of the story. +Because @code{gprof} can only report call times and counts by function, +the best way to get finer-grained information on where the program +is spending its time is to re-factor large functions into sequences +of calls to smaller ones. Beware however that this can introduce +artifical hot spots since compiling with @samp{-pg} adds a significant +overhead to function calls. An alternative solution is to use a +non-intrusive profiler, e.g.@: oprofile. + +@item How do I find which lines in my program were executed the most times? + +Compile your program with basic-block counting enabled, run it, then +use the following pipeline: + +@example +gprof -l -C @var{objfile} | sort -k 3 -n -r +@end example + +This listing will show you the lines in your code executed most often, +but not necessarily those that consumed the most time. + +@item How do I find which lines in my program called a particular function? + +Use @samp{gprof -l} and lookup the function in the call graph. +The callers will be broken down by function and line number. + +@item How do I analyze a program that runs for less than a second? + +Try using a shell script like this one: + +@example +for i in `seq 1 100`; do + fastprog + mv gmon.out gmon.out.$i +done + +gprof -s fastprog gmon.out.* + +gprof fastprog gmon.sum +@end example + +If your program is completely deterministic, all the call counts +will be simple multiples of 100 (i.e. a function called once in +each run will appear with a call count of 100). + +@end table + +@node Incompatibilities +@chapter Incompatibilities with Unix @code{gprof} + +@sc{gnu} @code{gprof} and Berkeley Unix @code{gprof} use the same data +file @file{gmon.out}, and provide essentially the same information. But +there are a few differences. + +@itemize @bullet +@item +@sc{gnu} @code{gprof} uses a new, generalized file format with support +for basic-block execution counts and non-realtime histograms. A magic +cookie and version number allows @code{gprof} to easily identify +new style files. Old BSD-style files can still be read. +@xref{File Format}. + +@item +For a recursive function, Unix @code{gprof} lists the function as a +parent and as a child, with a @code{calls} field that lists the number +of recursive calls. @sc{gnu} @code{gprof} omits these lines and puts +the number of recursive calls in the primary line. + +@item +When a function is suppressed from the call graph with @samp{-e}, @sc{gnu} +@code{gprof} still lists it as a subroutine of functions that call it. + +@item +@sc{gnu} @code{gprof} accepts the @samp{-k} with its argument +in the form @samp{from/to}, instead of @samp{from to}. + +@item +In the annotated source listing, +if there are multiple basic blocks on the same line, +@sc{gnu} @code{gprof} prints all of their counts, separated by commas. + +@ignore - it does this now +@item +The function names printed in @sc{gnu} @code{gprof} output do not include +the leading underscores that are added internally to the front of all +C identifiers on many operating systems. +@end ignore + +@item +The blurbs, field widths, and output formats are different. @sc{gnu} +@code{gprof} prints blurbs after the tables, so that you can see the +tables without skipping the blurbs. +@end itemize + +@node Details +@chapter Details of Profiling + +@menu +* Implementation:: How a program collects profiling information +* File Format:: Format of @samp{gmon.out} files +* Internals:: @code{gprof}'s internal operation +* Debugging:: Using @code{gprof}'s @samp{-d} option +@end menu + +@node Implementation,File Format,,Details +@section Implementation of Profiling + +Profiling works by changing how every function in your program is compiled +so that when it is called, it will stash away some information about where +it was called from. From this, the profiler can figure out what function +called it, and can count how many times it was called. This change is made +by the compiler when your program is compiled with the @samp{-pg} option, +which causes every function to call @code{mcount} +(or @code{_mcount}, or @code{__mcount}, depending on the OS and compiler) +as one of its first operations. + +The @code{mcount} routine, included in the profiling library, +is responsible for recording in an in-memory call graph table +both its parent routine (the child) and its parent's parent. This is +typically done by examining the stack frame to find both +the address of the child, and the return address in the original parent. +Since this is a very machine-dependent operation, @code{mcount} +itself is typically a short assembly-language stub routine +that extracts the required +information, and then calls @code{__mcount_internal} +(a normal C function) with two arguments - @code{frompc} and @code{selfpc}. +@code{__mcount_internal} is responsible for maintaining +the in-memory call graph, which records @code{frompc}, @code{selfpc}, +and the number of times each of these call arcs was traversed. + +GCC Version 2 provides a magical function (@code{__builtin_return_address}), +which allows a generic @code{mcount} function to extract the +required information from the stack frame. However, on some +architectures, most notably the SPARC, using this builtin can be +very computationally expensive, and an assembly language version +of @code{mcount} is used for performance reasons. + +Number-of-calls information for library routines is collected by using a +special version of the C library. The programs in it are the same as in +the usual C library, but they were compiled with @samp{-pg}. If you +link your program with @samp{gcc @dots{} -pg}, it automatically uses the +profiling version of the library. + +Profiling also involves watching your program as it runs, and keeping a +histogram of where the program counter happens to be every now and then. +Typically the program counter is looked at around 100 times per second of +run time, but the exact frequency may vary from system to system. + +This is done is one of two ways. Most UNIX-like operating systems +provide a @code{profil()} system call, which registers a memory +array with the kernel, along with a scale +factor that determines how the program's address space maps +into the array. +Typical scaling values cause every 2 to 8 bytes of address space +to map into a single array slot. +On every tick of the system clock +(assuming the profiled program is running), the value of the +program counter is examined and the corresponding slot in +the memory array is incremented. Since this is done in the kernel, +which had to interrupt the process anyway to handle the clock +interrupt, very little additional system overhead is required. + +However, some operating systems, most notably Linux 2.0 (and earlier), +do not provide a @code{profil()} system call. On such a system, +arrangements are made for the kernel to periodically deliver +a signal to the process (typically via @code{setitimer()}), +which then performs the same operation of examining the +program counter and incrementing a slot in the memory array. +Since this method requires a signal to be delivered to +user space every time a sample is taken, it uses considerably +more overhead than kernel-based profiling. Also, due to the +added delay required to deliver the signal, this method is +less accurate as well. + +A special startup routine allocates memory for the histogram and +either calls @code{profil()} or sets up +a clock signal handler. +This routine (@code{monstartup}) can be invoked in several ways. +On Linux systems, a special profiling startup file @code{gcrt0.o}, +which invokes @code{monstartup} before @code{main}, +is used instead of the default @code{crt0.o}. +Use of this special startup file is one of the effects +of using @samp{gcc @dots{} -pg} to link. +On SPARC systems, no special startup files are used. +Rather, the @code{mcount} routine, when it is invoked for +the first time (typically when @code{main} is called), +calls @code{monstartup}. + +If the compiler's @samp{-a} option was used, basic-block counting +is also enabled. Each object file is then compiled with a static array +of counts, initially zero. +In the executable code, every time a new basic-block begins +(i.e. when an @code{if} statement appears), an extra instruction +is inserted to increment the corresponding count in the array. +At compile time, a paired array was constructed that recorded +the starting address of each basic-block. Taken together, +the two arrays record the starting address of every basic-block, +along with the number of times it was executed. + +The profiling library also includes a function (@code{mcleanup}) which is +typically registered using @code{atexit()} to be called as the +program exits, and is responsible for writing the file @file{gmon.out}. +Profiling is turned off, various headers are output, and the histogram +is written, followed by the call-graph arcs and the basic-block counts. + +The output from @code{gprof} gives no indication of parts of your program that +are limited by I/O or swapping bandwidth. This is because samples of the +program counter are taken at fixed intervals of the program's run time. +Therefore, the +time measurements in @code{gprof} output say nothing about time that your +program was not running. For example, a part of the program that creates +so much data that it cannot all fit in physical memory at once may run very +slowly due to thrashing, but @code{gprof} will say it uses little time. On +the other hand, sampling by run time has the advantage that the amount of +load due to other users won't directly affect the output you get. + +@node File Format,Internals,Implementation,Details +@section Profiling Data File Format + +The old BSD-derived file format used for profile data does not contain a +magic cookie that allows to check whether a data file really is a +@code{gprof} file. Furthermore, it does not provide a version number, thus +rendering changes to the file format almost impossible. @sc{gnu} @code{gprof} +uses a new file format that provides these features. For backward +compatibility, @sc{gnu} @code{gprof} continues to support the old BSD-derived +format, but not all features are supported with it. For example, +basic-block execution counts cannot be accommodated by the old file +format. + +The new file format is defined in header file @file{gmon_out.h}. It +consists of a header containing the magic cookie and a version number, +as well as some spare bytes available for future extensions. All data +in a profile data file is in the native format of the target for which +the profile was collected. @sc{gnu} @code{gprof} adapts automatically +to the byte-order in use. + +In the new file format, the header is followed by a sequence of +records. Currently, there are three different record types: histogram +records, call-graph arc records, and basic-block execution count +records. Each file can contain any number of each record type. When +reading a file, @sc{gnu} @code{gprof} will ensure records of the same type are +compatible with each other and compute the union of all records. For +example, for basic-block execution counts, the union is simply the sum +of all execution counts for each basic-block. + +@subsection Histogram Records + +Histogram records consist of a header that is followed by an array of +bins. The header contains the text-segment range that the histogram +spans, the size of the histogram in bytes (unlike in the old BSD +format, this does not include the size of the header), the rate of the +profiling clock, and the physical dimension that the bin counts +represent after being scaled by the profiling clock rate. The +physical dimension is specified in two parts: a long name of up to 15 +characters and a single character abbreviation. For example, a +histogram representing real-time would specify the long name as +"seconds" and the abbreviation as "s". This feature is useful for +architectures that support performance monitor hardware (which, +fortunately, is becoming increasingly common). For example, under DEC +OSF/1, the "uprofile" command can be used to produce a histogram of, +say, instruction cache misses. In this case, the dimension in the +histogram header could be set to "i-cache misses" and the abbreviation +could be set to "1" (because it is simply a count, not a physical +dimension). Also, the profiling rate would have to be set to 1 in +this case. + +Histogram bins are 16-bit numbers and each bin represent an equal +amount of text-space. For example, if the text-segment is one +thousand bytes long and if there are ten bins in the histogram, each +bin represents one hundred bytes. + + +@subsection Call-Graph Records + +Call-graph records have a format that is identical to the one used in +the BSD-derived file format. It consists of an arc in the call graph +and a count indicating the number of times the arc was traversed +during program execution. Arcs are specified by a pair of addresses: +the first must be within caller's function and the second must be +within the callee's function. When performing profiling at the +function level, these addresses can point anywhere within the +respective function. However, when profiling at the line-level, it is +better if the addresses are as close to the call-site/entry-point as +possible. This will ensure that the line-level call-graph is able to +identify exactly which line of source code performed calls to a +function. + +@subsection Basic-Block Execution Count Records + +Basic-block execution count records consist of a header followed by a +sequence of address/count pairs. The header simply specifies the +length of the sequence. In an address/count pair, the address +identifies a basic-block and the count specifies the number of times +that basic-block was executed. Any address within the basic-address can +be used. + +@node Internals,Debugging,File Format,Details +@section @code{gprof}'s Internal Operation + +Like most programs, @code{gprof} begins by processing its options. +During this stage, it may building its symspec list +(@code{sym_ids.c:sym_id_add}), if +options are specified which use symspecs. +@code{gprof} maintains a single linked list of symspecs, +which will eventually get turned into 12 symbol tables, +organized into six include/exclude pairs - one +pair each for the flat profile (INCL_FLAT/EXCL_FLAT), +the call graph arcs (INCL_ARCS/EXCL_ARCS), +printing in the call graph (INCL_GRAPH/EXCL_GRAPH), +timing propagation in the call graph (INCL_TIME/EXCL_TIME), +the annotated source listing (INCL_ANNO/EXCL_ANNO), +and the execution count listing (INCL_EXEC/EXCL_EXEC). + +After option processing, @code{gprof} finishes +building the symspec list by adding all the symspecs in +@code{default_excluded_list} to the exclude lists +EXCL_TIME and EXCL_GRAPH, and if line-by-line profiling is specified, +EXCL_FLAT as well. +These default excludes are not added to EXCL_ANNO, EXCL_ARCS, and EXCL_EXEC. + +Next, the BFD library is called to open the object file, +verify that it is an object file, +and read its symbol table (@code{core.c:core_init}), +using @code{bfd_canonicalize_symtab} after mallocing +an appropriately sized array of symbols. At this point, +function mappings are read (if the @samp{--file-ordering} option +has been specified), and the core text space is read into +memory (if the @samp{-c} option was given). + +@code{gprof}'s own symbol table, an array of Sym structures, +is now built. +This is done in one of two ways, by one of two routines, depending +on whether line-by-line profiling (@samp{-l} option) has been +enabled. +For normal profiling, the BFD canonical symbol table is scanned. +For line-by-line profiling, every +text space address is examined, and a new symbol table entry +gets created every time the line number changes. +In either case, two passes are made through the symbol +table - one to count the size of the symbol table required, +and the other to actually read the symbols. In between the +two passes, a single array of type @code{Sym} is created of +the appropriate length. +Finally, @code{symtab.c:symtab_finalize} +is called to sort the symbol table and remove duplicate entries +(entries with the same memory address). + +The symbol table must be a contiguous array for two reasons. +First, the @code{qsort} library function (which sorts an array) +will be used to sort the symbol table. +Also, the symbol lookup routine (@code{symtab.c:sym_lookup}), +which finds symbols +based on memory address, uses a binary search algorithm +which requires the symbol table to be a sorted array. +Function symbols are indicated with an @code{is_func} flag. +Line number symbols have no special flags set. +Additionally, a symbol can have an @code{is_static} flag +to indicate that it is a local symbol. + +With the symbol table read, the symspecs can now be translated +into Syms (@code{sym_ids.c:sym_id_parse}). Remember that a single +symspec can match multiple symbols. +An array of symbol tables +(@code{syms}) is created, each entry of which is a symbol table +of Syms to be included or excluded from a particular listing. +The master symbol table and the symspecs are examined by nested +loops, and every symbol that matches a symspec is inserted +into the appropriate syms table. This is done twice, once to +count the size of each required symbol table, and again to build +the tables, which have been malloced between passes. +From now on, to determine whether a symbol is on an include +or exclude symspec list, @code{gprof} simply uses its +standard symbol lookup routine on the appropriate table +in the @code{syms} array. + +Now the profile data file(s) themselves are read +(@code{gmon_io.c:gmon_out_read}), +first by checking for a new-style @samp{gmon.out} header, +then assuming this is an old-style BSD @samp{gmon.out} +if the magic number test failed. + +New-style histogram records are read by @code{hist.c:hist_read_rec}. +For the first histogram record, allocate a memory array to hold +all the bins, and read them in. +When multiple profile data files (or files with multiple histogram +records) are read, the starting address, ending address, number +of bins and sampling rate must match between the various histograms, +or a fatal error will result. +If everything matches, just sum the additional histograms into +the existing in-memory array. + +As each call graph record is read (@code{call_graph.c:cg_read_rec}), +the parent and child addresses +are matched to symbol table entries, and a call graph arc is +created by @code{cg_arcs.c:arc_add}, unless the arc fails a symspec +check against INCL_ARCS/EXCL_ARCS. As each arc is added, +a linked list is maintained of the parent's child arcs, and of the child's +parent arcs. +Both the child's call count and the arc's call count are +incremented by the record's call count. + +Basic-block records are read (@code{basic_blocks.c:bb_read_rec}), +but only if line-by-line profiling has been selected. +Each basic-block address is matched to a corresponding line +symbol in the symbol table, and an entry made in the symbol's +bb_addr and bb_calls arrays. Again, if multiple basic-block +records are present for the same address, the call counts +are cumulative. + +A gmon.sum file is dumped, if requested (@code{gmon_io.c:gmon_out_write}). + +If histograms were present in the data files, assign them to symbols +(@code{hist.c:hist_assign_samples}) by iterating over all the sample +bins and assigning them to symbols. Since the symbol table +is sorted in order of ascending memory addresses, we can +simple follow along in the symbol table as we make our pass +over the sample bins. +This step includes a symspec check against INCL_FLAT/EXCL_FLAT. +Depending on the histogram +scale factor, a sample bin may span multiple symbols, +in which case a fraction of the sample count is allocated +to each symbol, proportional to the degree of overlap. +This effect is rare for normal profiling, but overlaps +are more common during line-by-line profiling, and can +cause each of two adjacent lines to be credited with half +a hit, for example. + +If call graph data is present, @code{cg_arcs.c:cg_assemble} is called. +First, if @samp{-c} was specified, a machine-dependent +routine (@code{find_call}) scans through each symbol's machine code, +looking for subroutine call instructions, and adding them +to the call graph with a zero call count. +A topological sort is performed by depth-first numbering +all the symbols (@code{cg_dfn.c:cg_dfn}), so that +children are always numbered less than their parents, +then making a array of pointers into the symbol table and sorting it into +numerical order, which is reverse topological +order (children appear before parents). +Cycles are also detected at this point, all members +of which are assigned the same topological number. +Two passes are now made through this sorted array of symbol pointers. +The first pass, from end to beginning (parents to children), +computes the fraction of child time to propagate to each parent +and a print flag. +The print flag reflects symspec handling of INCL_GRAPH/EXCL_GRAPH, +with a parent's include or exclude (print or no print) property +being propagated to its children, unless they themselves explicitly appear +in INCL_GRAPH or EXCL_GRAPH. +A second pass, from beginning to end (children to parents) actually +propagates the timings along the call graph, subject +to a check against INCL_TIME/EXCL_TIME. +With the print flag, fractions, and timings now stored in the symbol +structures, the topological sort array is now discarded, and a +new array of pointers is assembled, this time sorted by propagated time. + +Finally, print the various outputs the user requested, which is now fairly +straightforward. The call graph (@code{cg_print.c:cg_print}) and +flat profile (@code{hist.c:hist_print}) are regurgitations of values +already computed. The annotated source listing +(@code{basic_blocks.c:print_annotated_source}) uses basic-block +information, if present, to label each line of code with call counts, +otherwise only the function call counts are presented. + +The function ordering code is marginally well documented +in the source code itself (@code{cg_print.c}). Basically, +the functions with the most use and the most parents are +placed first, followed by other functions with the most use, +followed by lower use functions, followed by unused functions +at the end. + +@node Debugging,,Internals,Details +@subsection Debugging @code{gprof} + +If @code{gprof} was compiled with debugging enabled, +the @samp{-d} option triggers debugging output +(to stdout) which can be helpful in understanding its operation. +The debugging number specified is interpreted as a sum of the following +options: + +@table @asis +@item 2 - Topological sort +Monitor depth-first numbering of symbols during call graph analysis +@item 4 - Cycles +Shows symbols as they are identified as cycle heads +@item 16 - Tallying +As the call graph arcs are read, show each arc and how +the total calls to each function are tallied +@item 32 - Call graph arc sorting +Details sorting individual parents/children within each call graph entry +@item 64 - Reading histogram and call graph records +Shows address ranges of histograms as they are read, and each +call graph arc +@item 128 - Symbol table +Reading, classifying, and sorting the symbol table from the object file. +For line-by-line profiling (@samp{-l} option), also shows line numbers +being assigned to memory addresses. +@item 256 - Static call graph +Trace operation of @samp{-c} option +@item 512 - Symbol table and arc table lookups +Detail operation of lookup routines +@item 1024 - Call graph propagation +Shows how function times are propagated along the call graph +@item 2048 - Basic-blocks +Shows basic-block records as they are read from profile data +(only meaningful with @samp{-l} option) +@item 4096 - Symspecs +Shows symspec-to-symbol pattern matching operation +@item 8192 - Annotate source +Tracks operation of @samp{-A} option +@end table + +@node GNU Free Documentation License +@chapter GNU Free Documentation License + + GNU Free Documentation License + + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". +@end smallexample + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@contents +@bye + +NEEDS AN INDEX + +-T - "traditional BSD style": How is it different? Should the +differences be documented? + +example flat file adds up to 100.01%... + +note: time estimates now only go out to one decimal place (0.0), where +they used to extend two (78.67). diff --git a/gprof/hertz.c b/gprof/hertz.c new file mode 100644 index 000000000000..6fa1db49ce2d --- /dev/null +++ b/gprof/hertz.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "hertz.h" + + +int +hertz () +{ +#ifdef HERTZ + return HERTZ; +#else /* ! defined (HERTZ) */ +#ifdef HAVE_SETITIMER + struct itimerval tim; + + tim.it_interval.tv_sec = 0; + tim.it_interval.tv_usec = 1; + tim.it_value.tv_sec = 0; + tim.it_value.tv_usec = 0; + setitimer (ITIMER_REAL, &tim, 0); + setitimer (ITIMER_REAL, 0, &tim); + if (tim.it_interval.tv_usec >= 2) + { + return 1000000 / tim.it_interval.tv_usec; + } +#endif /* ! defined (HAVE_SETITIMER) */ +#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK) + return sysconf (_SC_CLK_TCK); +#else /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */ +#ifdef __MSDOS__ + return 18; +#else /* ! defined (__MSDOS__) */ + return HZ_WRONG; +#endif /* ! defined (__MSDOS__) */ +#endif /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */ +#endif /* ! defined (HERTZ) */ +} diff --git a/gprof/hertz.h b/gprof/hertz.h new file mode 100644 index 000000000000..7f8b3ee58b21 --- /dev/null +++ b/gprof/hertz.h @@ -0,0 +1,13 @@ +#ifndef hertz_h +#define hertz_h + +#define HZ_WRONG 0 /* impossible clock frequency */ + +/* + * Discover the tick frequency of the machine if something goes wrong, + * we return HZ_WRONG, an impossible sampling frequency. + */ + +extern int hertz PARAMS ((void)); + +#endif /* hertz_h */ diff --git a/gprof/hist.c b/gprof/hist.c new file mode 100644 index 000000000000..bfa34eebf083 --- /dev/null +++ b/gprof/hist.c @@ -0,0 +1,562 @@ +/* hist.c - Histogram related operations. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "corefile.h" +#include "gmon_io.h" +#include "gmon_out.h" +#include "hist.h" +#include "sym_ids.h" +#include "utils.h" + +#define UNITS_TO_CODE (offset_to_code / sizeof(UNIT)) + +static void scale_and_align_entries PARAMS ((void)); +static void print_header PARAMS ((int)); +static void print_line PARAMS ((Sym *, double)); +static int cmp_time PARAMS ((const PTR, const PTR)); + +/* Declarations of automatically generated functions to output blurbs. */ +extern void flat_blurb PARAMS ((FILE * fp)); + +bfd_vma s_lowpc; /* Lowest address in .text. */ +bfd_vma s_highpc = 0; /* Highest address in .text. */ +bfd_vma lowpc, highpc; /* Same, but expressed in UNITs. */ +int hist_num_bins = 0; /* Number of histogram samples. */ +int *hist_sample = 0; /* Histogram samples (shorts in the file!). */ +double hist_scale; +char hist_dimension[16] = "seconds"; +char hist_dimension_abbrev = 's'; + +static double accum_time; /* Accumulated time so far for print_line(). */ +static double total_time; /* Total time for all routines. */ + +/* Table of SI prefixes for powers of 10 (used to automatically + scale some of the values in the flat profile). */ +const struct + { + char prefix; + double scale; + } +SItab[] = +{ + { 'T', 1e-12 }, /* tera */ + { 'G', 1e-09 }, /* giga */ + { 'M', 1e-06 }, /* mega */ + { 'K', 1e-03 }, /* kilo */ + { ' ', 1e-00 }, + { 'm', 1e+03 }, /* milli */ + { 'u', 1e+06 }, /* micro */ + { 'n', 1e+09 }, /* nano */ + { 'p', 1e+12 }, /* pico */ + { 'f', 1e+15 }, /* femto */ + { 'a', 1e+18 } /* ato */ +}; + + +/* Read the histogram from file IFP. FILENAME is the name of IFP and + is provided for formatting error messages only. */ + +void +hist_read_rec (ifp, filename) + FILE * ifp; + const char *filename; +{ + bfd_vma n_lowpc, n_highpc; + int i, ncnt, profrate; + UNIT count; + + if (gmon_io_read_vma (ifp, &n_lowpc) + || gmon_io_read_vma (ifp, &n_highpc) + || gmon_io_read_32 (ifp, &ncnt) + || gmon_io_read_32 (ifp, &profrate) + || gmon_io_read (ifp, hist_dimension, 15) + || gmon_io_read (ifp, &hist_dimension_abbrev, 1)) + { + fprintf (stderr, _("%s: %s: unexpected end of file\n"), + whoami, filename); + + done (1); + } + + if (!s_highpc) + { + /* This is the first histogram record. */ + s_lowpc = n_lowpc; + s_highpc = n_highpc; + lowpc = (bfd_vma) n_lowpc / sizeof (UNIT); + highpc = (bfd_vma) n_highpc / sizeof (UNIT); + hist_num_bins = ncnt; + hz = profrate; + } + + DBG (SAMPLEDEBUG, + printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %d\n", + (unsigned long) n_lowpc, (unsigned long) n_highpc, ncnt); + printf ("[hist_read_rec] s_lowpc 0x%lx s_highpc 0x%lx nsamples %d\n", + (unsigned long) s_lowpc, (unsigned long) s_highpc, + hist_num_bins); + printf ("[hist_read_rec] lowpc 0x%lx highpc 0x%lx\n", + (unsigned long) lowpc, (unsigned long) highpc)); + + if (n_lowpc != s_lowpc || n_highpc != s_highpc + || ncnt != hist_num_bins || hz != profrate) + { + fprintf (stderr, _("%s: `%s' is incompatible with first gmon file\n"), + whoami, filename); + done (1); + } + + if (!hist_sample) + { + hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0])); + memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0])); + } + + for (i = 0; i < hist_num_bins; ++i) + { + if (fread (&count[0], sizeof (count), 1, ifp) != 1) + { + fprintf (stderr, + _("%s: %s: unexpected EOF after reading %d of %d samples\n"), + whoami, filename, i, hist_num_bins); + done (1); + } + hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]); + DBG (SAMPLEDEBUG, + printf ("[hist_read_rec] 0x%lx: %u\n", + (unsigned long) (n_lowpc + i * (n_highpc - n_lowpc) / ncnt), + hist_sample[i])); + } +} + + +/* Write execution histogram to file OFP. FILENAME is the name + of OFP and is provided for formatting error-messages only. */ + +void +hist_write_hist (ofp, filename) + FILE * ofp; + const char *filename; +{ + UNIT count; + int i; + + /* Write header. */ + + if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST) + || gmon_io_write_vma (ofp, s_lowpc) + || gmon_io_write_vma (ofp, s_highpc) + || gmon_io_write_32 (ofp, hist_num_bins) + || gmon_io_write_32 (ofp, hz) + || gmon_io_write (ofp, hist_dimension, 15) + || gmon_io_write (ofp, &hist_dimension_abbrev, 1)) + { + perror (filename); + done (1); + } + + for (i = 0; i < hist_num_bins; ++i) + { + bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i], (bfd_byte *) &count[0]); + + if (fwrite (&count[0], sizeof (count), 1, ofp) != 1) + { + perror (filename); + done (1); + } + } +} + + +/* Calculate scaled entry point addresses (to save time in + hist_assign_samples), and, on architectures that have procedure + entry masks at the start of a function, possibly push the scaled + entry points over the procedure entry mask, if it turns out that + the entry point is in one bin and the code for a routine is in the + next bin. */ + +static void +scale_and_align_entries () +{ + Sym *sym; + bfd_vma bin_of_entry; + bfd_vma bin_of_code; + + for (sym = symtab.base; sym < symtab.limit; sym++) + { + sym->hist.scaled_addr = sym->addr / sizeof (UNIT); + bin_of_entry = (sym->hist.scaled_addr - lowpc) / hist_scale; + bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - lowpc) + / hist_scale); + if (bin_of_entry < bin_of_code) + { + DBG (SAMPLEDEBUG, + printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n", + (unsigned long) sym->hist.scaled_addr, + (unsigned long) (sym->hist.scaled_addr + + UNITS_TO_CODE))); + sym->hist.scaled_addr += UNITS_TO_CODE; + } + } +} + + +/* Assign samples to the symbol to which they belong. + + Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC) + which may overlap one more symbol address ranges. If a symbol + overlaps with the bin's address range by O percent, then O percent + of the bin's count is credited to that symbol. + + There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be + with respect to the symbol's address range [SYM_LOW_PC, + SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes + the distance (in UNITs) between the arrows, the fraction of the + sample that is to be credited to the symbol which starts at + SYM_LOW_PC. + + sym_low_pc sym_high_pc + | | + v v + + +-----------------------------------------------+ + | | + | ->| |<- ->| |<- ->| |<- | + | | | | | | + +---------+ +---------+ +---------+ + + ^ ^ ^ ^ ^ ^ + | | | | | | + bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc + + For the VAX we assert that samples will never fall in the first two + bytes of any routine, since that is the entry mask, thus we call + scale_and_align_entries() to adjust the entry points if the entry + mask falls in one bin but the code for the routine doesn't start + until the next bin. In conjunction with the alignment of routine + addresses, this should allow us to have only one sample for every + four bytes of text space and never have any overlap (the two end + cases, above). */ + +void +hist_assign_samples () +{ + bfd_vma bin_low_pc, bin_high_pc; + bfd_vma sym_low_pc, sym_high_pc; + bfd_vma overlap, addr; + int bin_count, i; + unsigned int j; + double time, credit; + + /* Read samples and assign to symbols. */ + hist_scale = highpc - lowpc; + hist_scale /= hist_num_bins; + scale_and_align_entries (); + + /* Iterate over all sample bins. */ + for (i = 0, j = 1; i < hist_num_bins; ++i) + { + bin_count = hist_sample[i]; + if (! bin_count) + continue; + + bin_low_pc = lowpc + (bfd_vma) (hist_scale * i); + bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1)); + time = bin_count; + + DBG (SAMPLEDEBUG, + printf ( + "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%d\n", + (unsigned long) (sizeof (UNIT) * bin_low_pc), + (unsigned long) (sizeof (UNIT) * bin_high_pc), + bin_count)); + total_time += time; + + /* Credit all symbols that are covered by bin I. */ + for (j = j - 1; j < symtab.len; ++j) + { + sym_low_pc = symtab.base[j].hist.scaled_addr; + sym_high_pc = symtab.base[j + 1].hist.scaled_addr; + + /* If high end of bin is below entry address, + go for next bin. */ + if (bin_high_pc < sym_low_pc) + break; + + /* If low end of bin is above high end of symbol, + go for next symbol. */ + if (bin_low_pc >= sym_high_pc) + continue; + + overlap = + MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc); + if (overlap > 0) + { + DBG (SAMPLEDEBUG, + printf ( + "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n", + (unsigned long) symtab.base[j].addr, + (unsigned long) (sizeof (UNIT) * sym_high_pc), + symtab.base[j].name, overlap * time / hist_scale, + (long) overlap)); + + addr = symtab.base[j].addr; + credit = overlap * time / hist_scale; + + /* Credit symbol if it appears in INCL_FLAT or that + table is empty and it does not appear it in + EXCL_FLAT. */ + if (sym_lookup (&syms[INCL_FLAT], addr) + || (syms[INCL_FLAT].len == 0 + && !sym_lookup (&syms[EXCL_FLAT], addr))) + { + symtab.base[j].hist.time += credit; + } + else + { + total_time -= credit; + } + } + } + } + + DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n", + total_time)); +} + + +/* Print header for flag histogram profile. */ + +static void +print_header (prefix) + int prefix; +{ + char unit[64]; + + sprintf (unit, _("%c%c/call"), prefix, hist_dimension_abbrev); + + if (bsd_style_output) + { + printf (_("\ngranularity: each sample hit covers %ld byte(s)"), + (long) hist_scale * sizeof (UNIT)); + if (total_time > 0.0) + { + printf (_(" for %.2f%% of %.2f %s\n\n"), + 100.0 / total_time, total_time / hz, hist_dimension); + } + } + else + { + printf (_("\nEach sample counts as %g %s.\n"), 1.0 / hz, hist_dimension); + } + + if (total_time <= 0.0) + { + printf (_(" no time accumulated\n\n")); + + /* This doesn't hurt since all the numerators will be zero. */ + total_time = 1.0; + } + + printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n", + "% ", _("cumulative"), _("self "), "", _("self "), _("total "), + ""); + printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n", + _("time"), hist_dimension, hist_dimension, _("calls"), unit, unit, + _("name")); +} + + +static void +print_line (sym, scale) + Sym *sym; + double scale; +{ + if (ignore_zeros && sym->ncalls == 0 && sym->hist.time == 0) + return; + + accum_time += sym->hist.time; + + if (bsd_style_output) + printf ("%5.1f %10.2f %8.2f", + total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0, + accum_time / hz, sym->hist.time / hz); + else + printf ("%6.2f %9.2f %8.2f", + total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0, + accum_time / hz, sym->hist.time / hz); + + if (sym->ncalls != 0) + printf (" %8lu %8.2f %8.2f ", + sym->ncalls, scale * sym->hist.time / hz / sym->ncalls, + scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls); + else + printf (" %8.8s %8.8s %8.8s ", "", "", ""); + + if (bsd_style_output) + print_name (sym); + else + print_name_only (sym); + + printf ("\n"); +} + + +/* Compare LP and RP. The primary comparison key is execution time, + the secondary is number of invocation, and the tertiary is the + lexicographic order of the function names. */ + +static int +cmp_time (lp, rp) + const PTR lp; + const PTR rp; +{ + const Sym *left = *(const Sym **) lp; + const Sym *right = *(const Sym **) rp; + double time_diff; + + time_diff = right->hist.time - left->hist.time; + + if (time_diff > 0.0) + return 1; + + if (time_diff < 0.0) + return -1; + + if (right->ncalls > left->ncalls) + return 1; + + if (right->ncalls < left->ncalls) + return -1; + + return strcmp (left->name, right->name); +} + + +/* Print the flat histogram profile. */ + +void +hist_print () +{ + Sym **time_sorted_syms, *top_dog, *sym; + unsigned int index; + unsigned log_scale; + double top_time, time; + bfd_vma addr; + + if (first_output) + first_output = FALSE; + else + printf ("\f\n"); + + accum_time = 0.0; + + if (bsd_style_output) + { + if (print_descriptions) + { + printf (_("\n\n\nflat profile:\n")); + flat_blurb (stdout); + } + } + else + { + printf (_("Flat profile:\n")); + } + + /* Sort the symbol table by time (call-count and name as secondary + and tertiary keys). */ + time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); + + for (index = 0; index < symtab.len; ++index) + time_sorted_syms[index] = &symtab.base[index]; + + qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time); + + if (bsd_style_output) + { + log_scale = 5; /* Milli-seconds is BSD-default. */ + } + else + { + /* Search for symbol with highest per-call + execution time and scale accordingly. */ + log_scale = 0; + top_dog = 0; + top_time = 0.0; + + for (index = 0; index < symtab.len; ++index) + { + sym = time_sorted_syms[index]; + + if (sym->ncalls != 0) + { + time = (sym->hist.time + sym->cg.child_time) / sym->ncalls; + + if (time > top_time) + { + top_dog = sym; + top_time = time; + } + } + } + + if (top_dog && top_dog->ncalls != 0 && top_time > 0.0) + { + top_time /= hz; + + for (log_scale = 0; log_scale < ARRAY_SIZE (SItab); log_scale ++) + { + double scaled_value = SItab[log_scale].scale * top_time; + + if (scaled_value >= 1.0 && scaled_value < 1000.0) + break; + } + } + } + + /* For now, the dimension is always seconds. In the future, we + may also want to support other (pseudo-)dimensions (such as + I-cache misses etc.). */ + print_header (SItab[log_scale].prefix); + + for (index = 0; index < symtab.len; ++index) + { + addr = time_sorted_syms[index]->addr; + + /* Print symbol if its in INCL_FLAT table or that table + is empty and the symbol is not in EXCL_FLAT. */ + if (sym_lookup (&syms[INCL_FLAT], addr) + || (syms[INCL_FLAT].len == 0 + && !sym_lookup (&syms[EXCL_FLAT], addr))) + print_line (time_sorted_syms[index], SItab[log_scale].scale); + } + + free (time_sorted_syms); + + if (print_descriptions && !bsd_style_output) + flat_blurb (stdout); +} diff --git a/gprof/hist.h b/gprof/hist.h new file mode 100644 index 000000000000..fe4362bdec01 --- /dev/null +++ b/gprof/hist.h @@ -0,0 +1,40 @@ +/* hist.h + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef hist_h +#define hist_h + +extern bfd_vma s_lowpc; /* Lowpc from the profile file. */ +extern bfd_vma s_highpc; /* Highpc from the profile file. */ +extern bfd_vma lowpc, highpc; /* Range profiled, in UNIT's. */ +extern int hist_num_bins; /* Number of histogram bins. */ +extern int *hist_sample; /* Code histogram. */ + +/* Scale factor converting samples to pc values: + each sample covers HIST_SCALE bytes. */ +extern double hist_scale; + + +extern void hist_read_rec PARAMS ((FILE *, const char *)); +extern void hist_write_hist PARAMS ((FILE *, const char *)); +extern void hist_assign_samples PARAMS ((void)); +extern void hist_print PARAMS ((void)); + +#endif /* hist_h */ diff --git a/gprof/i386.c b/gprof/i386.c new file mode 100644 index 000000000000..0fcaa78a7197 --- /dev/null +++ b/gprof/i386.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1983, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" + +static int i386_iscall PARAMS ((unsigned char *)); +void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +static int +i386_iscall (ip) + unsigned char *ip; +{ + if (*ip == 0xe8) + return 1; + return 0; +} + + +void +i386_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + unsigned char *instructp; + Sym *child; + bfd_vma pc, destpc; + + if (core_text_space == 0) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", + parent->name, (unsigned long) p_lowpc, + (unsigned long) p_highpc)); + + for (pc = p_lowpc; pc < p_highpc; ++pc) + { + instructp = (unsigned char *) core_text_space + pc - core_text_sect->vma; + if (i386_iscall (instructp)) + { + DBG (CALLDEBUG, + printf ("[findcall]\t0x%lx:call", (unsigned long) pc)); + /* + * regular pc relative addressing + * check that this is the address of + * a function. + */ + + destpc = bfd_get_32 (core_bfd, instructp + 1) + pc + 5; + if (destpc >= s_lowpc && destpc <= s_highpc) + { + child = sym_lookup (&symtab, destpc); + if (child && child->addr == destpc) + { + /* + * a hit + */ + DBG (CALLDEBUG, + printf ("\tdestpc 0x%lx (%s)\n", + (unsigned long) destpc, child->name)); + arc_add (parent, child, (unsigned long) 0); + instructp += 4; /* call is a 5 byte instruction */ + continue; + } + } + /* + * else: + * it looked like a callf, but it: + * a) wasn't actually a callf, or + * b) didn't point to a known function in the symtab, or + * c) something funny is going on. + */ + DBG (CALLDEBUG, printf ("\tbut it's a botch\n")); + } + } +} diff --git a/gprof/po/.cvsignore b/gprof/po/.cvsignore new file mode 100644 index 000000000000..becd1537dbec --- /dev/null +++ b/gprof/po/.cvsignore @@ -0,0 +1 @@ +*.gmo diff --git a/gprof/po/Make-in b/gprof/po/Make-in index 833d418224cb..6176dbf78c3c 100644 --- a/gprof/po/Make-in +++ b/gprof/po/Make-in @@ -24,6 +24,8 @@ gnulocaledir = $(prefix)/share/locale gettextsrcdir = $(prefix)/share/gettext/po subdir = po +DESTDIR = + INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @MKINSTALLDIRS@ @@ -70,9 +72,7 @@ INSTOBJEXT = @INSTOBJEXT@ .po.gmo: file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ - && test -w $$file \ - && (rm -f $$file && $(GMSGFMT) -o $$file $< ) \ - || echo "$$file is not writable" + && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ @@ -113,9 +113,9 @@ install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(datadir); \ + $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ else \ - $(top_srcdir)/mkinstalldirs $(datadir); \ + $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \ fi @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ @@ -125,7 +125,7 @@ install-data-yes: all *) destdir=$(localedir);; \ esac; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ - dir=$$destdir/$$lang/LC_MESSAGES; \ + dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \ if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $$dir; \ else \ @@ -155,12 +155,12 @@ install-data-yes: all done if test "$(PACKAGE)" = "gettext"; then \ if test -r $(MKINSTALLDIRS); then \ - $(MKINSTALLDIRS) $(gettextsrcdir); \ + $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ else \ - $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \ fi; \ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ - $(gettextsrcdir)/Makefile.in.in; \ + $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ else \ : ; \ fi @@ -173,12 +173,12 @@ uninstall: for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ - rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ - rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ - rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ - rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ done - rm -f $(gettextsrcdir)/po-Makefile.in.in + rm -f $(DESTDIR)$(gettextsrcdir)/po-Makefile.in.in check: all diff --git a/gprof/po/da.gmo b/gprof/po/da.gmo Binary files differnew file mode 100644 index 000000000000..d2bfe782d2aa --- /dev/null +++ b/gprof/po/da.gmo diff --git a/gprof/po/da.po b/gprof/po/da.po new file mode 100644 index 000000000000..457de35e9ad7 --- /dev/null +++ b/gprof/po/da.po @@ -0,0 +1,552 @@ +# Danish messages for gprof. +# Copyright (C) 2001, 2002 Free Software Foundation, Inc. +# Keld Simonsen <keld@dkuug.dk>, 2002 +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.12.91\n" +"POT-Creation-Date: 2002-07-23 15:58-0400\n" +"PO-Revision-Date: 2002-11-09 14:01+0100\n" +"Last-Translator: Keld Simonsen <keld@dkuug.dk>\n" +"Language-Team: Danish <dansk@klid.dk>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: alpha.c:93 mips.c:47 +msgid "<indirect child>" +msgstr "<indirekte barn>" + +#: alpha.c:110 mips.c:64 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx til 0x%lx\n" + +#: alpha.c:132 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <indirekte_barn>\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: uventet filslutning\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: advarsel: ignorerer eksekveringsregning for grundblok (brug -l eller --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu eksekveringer\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<ukendt>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"Øverste %d linjer:\n" +"\n" +" Linje Antal\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Eksekveringsoversigt:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Eksekverbare linjer i denne fil\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Eksekverede linjer\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Procent af filen eksekveret\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Totalt antal linjeeksekveringer\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Gennemsniteksekveringer per linje\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] gren fra %s til %s gennemløbet %lu gange\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Kaldsgraf (forklaring følger)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tKaldsgraf\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"opløsning: hver stikprøve dækker %ld byte" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" for %.2f%% på %.2f sekunder\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" ingen tid propageret\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "kaldt" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "totalt" + +#: cg_print.c:95 +msgid "parents" +msgstr "forældre" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "indeks" + +#: cg_print.c:97 +msgid "%time" +msgstr "%tid" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "selv" + +#: cg_print.c:97 +msgid "descendants" +msgstr "afkom" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "navn" + +#: cg_print.c:100 +msgid "children" +msgstr "børn" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "indeks %% tid selv børn kaldt navn\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <hele cyklusen %d> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontant>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontant>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Indeks efter funktionsnavn\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<cyklus %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: kunne ikke åbne %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: kan ikke tolke mappingsfilen %s.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: ikke i a.out-format\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: kan ikke finde .text-sektion i %s\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: slut på plads for %lu byte tekstplads\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: kan ikke lave -c\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c understøttes ikke på arkitekturen %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: filen \"%s\" har ingen symboler\n" + +#: corefile.c:748 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: nogen regnede forkert: ltab.len=%d i stedet for %ld\n" + +#: gmon_io.c:96 gmon_io.c:159 gmon_io.c:219 gmon_io.c:251 gmon_io.c:422 +#: gmon_io.c:449 gmon_io.c:646 gmon_io.c:671 +#, c-format +msgid "%s: bits per address has unexpected value of %u\n" +msgstr "%s: bit per adresse har en uventet værdi på %u\n" + +#: gmon_io.c:288 gmon_io.c:383 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: filen er for kort til at være en gmon-fil\n" + +#: gmon_io.c:298 gmon_io.c:432 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: filen \"%s\" har fejlagtigt magisk tal\n" + +#: gmon_io.c:309 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: filen \"%s\" har version %d som ikke understøttes\n" + +#: gmon_io.c:339 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: fandt fejlagtig mærke %d (er filen beskadiget?)\n" + +#: gmon_io.c:405 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: profileringshastighed er inkompatibel med første gmon-fil\n" + +#: gmon_io.c:465 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: inkompatibel med første gmon-fil\n" + +#: gmon_io.c:493 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: filen \"%s\" ser ikke ud til at være i gmon.out-format\n" + +#: gmon_io.c:514 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: uventet filslut efter læsning af %d/%d poster\n" + +#: gmon_io.c:547 +msgid "time is in ticks, not seconds\n" +msgstr "tiden er i tick, ikke sekunder\n" + +#: gmon_io.c:553 gmon_io.c:742 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: ved ikke hvordan filformat %d skal håndteres\n" + +#: gmon_io.c:560 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "Filen \"%s\" (version %d) indeholder:\n" + +#: gmon_io.c:563 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d histogrampost\n" + +#: gmon_io.c:564 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d histogramposter\n" + +#: gmon_io.c:566 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d kaldsgrafpost\n" + +#: gmon_io.c:567 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d kaldsgrafposter\n" + +#: gmon_io.c:569 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d grundbloksregningspost\n" + +#: gmon_io.c:570 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d grundbloksregningsposter\n" + +#: gprof.c:152 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Brug: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][navn]]\n" +"\t[-I kataloger] [-d[tal]] [-k fra/til] [-m mindste-antal]\n" +"\t[-t table-length] [--[no-]annotated-source[=navn]]\n" +"\t[--[no-]exec-counts[=navn]] [--[no-]flat-profile[=navn]]\n" +"\t[--[no-]graph[=navn]] [--[no-]time=navn] [--all-lines] [--brief]\n" +"\t[--debug[=niveau]] [--function-ordering] [--file-ordering]\n" +"\t[--directory-path=kataloger] [--display-unused-functions]\n" +"\t[--file-format=navn] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=længde] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STIL]] [--no-demangle]\n" +"\t[billedfil] [profilfil...]\n" + +#: gprof.c:168 +#, c-format +msgid "Report bugs to %s\n" +msgstr "" +"Rapportér fejl til %s,\n" +"og synpunkter på oversættelsen til dansk@klid.dk\n" + +#: gprof.c:242 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: fejlsøgning understøttes ikke; -d ignoreredes\n" + +#: gprof.c:322 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: ukendt filformat %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:406 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:407 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Baseret på BSD gprof, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:408 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Dette program er frit programmel. Dette program har ingen som helst garanti.\n" + +#: gprof.c:449 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: ukendt demanglingsstil \"%s\"\n" + +#: gprof.c:469 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Kun en af --function-ordering og --file-ordering kan angives.\n" + +#: gprof.c:569 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: desværre, filformatet \"prof\" understøttes ikke endnu\n" + +#: gprof.c:630 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: gmon.out-filen mangler histogram\n" + +#: gprof.c:637 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: gmon.out-filen mangler kaldsgrafdata\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: \"%s\" er inkompatibel med første gmon-fil\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: uventet filslut efter læsning af %d af %d stikprøve\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/kald" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" for %.2f%% af %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Hver stikprøve regnes som %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" ingen tid akkumuleret\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "kumulativ" + +#: hist.c:385 +msgid "self " +msgstr "selv" + +#: hist.c:385 +msgid "total " +msgstr "totalt" + +#: hist.c:388 +msgid "time" +msgstr "tid" + +#: hist.c:388 +msgid "calls" +msgstr "kald" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"flad profil:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Flad profil:\n" + +#: mips.c:75 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:100 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: kunne ikke finde \"%s\"\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Fil %s:\n" + +#: utils.c:99 +#, c-format +msgid " <cycle %d>" +msgstr " <cyklus %d>" + +#~ msgid "%s: bfd_vma has unexpected size of %ld bytes\n" +#~ msgstr "%s: bfd_vma har en uventet størrelse på %ld byte\n" diff --git a/gprof/po/de.gmo b/gprof/po/de.gmo Binary files differnew file mode 100644 index 000000000000..0d571f5fb008 --- /dev/null +++ b/gprof/po/de.gmo diff --git a/gprof/po/de.po b/gprof/po/de.po new file mode 100644 index 000000000000..201d6da78693 --- /dev/null +++ b/gprof/po/de.po @@ -0,0 +1,549 @@ +# German translation of gprof +# Copyright (C) 1997, 1998 Free Software Foundation, Inc. +# This file is distributed under the same license as the gprof package. +# Roland Stigge <stigge@antcom.de>, 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.14rel030712\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" +"PO-Revision-Date: 2003-08-02 12:13+0200\n" +"Last-Translator: Roland Stigge <stigge@antcom.de>\n" +"Language-Team: German <de@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" +"Content-Transfer-Encoding: 8bit\n" + +#: alpha.c:103 mips.c:57 +msgid "<indirect child>" +msgstr "<indirektes Kind>" + +#: alpha.c:120 mips.c:74 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx bis 0x%lx\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <indirektes Kind>\n" + +#: alpha.c:152 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: unerwartetes Dateiende\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: Warnung: ignoriere basic-block Befehlszähler (benutzen Sie -l oder --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu Ausführungen\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<unbekannt>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"Erste %d Zeilen:\n" +"\n" +" Zeile Anzahl\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Ausführungszusammenfassung:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Ausführbare Zeilen in dieser Datei\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Zeilen ausgeführt\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Prozent der Datei ausgeführt\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Gesamtzahl ausgeführter Zeilen\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Durchschnittliche Ausführungen pro Zeile\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] Bogen von %s bis %s wurde %lu mal durchlaufen\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Aufrufgraph (Erklärung folgt)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tAufrufgraph\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"Granularität: jeder Stichprobentreffer deckt %ld Byte(s) ab" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" für %.2f%% von %.2f Sekunden\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" keine Zeit weitergereicht\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "aufgerufen" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "gesamt" + +#: cg_print.c:95 +msgid "parents" +msgstr "Eltern" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "Index" + +# c-format ??? +#: cg_print.c:97 +#, c-format +msgid "%time" +msgstr "%time" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "selbst" + +#: cg_print.c:97 +msgid "descendants" +msgstr "Nachfahren" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "Name" + +#: cg_print.c:100 +msgid "children" +msgstr "Kinder" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "Index %% Zeit Selb. Kinder aufgerufen Name\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <Zyklus %d als Ganzes> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontan>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontan>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Index nach Funktionsnamen\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<Zyklus %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: Konnte %s nicht öffnen.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: Konnte Mapping-Datei %s nicht analysieren.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: nicht im a.out-Format\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: kann den .text-Abschnitt in %s nicht finden\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: Platzmangel für %lu Bytes des Textraumes\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: kann -c nicht ausführen\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c nicht unterstützt auf Architektur %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: Datei `%s' hat keine Symbole\n" + +#: corefile.c:758 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: jemand hat sich verzählt: ltab.len=%d anstelle von %ld\n" + +#: gmon_io.c:82 +#, c-format +msgid "%s: address size has unexpected value of %u\n" +msgstr "%s: Adressbreite hat unerwarteten Wert von %u\n" + +#: gmon_io.c:345 gmon_io.c:440 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: Datei zu kurz um eine gmon-Datei zu sein\n" + +#: gmon_io.c:355 gmon_io.c:483 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: Datei `%s' hat ungültiges magisches Cookie\n" + +#: gmon_io.c:366 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: Datei `%s' hat nicht unterstützte Version %d\n" + +#: gmon_io.c:396 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: schlechte Markierung %d gefunden (Datei beschädigt?)\n" + +#: gmon_io.c:462 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: Profilingrate inkompatibel mit erster gmon-Datei\n" + +#: gmon_io.c:510 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: inkompatibel mit erster gmon-Datei\n" + +#: gmon_io.c:538 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: Datei '%s' ist nicht im gmon.out-Format\n" + +#: gmon_io.c:559 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: unerwartetes Dateiende nach dem Lesen von %d/%d Kästen\n" + +#: gmon_io.c:592 +msgid "time is in ticks, not seconds\n" +msgstr "Zeit in Takten, nicht Sekunden\n" + +#: gmon_io.c:598 gmon_io.c:775 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: keine Behandlung des Dateiformates %d bekannt\n" + +#: gmon_io.c:605 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "Datei `%s' (version %d) enthält:\n" + +#: gmon_io.c:608 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d Histogrammdatensatz\n" + +#: gmon_io.c:609 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d Histogrammdatensätze\n" + +#: gmon_io.c:611 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d Aufrufgraph-Datensatz\n" + +#: gmon_io.c:612 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d Aufrufgraph-Datensätze\n" + +#: gmon_io.c:614 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d basic-block Anzahldatensatz\n" + +#: gmon_io.c:615 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d basic-block Anzahldatensätze\n" + +#: gprof.c:163 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Aufruf: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][Name]] [-I Verzeichnisse]\n" +"\t[-d[Anz.]] [-k von/bis] [-m min-Anz.] [-t Tabellenlänge]\n" +"\t[--[no-]annotated-source[=Name]] [--[no-]exec-counts[=Name]]\n" +"\t[--[no-]flat-profile[=Name]] [--[no-]graph[=Name]]\n" +"\t[--[no-]time=Name] [--all-lines] [--brief] [--debug[=Level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=Verz.] [--display-unused-functions]\n" +"\t[--file-format=Name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STIL]] [--no-demangle]\n" +"\t[image-file] [profile-Datei...]\n" + +#: gprof.c:179 +#, c-format +msgid "Report bugs to %s\n" +msgstr "Melden Sie Fehler an %s\n" + +#: gprof.c:253 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: Debugging nicht unterstützt; -d ignoriert\n" + +#: gprof.c:333 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: unbekanntes Dateiformat %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:417 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:418 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Basierend auf BSD gprof, copyright 1983 Regenten der University of California.\n" + +#: gprof.c:419 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Dieses Programm ist Freie Software. Es kommt absolut ohne Garantie.\n" + +#: gprof.c:460 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: unbekannter Auflösungsstil `%s'\n" + +#: gprof.c:480 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Nur entweder --function-ordering oder --file-ordering kann angegeben werden.\n" + +#: gprof.c:578 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: Sorry, Dateiformat `gprof' wird noch nicht unterstützt\n" + +#: gprof.c:639 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: gmon.out-Datei hat kein Histogramm\n" + +#: gprof.c:646 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: gmon.out-Datei hat keine Aufrufgraph-Daten\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: `%s' ist inkompatibel mit erster gmon-Datei\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: unerwartetes Dateiende nach dem Lesen von %d von %d Mustern\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/Aufruf" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" für %.2f%% von %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Jedes Muster zählt als %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" keine Zeit angesammelt\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "kumulativ" + +#: hist.c:385 +msgid "self " +msgstr "Selbst" + +#: hist.c:385 +msgid "total " +msgstr "Gesamt" + +#: hist.c:388 +msgid "time" +msgstr "Zeit" + +#: hist.c:388 +msgid "calls" +msgstr "Aufrufe" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"Flaches Profil:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Flaches Profil:\n" + +#: mips.c:85 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:110 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: Konnte `%s' nicht finden\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Datei %s:\n" + +#: utils.c:109 +#, c-format +msgid " <cycle %d>" +msgstr " <Zyklus %d>" diff --git a/gprof/po/es.gmo b/gprof/po/es.gmo Binary files differnew file mode 100644 index 000000000000..e2e98a88131d --- /dev/null +++ b/gprof/po/es.gmo diff --git a/gprof/po/es.po b/gprof/po/es.po new file mode 100644 index 000000000000..dc657a81b6cc --- /dev/null +++ b/gprof/po/es.po @@ -0,0 +1,552 @@ +# Mensajes en español para gprof 2.14rel030712. +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2002, 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.14rel030712\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" +"PO-Revision-Date: 2003-07-14 18:45-0500\n" +"Last-Translator: Cristian Othón Martínez Vera <cfuga@itam.mx>\n" +"Language-Team: Spanish <es@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: alpha.c:103 mips.c:57 +msgid "<indirect child>" +msgstr "<hijo indirecto>" + +#: alpha.c:120 mips.c:74 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx a 0x%lx\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <hijo_indirecto>\n" + +#: alpha.c:152 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: fin de fichero inesperado\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: aviso: ignorando las cuentas de ejecución de bloques básicos (use -l o --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu ejecuciones\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<desconocido>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"%d Líneas Principales:\n" +"\n" +" Línea Cuenta\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Resumen de Ejecución:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Líneas ejecutables en este fichero\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Líneas ejecutadas\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Porcentaje ejecutado del fichero\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Número total de ejecuciones de línea\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Ejecuciones promedio por línea\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] arco desde %s hasta %s recorrido %lu veces\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Gráfico de llamadas (explicación a continuación)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tGráfico de llamadas\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"granularidad: cada elemento de muestra cubre %ld byte(s)" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" para %.2f%% de %.2f segundos\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" no hay tiempo propagado\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "llamado" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "total" + +#: cg_print.c:95 +msgid "parents" +msgstr "padres" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "índice" + +#: cg_print.c:97 +#, c-format +msgid "%time" +msgstr "%tiempo" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "sí mismo" + +#: cg_print.c:97 +msgid "descendants" +msgstr "descendientes" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "nombre" + +#: cg_print.c:100 +msgid "children" +msgstr "hijos" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "ind %% tiempo sí_mismo hijos llamado nombre\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <ciclo %d como un todo> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <espontáneos>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <espontáneos>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Índice por nombre de función\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<ciclo %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: no se puede abrir %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: no se puede decodificar el fichero de mapeo %s.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: no está en el formato a.out\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: no se puede encontrar la sección .text en %s\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: se terminó el espacio para %lu bytes de espacio de texto\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: no se puede hacer -c\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c no tiene soporte en la arquitectura %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: el fichero `%s' no tiene símbolos\n" + +#: corefile.c:758 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: alguien contó mal: ltab.len=%d en lugar de %ld\n" + +#: gmon_io.c:82 +#, c-format +msgid "%s: address size has unexpected value of %u\n" +msgstr "%s: el tamaño de la dirección tiene un valor inesperado de %u\n" + +#: gmon_io.c:345 gmon_io.c:440 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: el fichero es muy corto para ser un fichero gmon\n" + +#: gmon_io.c:355 gmon_io.c:483 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: el fichero `%s' tiene una galleta mágica errónea\n" + +#: gmon_io.c:366 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: el fichero `%s' tiene la version %d que no tiene soporte\n" + +#: gmon_io.c:396 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: se encontró la marca errónea %d (¿fichero corrupto?)\n" + +#: gmon_io.c:462 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: tasa de análisis de perfil incompatible con el primer fichero gmon\n" + +#: gmon_io.c:510 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: incompatible con el primer fichero gmon\n" + +#: gmon_io.c:538 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: el fichero '%s' no parece estar en el formato gmon.out\n" + +# FIXME: comprobar con el código si bins es abreviatura de binarios o +# se refiere a la denominación inglesa de 'papelera'. cfuga +#: gmon_io.c:559 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: fin de fichero inesperado después de leer %d/%d binarios\n" + +#: gmon_io.c:592 +msgid "time is in ticks, not seconds\n" +msgstr "el tiempo está en tics, no en segundos\n" + +#: gmon_io.c:598 gmon_io.c:775 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: se desconoce cómo lidiar con el fichero de formato %d\n" + +#: gmon_io.c:605 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "El fichero `%s' (versión %d) contiene:\n" + +#: gmon_io.c:608 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d registro de histograma\n" + +#: gmon_io.c:609 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d registros de histogramas\n" + +#: gmon_io.c:611 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d registro de gráfico de llamadas\n" + +#: gmon_io.c:612 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d registros de gráficos de llamadas\n" + +#: gmon_io.c:614 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d registro de cuenta de bloques básicos\n" + +#: gmon_io.c:615 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d registros de cuentas de bloques básicos\n" + +#: gprof.c:163 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Modo de empleo: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][nombre]] [-I dirs]\n" +"\t[-d[num]] [-k de/a] [-m cuenta-min] [-t longitud-tabla]\n" +"\t[--[no-]annotated-source[=nombre]] [--[no-]exec-counts[=nombre]]\n" +"\t[--[no-]flat-profile[=nombre]] [--[no-]graph[=nombre]]\n" +"\t[--[no-]time=nombre] [--all-lines] [--brief] [--debug[=nivel]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=nombre] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=long] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=ESTILO]] [--no-demangle]\n" +"\t[fichero-imagen] [fichero-perfil...]\n" + +#: gprof.c:179 +#, c-format +msgid "Report bugs to %s\n" +msgstr "Reportar bichos a %s\n" + +#: gprof.c:253 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: no hay soporte para depuración; se ignora -d\n" + +#: gprof.c:333 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: formato de fichero %s desconocido\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:417 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:418 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Basado en gprof de BSD, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:419 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Este programa es software libre. Este programa no tiene ninguna garantía en lo absoluto.\n" + +#: gprof.c:460 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: estilo de desenredo desconocido `%s'\n" + +#: gprof.c:480 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Sólo se puede especificar uno de --function-ordering y --file-ordering.\n" + +#: gprof.c:578 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: perdón, el formato de fichero `prof' aún no tiene soporte\n" + +#: gprof.c:639 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: al fichero gmon.out le falta el histograma\n" + +#: gprof.c:646 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: al fichero gmon.out le falta los datos del gráfico de llamadas\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: `%s' es incompatible con el primer fichero gmon\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: fin de fichero inesperado después de leer %d de %d muestras\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/llamada" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" para %.2f%% de %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Cada muestra cuenta como %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" no hay tiempo acumulado\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "cumulativo" + +#: hist.c:385 +msgid "self " +msgstr "sí mismo " + +#: hist.c:385 +msgid "total " +msgstr "total " + +#: hist.c:388 +msgid "time" +msgstr "tiempo" + +#: hist.c:388 +msgid "calls" +msgstr "llamadas" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"perfil plano:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Perfil plano:\n" + +#: mips.c:85 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:110 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: no se puede encontrar `%s'\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Fichero %s:\n" + +#: utils.c:109 +#, c-format +msgid " <cycle %d>" +msgstr " <ciclo %d>" + +#~ msgid "%s: bfd_vma has unexpected size of %ld bytes\n" +#~ msgstr "%s: bfd_vma tiene un tamaño inesperado de %ld bytes\n" diff --git a/gprof/po/fr.gmo b/gprof/po/fr.gmo Binary files differnew file mode 100644 index 000000000000..7b4cbb1b681c --- /dev/null +++ b/gprof/po/fr.gmo diff --git a/gprof/po/fr.po b/gprof/po/fr.po new file mode 100644 index 000000000000..2cc0e220bbe9 --- /dev/null +++ b/gprof/po/fr.po @@ -0,0 +1,551 @@ +# Messages français pour gprof. +# Copyright © 2004 Free Software Foundation, Inc. +# Michel Robitaille <robitail@IRO.UMontreal.CA>, traducteur depuis/since 1996. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.14rel030712\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" +"PO-Revision-Date: 2004-05-10 08:00-0500\n" +"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n" +"Language-Team: French <traduc@traduc.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: alpha.c:103 mips.c:57 +msgid "<indirect child>" +msgstr "<rejeton indirect>" + +#: alpha.c:120 mips.c:74 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx to 0x%lx\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <indirect_child>\n" + +#: alpha.c:152 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: fin prématurée du fichier\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: AVERTISSEMENT: a ignoré les compteurs d'exécution des blocs de base(utiliser -l ou --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu exécutions\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<inconnu>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"%d Lignes du haut:\n" +"\n" +" Ligne Compteur\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Sommaire d'exécution:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Lignes exécutables dans ce fichier\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Lignes exécutées\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Percent du fichier exécuté\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Nombre total de lignes exécutées\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Exécutions moyennes par ligne\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] arc à partir de %s à %s traversés %lu fois\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Appel de graphe (les explications suivent)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tAppel de graphe\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"granularité: chaque échantillonnage couvre %ld octet(s)" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" pour %.2f%% of %.2f secondes\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" pas de propagation de temps\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "appelé" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "total" + +#: cg_print.c:95 +msgid "parents" +msgstr "parents" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "index" + +#: cg_print.c:97 +#, c-format +msgid "%time" +msgstr "%time" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "auto" + +#: cg_print.c:97 +msgid "descendants" +msgstr "descendants" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "nom" + +#: cg_print.c:100 +msgid "children" +msgstr "rejetons" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "index %% temp auto rejetons appelé nom\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <cycle %d en entier> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontanés>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontanés>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Index par nom de fonction\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<cycle %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: ne peut ouvrir %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: incapable d'analyser le fichier de projection %s.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: n'est pas dans le format a.out\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: ne peut repérer la section .text dans %s\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: espace épuisé pour %lu octets dans l'espace texte\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: ne peut appliquer l'option -c\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: l'option -c n'est pas supporté l'architecture %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: fichier « %s » n'a pas de symbole\n" + +#: corefile.c:758 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: mauvais décomptage: ltab.len=%d au lieu de %ld\n" + +#: gmon_io.c:82 +#, c-format +msgid "%s: address size has unexpected value of %u\n" +msgstr "%s: taille d'adresse a une valeur inattendue de %u\n" + +#: gmon_io.c:345 gmon_io.c:440 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: fichier trop court pour être un fichier gmon\n" + +#: gmon_io.c:355 gmon_io.c:483 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: fichier « %s » a un nombre magique erroné\n" + +#: gmon_io.c:366 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: fichier « %s » est d'une version non supportée %d\n" + +#: gmon_io.c:396 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: a repéré une étiquette erronée %d (fichier corrompu?)\n" + +#: gmon_io.c:462 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: taux de profilage incompatible avec le premier fichier gmon\n" + +#: gmon_io.c:510 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: incompatible avec le premier fichier gmon\n" + +#: gmon_io.c:538 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: fichier « %s » ne semble pas être dans le format gmon.out\n" + +#: gmon_io.c:559 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: EOF inattendu après la lecture de %d/%d bins\n" + +#: gmon_io.c:592 +msgid "time is in ticks, not seconds\n" +msgstr "temps est en tics et non pas en secondes\n" + +#: gmon_io.c:598 gmon_io.c:775 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: ne sait pas comment gérer le format %d du fichier\n" + +#: gmon_io.c:605 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "Fichier « %s » (version %d) contient:\n" + +#: gmon_io.c:608 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d enregistrement de type histogramme\n" + +#: gmon_io.c:609 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d enregistrements de type histogramme\n" + +#: gmon_io.c:611 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d enregistrement de type call-graph\n" + +#: gmon_io.c:612 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d enregistrements de type call-graph\n" + +#: gmon_io.c:614 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d enregistrement de décomptes de bloc de base\n" + +#: gmon_io.c:615 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d enregistrements de décomptes de bloc de base\n" + +#: gprof.c:163 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][nom]] [-I répertoires]\n" +"\t[-d[nombre]] [-k de/à] [-m minimum] [-t longueur-de-la-table]\n" +"\t[--[no-]annotated-source[=nom]] [--[no-]exec-counts[=nom]]\n" +"\t[--[no-]flat-profile[=nom]] [--[no-]graph[=nom]]\n" +"\t[--[no-]time=nom] [--all-lines] [--brief] [--debug[=niveau]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=répertoires] [--display-unused-functions]\n" +"\t[--file-format=nom] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=longueur] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[fichier-image] [fichier-profile...]\n" + +#: gprof.c:179 +#, c-format +msgid "Report bugs to %s\n" +msgstr "Rapporter toutes anomalies à %s\n" + +#: gprof.c:253 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: mise au point n'est pas supportée; -d ignorée\n" + +#: gprof.c:333 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: format de fichier inconnu %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:417 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:418 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Basé à partir de BSD gprof, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:419 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Ce logiciel est libre. AUCUNE garantie n'est donnée.\n" + +#: gprof.c:460 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: style d'encodage par mutilation inconnu « %s »\n" + +#: gprof.c:480 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: une seule des options --function-ordering et --file-ordering peut être spécifiée.\n" + +#: gprof.c:578 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: désolé, le format de fichier « prof » n'est pas encore supporté\n" + +#: gprof.c:639 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: le fichier gmon.out n'a pas d'histogramme\n" + +#: gprof.c:646 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: le fichier gmon.out n'a pas de données de type call-graph\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: « %s » est incompatible avec le premier fichier gmon\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: EOF inattendu après la lecture de %d de %d échantillons\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/appel" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" pour %.2f%% of %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Chaque échantillon dénombre %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" pas d'accumulation de temps\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "cumulatif" + +#: hist.c:385 +msgid "self " +msgstr "auto " + +#: hist.c:385 +msgid "total " +msgstr "total " + +#: hist.c:388 +msgid "time" +msgstr "temps" + +#: hist.c:388 +msgid "calls" +msgstr "appels" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"profile plat:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Profile plat:\n" + +#: mips.c:85 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:110 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: n'a pu localiser « %s »\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Fichier %s:\n" + +#: utils.c:109 +#, c-format +msgid " <cycle %d>" +msgstr " <cycle %d>" + +#~ msgid "%s: bfd_vma has unexpected size of %ld bytes\n" +#~ msgstr "%s: bfd_vma a une taille inattendue de %ld octetst\n" diff --git a/gprof/po/gprof.pot b/gprof/po/gprof.pot index ab103f4007e0..b1c319a3e178 100644 --- a/gprof/po/gprof.pot +++ b/gprof/po/gprof.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2002-10-30 10:08-0500\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -244,97 +244,96 @@ msgstr "" msgid "%s: file `%s' has no symbols\n" msgstr "" -#: corefile.c:748 +#: corefile.c:758 #, c-format msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" msgstr "" -#: gmon_io.c:96 gmon_io.c:159 gmon_io.c:219 gmon_io.c:251 gmon_io.c:422 -#: gmon_io.c:449 gmon_io.c:646 gmon_io.c:671 +#: gmon_io.c:82 #, c-format -msgid "%s: bits per address has unexpected value of %u\n" +msgid "%s: address size has unexpected value of %u\n" msgstr "" -#: gmon_io.c:288 gmon_io.c:383 +#: gmon_io.c:345 gmon_io.c:440 #, c-format msgid "%s: file too short to be a gmon file\n" msgstr "" -#: gmon_io.c:298 gmon_io.c:432 +#: gmon_io.c:355 gmon_io.c:483 #, c-format msgid "%s: file `%s' has bad magic cookie\n" msgstr "" -#: gmon_io.c:309 +#: gmon_io.c:366 #, c-format msgid "%s: file `%s' has unsupported version %d\n" msgstr "" -#: gmon_io.c:339 +#: gmon_io.c:396 #, c-format msgid "%s: %s: found bad tag %d (file corrupted?)\n" msgstr "" -#: gmon_io.c:405 +#: gmon_io.c:462 #, c-format msgid "%s: profiling rate incompatible with first gmon file\n" msgstr "" -#: gmon_io.c:465 +#: gmon_io.c:510 #, c-format msgid "%s: incompatible with first gmon file\n" msgstr "" -#: gmon_io.c:493 +#: gmon_io.c:538 #, c-format msgid "%s: file '%s' does not appear to be in gmon.out format\n" msgstr "" -#: gmon_io.c:514 +#: gmon_io.c:559 #, c-format msgid "%s: unexpected EOF after reading %d/%d bins\n" msgstr "" -#: gmon_io.c:547 +#: gmon_io.c:592 msgid "time is in ticks, not seconds\n" msgstr "" -#: gmon_io.c:553 gmon_io.c:742 +#: gmon_io.c:598 gmon_io.c:775 #, c-format msgid "%s: don't know how to deal with file format %d\n" msgstr "" -#: gmon_io.c:560 +#: gmon_io.c:605 #, c-format msgid "File `%s' (version %d) contains:\n" msgstr "" -#: gmon_io.c:563 +#: gmon_io.c:608 #, c-format msgid "\t%d histogram record\n" msgstr "" -#: gmon_io.c:564 +#: gmon_io.c:609 #, c-format msgid "\t%d histogram records\n" msgstr "" -#: gmon_io.c:566 +#: gmon_io.c:611 #, c-format msgid "\t%d call-graph record\n" msgstr "" -#: gmon_io.c:567 +#: gmon_io.c:612 #, c-format msgid "\t%d call-graph records\n" msgstr "" -#: gmon_io.c:569 +#: gmon_io.c:614 #, c-format msgid "\t%d basic-block count record\n" msgstr "" -#: gmon_io.c:570 +#: gmon_io.c:615 #, c-format msgid "\t%d basic-block count records\n" msgstr "" diff --git a/gprof/po/id.gmo b/gprof/po/id.gmo Binary files differnew file mode 100644 index 000000000000..bbf145e41b69 --- /dev/null +++ b/gprof/po/id.gmo diff --git a/gprof/po/id.po b/gprof/po/id.po new file mode 100644 index 000000000000..d88485f16225 --- /dev/null +++ b/gprof/po/id.po @@ -0,0 +1,547 @@ +# gprof 2.12.1 (Indonesian) +# Copyright (C) 2002 Free Software Foundation, Inc. +# Tedi Heriyanto <tedi_h@gmx.net>, 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.12.1\n" +"POT-Creation-Date: 2002-01-31 18:32+0000\n" +"PO-Revision-Date: 2002-07-23 12:43GMT+0700\n" +"Last-Translator: Tedi Heriyanto <tedi_h@gmx.net>\n" +"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.5\n" + +#: alpha.c:93 mips.c:47 +msgid "<indirect child>" +msgstr "<indirect child>" + +#: alpha.c:110 mips.c:64 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx hingga 0x%lx\n" + +#: alpha.c:132 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <indirect_child>\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:122 call_graph.c:90 hist.c:93 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: akhir file tidak diharapkan\n" + +#: basic_blocks.c:190 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: peringatan: mengabaikan hitungan basic-block exec (gunakan -l atau --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:281 basic_blocks.c:291 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu eksekusi\n" + +#: basic_blocks.c:282 basic_blocks.c:292 +msgid "<unknown>" +msgstr "<tidak dikenal>" + +#: basic_blocks.c:536 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"Awal %d Baris:\n" +"\n" +" Baris Hitungan\n" +"\n" + +#: basic_blocks.c:560 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Ringkasan Eksekusi:\n" +"\n" + +#: basic_blocks.c:561 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld baris eksekutabel dalam file ini\n" + +#: basic_blocks.c:563 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld baris dieksekusi\n" + +#: basic_blocks.c:564 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Persen file dieksekusi\n" + +#: basic_blocks.c:568 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Total jumlah baris eksekusi\n" + +#: basic_blocks.c:570 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Rata-rata eksekusi per baris\n" + +#: call_graph.c:69 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] arc dari %s hingga %s ditransvers %lu kali\n" + +#: cg_print.c:58 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Panggil graph (penjelasan mengikuti)\n" +"\n" + +#: cg_print.c:60 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tPanggil graph\n" +"\n" + +#: cg_print.c:63 hist.c:355 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"granularitas: setiap sampel mencapai %ld byte(s)" + +#: cg_print.c:67 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" untuk %.2f%% dari %.2f detik\n" +"\n" + +#: cg_print.c:71 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" no time propagated\n" +"\n" + +#: cg_print.c:80 cg_print.c:83 cg_print.c:85 +msgid "called" +msgstr "dipanggil" + +#: cg_print.c:80 cg_print.c:85 +msgid "total" +msgstr "total" + +#: cg_print.c:80 +msgid "parents" +msgstr "orangtua" + +#: cg_print.c:82 cg_print.c:83 +msgid "index" +msgstr "indeks" + +#: cg_print.c:82 +msgid "%time" +msgstr "%time" + +#: cg_print.c:82 cg_print.c:83 +msgid "self" +msgstr "diri" + +#: cg_print.c:82 +msgid "descendants" +msgstr "turunan" + +#: cg_print.c:83 hist.c:381 +msgid "name" +msgstr "nama" + +#: cg_print.c:85 +msgid "children" +msgstr "anak" + +#: cg_print.c:90 +#, c-format +msgid "index %% time self children called name\n" +msgstr "indeks %% waktu diri anak dipanggil nama\n" + +#: cg_print.c:113 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <siklus %d sebagai kesatuan> [%d]\n" + +#: cg_print.c:339 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontan>\n" + +#: cg_print.c:340 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontan>\n" + +#: cg_print.c:574 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Indeks berdasarkan nama fungsi\n" +"\n" + +#: cg_print.c:631 cg_print.c:640 +#, c-format +msgid "<cycle %d>" +msgstr "<siklus %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: tidak dapat membuka %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: tidak dapat memparsing file mapping %s.\n" + +#: corefile.c:154 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: bukan dalam format a.out\n" + +#: corefile.c:165 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: tidak dapat menemukan bagian teks dalam %s\n" + +#: corefile.c:223 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: kehabisan ruang untuk %lu byte ruang teks\n" + +#: corefile.c:237 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: tidak dapat melakukan -c\n" + +#: corefile.c:272 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c tidak didukung pada arsitektur %s\n" + +#: corefile.c:439 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: file `%s' tidak memiliki simbol\n" + +#: corefile.c:739 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: somebody miscounted: ltab.len=%d alih-alih %ld\n" + +#: gmon_io.c:83 gmon_io.c:137 gmon_io.c:188 gmon_io.c:216 gmon_io.c:386 gmon_io.c:413 gmon_io.c:609 gmon_io.c:634 +#, c-format +msgid "%s: bits per address has unexpected value of %u\n" +msgstr "%s: bit per alamat memiliki nilai yang tidak diharapkan %u\n" + +#: gmon_io.c:252 gmon_io.c:347 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: file terlalu pendek untuk menjadi file gmon\n" + +#: gmon_io.c:262 gmon_io.c:396 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: file `%s' memiliki cookie ajaib yang buruk\n" + +#: gmon_io.c:273 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: file `%s' memiliki versi yang belum didukung %d\n" + +#: gmon_io.c:303 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: ditemukan bad tag %d (file terkorupsi?)\n" + +#: gmon_io.c:369 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: rate profil tidak kompatibel dengan file gmon pertama\n" + +#: gmon_io.c:429 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: tidak kompatibel dengan file gmon pertama\n" + +#: gmon_io.c:457 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: file '%s' tampaknya bukan dalam format gmon.out\n" + +#: gmon_io.c:478 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: EOF tak diharapkan setelah membaca %d/%d bins\n" + +#: gmon_io.c:511 +msgid "time is in ticks, not seconds\n" +msgstr "waktu dalam tick, bukan detik\n" + +#: gmon_io.c:517 gmon_io.c:704 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: tidak tahu bagaimana menangani format file %d\n" + +#: gmon_io.c:524 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "File `%s' (versi %d) berisi:\n" + +#: gmon_io.c:527 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d catatan histogram\n" + +#: gmon_io.c:528 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d catatan histogram\n" + +#: gmon_io.c:530 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d catatan call-graph\n" + +#: gmon_io.c:531 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d catatan call-graph\n" + +#: gmon_io.c:533 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d catatan hitungan basic-block\n" + +#: gmon_io.c:534 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d catatan hitungan basic-block\n" + +#: gprof.c:147 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Penggunaan: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" + +#: gprof.c:163 +#, c-format +msgid "Report bugs to %s\n" +msgstr "Laporkan kesalahan ke %s\n" + +#: gprof.c:235 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: debugging tidak didukung; -d diabaikan\n" + +#: gprof.c:315 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: format file tidak dikenal %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:399 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:400 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Berdasarkan BSD gprof, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:401 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "This program is free software. This program has absolutely no warranty.\n" + +#: gprof.c:442 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: gaya demangling tidak dikenal `%s'\n" + +#: gprof.c:462 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Hanya satu --function-ordering dan --file-ordering dapat dispesifikasikan.\n" + +#: gprof.c:562 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: maaf, format file `prof' belum didukung\n" + +#: gprof.c:623 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: file gmon.out kehilangan histogram\n" + +#: gprof.c:630 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: file gmon.out kehilangan data call-graph\n" + +#: hist.c:122 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: `%s' tidak kompatibel dengan file gmon pertama\n" + +#: hist.c:138 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: EOF tidak diharapkan setelah membaca %d dari %d sampel\n" + +#: hist.c:351 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/panggilan" + +#: hist.c:359 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" untuk %.2f%% dari %.2f %s\n" +"\n" + +#: hist.c:365 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Setiap sampel dihitung sebagai %g %s.\n" + +#: hist.c:370 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" tidak ada waktu terkumpul\n" +"\n" + +#: hist.c:377 +msgid "cumulative" +msgstr "kumulatif" + +#: hist.c:377 +msgid "self " +msgstr "diri.." + +#: hist.c:377 +msgid "total " +msgstr "total " + +#: hist.c:380 +msgid "time" +msgstr "waktu" + +#: hist.c:380 +msgid "calls" +msgstr "panggilan" + +#: hist.c:469 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"profil flat:\n" + +#: hist.c:475 +msgid "Flat profile:\n" +msgstr "Profil flat:\n" + +#: mips.c:75 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:100 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:163 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: tidak dapat menemukan `%s'\n" + +#: source.c:238 +#, c-format +msgid "*** File %s:\n" +msgstr "*** File %s:\n" + +#: utils.c:96 +#, c-format +msgid " <cycle %d>" +msgstr " <siklus %d>" diff --git a/gprof/po/pt_BR.gmo b/gprof/po/pt_BR.gmo Binary files differnew file mode 100644 index 000000000000..32876f760040 --- /dev/null +++ b/gprof/po/pt_BR.gmo diff --git a/gprof/po/pt_BR.po b/gprof/po/pt_BR.po new file mode 100644 index 000000000000..832a79a8b156 --- /dev/null +++ b/gprof/po/pt_BR.po @@ -0,0 +1,551 @@ +# gprof: translation to Brazilian Portuguese (pt_BR) +# Copyright (C) 2002 Free Software Foundation, Inc. +# Alexandre Folle de Menezes <afmenez@terra.com.br>, 2002. +# based on the version 2.12.91 translation to Spanish (es) by +# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.12.91\n" +"POT-Creation-Date: 2002-07-23 15:58-0400\n" +"PO-Revision-Date: 2002-11-29 03:00-0300\n" +"Last-Translator: Alexandre Folle de Menezes <afmenez@terra.com.br>\n" +"Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: alpha.c:93 mips.c:47 +msgid "<indirect child>" +msgstr "<filho indireto>" + +#: alpha.c:110 mips.c:64 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx até 0x%lx\n" + +#: alpha.c:132 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <filho_indireto>\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: final de arquivo inesperado\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: aviso: ignorando os contadores de execução de blocos básicos (use -l ou --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu execuções\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<desconhecido>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"%d Linhas Principais:\n" +"\n" +" Linha Contador\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Resumo da Execução:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Linhas executáveis neste arquivo\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Linhas executadas\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Percentagem executada do arquivo\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Número total de execuções de linha\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Média de execuções por linha\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] arco de %s até %s percorido %lu vezes\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Gráfico de chamadas (explicação adiante)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tGráfico de chamadas\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"granularidade: cada elemento de amostra cobre %ld byte(s)" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" para %.2f%% de %.2f segundos\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" nenhum tempo propagado\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "chamado" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "total" + +#: cg_print.c:95 +msgid "parents" +msgstr "pais" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "índice" + +#: cg_print.c:97 +msgid "%time" +msgstr "%tempo" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "si mesmo" + +#: cg_print.c:97 +msgid "descendants" +msgstr "descendentes" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "nome" + +#: cg_print.c:100 +msgid "children" +msgstr "filhos" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "ind %% tempo si_mesmo filhos chamado nome\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <ciclo %d como um todo> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <espontâneos>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <espontâneos>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Índice por nome de função\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<ciclo %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: impossível abrir %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: impossível analisar o arquivo de mapeamento %s.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: não está no formato a.out\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: impossível encontrar a seção .text em %s\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: terminou o espaço para %lu bytes de espaço de texto\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: impossível fazer -c\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c não tem suporte na arquitetura %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: o arquivo `%s' não tem símbolos\n" + +#: corefile.c:748 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: alguém contou mal: ltab.len=%d em lugar de %ld\n" + +#: gmon_io.c:96 gmon_io.c:159 gmon_io.c:219 gmon_io.c:251 gmon_io.c:422 +#: gmon_io.c:449 gmon_io.c:646 gmon_io.c:671 +#, c-format +msgid "%s: bits per address has unexpected value of %u\n" +msgstr "%s: bits por endereço tem valor inesperado de %u\n" + +#: gmon_io.c:288 gmon_io.c:383 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: o arquivo é muito pequeno para ser um arquivo gmon\n" + +#: gmon_io.c:298 gmon_io.c:432 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: o arquivo `%s' tem um magic cookie inválido\n" + +#: gmon_io.c:309 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: o arquivo `%s' tem a versão %d, que não é suportada\n" + +#: gmon_io.c:339 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: marca %d inválida encontrada (arquivo corrompido?)\n" + +#: gmon_io.c:405 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: taxa de análises de perfil incompatível com o primeiro arquivo gmon\n" + +#: gmon_io.c:465 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: incompatível com o primeiro arquivo gmon\n" + +#: gmon_io.c:493 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: o arquivo '%s' não parece estar no formato gmon.out\n" + +# FIXME: comprobar con el código si bins es abreviatura de binarios o +# se refiere a la denominación inglesa de 'papelera'. cfuga +#: gmon_io.c:514 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: final de arquivo inesperado depois de ler %d/%d binários\n" + +#: gmon_io.c:547 +msgid "time is in ticks, not seconds\n" +msgstr "o tempo está em tiques, não em segundos\n" + +#: gmon_io.c:553 gmon_io.c:742 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: não sei como lidar com o arquivo de formato %d\n" + +#: gmon_io.c:560 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "O arquivo `%s' (versão %d) contém:\n" + +#: gmon_io.c:563 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d registro de histograma\n" + +#: gmon_io.c:564 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d registros de histogramas\n" + +#: gmon_io.c:566 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d registro de gráfico de chamadas\n" + +#: gmon_io.c:567 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d registros de gráficos de chamadas\n" + +#: gmon_io.c:569 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d registro de contagem de blocos básicos\n" + +#: gmon_io.c:570 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d registros de contagens de blocos básicos\n" + +#: gprof.c:152 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Modo de empleo: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][nome]] [-I dirs]\n" +"\t[-d[num]] [-k de/a] [-m contagem-min] [-t tamanho-tabela]\n" +"\t[--[no-]annotated-source[=nome]] [--[no-]exec-counts[=nome]]\n" +"\t[--[no-]flat-profile[=nome]] [--[no-]graph[=nome]]\n" +"\t[--[no-]time=nome] [--all-lines] [--brief] [--debug[=nível]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=nome] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=long] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=ESTILO]] [--no-demangle]\n" +"\t[arquivo-imagen] [arquivo-perfil...]\n" + +#: gprof.c:168 +#, c-format +msgid "Report bugs to %s\n" +msgstr "Reportar bugs para %s\n" + +#: gprof.c:242 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: não há suporte para depuração; -d ignorado\n" + +#: gprof.c:322 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: formato de arquivo %s desconhecido\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:406 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:407 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Basado no BSD gprof, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:408 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Este programa é software livre. Este programa não tem absolutamente nenhuma garantia.\n" + +#: gprof.c:449 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: estilo de desembaralhamento desconhecido `%s'\n" + +#: gprof.c:469 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Apenas um de --function-ordering e --file-ordering pode ser especificado.\n" + +#: gprof.c:569 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: perdão, o formato de arquivo `prof' ainda não é suportado\n" + +#: gprof.c:630 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: falta o histograma do arquivo gmon.out\n" + +#: gprof.c:637 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: faltam os dados do gráfico de chamadas do arquivo gmon.out\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: `%s' é incompatível com o primeiro arquivo gmon\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: final de arquivo inesperado depois de ler %d de %d amostras\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/chamada" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" para %.2f%% de %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Cada amostra conta como %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" não há tempo acumulado\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "cumulativo" + +#: hist.c:385 +msgid "self " +msgstr "si mesmo " + +#: hist.c:385 +msgid "total " +msgstr "total " + +#: hist.c:388 +msgid "time" +msgstr "tempo" + +#: hist.c:388 +msgid "calls" +msgstr "chamadas" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"perfil plano:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Perfil plano:\n" + +#: mips.c:75 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:100 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: impossível encontrar `%s'\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Arquivo %s:\n" + +#: utils.c:99 +#, c-format +msgid " <cycle %d>" +msgstr " <ciclo %d>" diff --git a/gprof/po/sv.gmo b/gprof/po/sv.gmo Binary files differnew file mode 100644 index 000000000000..3b5352b77a77 --- /dev/null +++ b/gprof/po/sv.gmo diff --git a/gprof/po/sv.po b/gprof/po/sv.po new file mode 100644 index 000000000000..c1b49c36bbed --- /dev/null +++ b/gprof/po/sv.po @@ -0,0 +1,554 @@ +# Swedish messages for gprof. +# Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +# Christian Rose <menthos@menthos.com>, 2001, 2002, 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.14rel030712\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" +"PO-Revision-Date: 2004-03-18 23:52+0100\n" +"Last-Translator: Christian Rose <menthos@menthos.com>\n" +"Language-Team: Swedish <sv@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: alpha.c:103 mips.c:57 +msgid "<indirect child>" +msgstr "<indirekt barn>" + +#: alpha.c:120 mips.c:74 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx till 0x%lx\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <indirekt_barn>\n" + +#: alpha.c:152 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: oväntat filslut\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: varning: ignorerar exekveringsräkning för grundblock (använd -l eller --line)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu exekveringar\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<okänd>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"Översta %d raderna:\n" +"\n" +" Rad Antal\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Exekveringssammanfattning:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld Exekverbara rader i denna fil\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Exekverade rader\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Procent av filen som exekverats\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Totala antalet radexekveringar\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Medelexekveringar per rad\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] båge från %s till %s traverserad %lu gånger\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t Angropsgraf (förklaring följer)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tAnropsgraf\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"upplösning: varje stickprov täcker %ld byte" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +" för %.2f%% på %.2f sekunder\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" ingen tid propagerad\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "anropad" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "totalt" + +#: cg_print.c:95 +msgid "parents" +msgstr "föräldrar" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "index" + +#: cg_print.c:97 +#, c-format +msgid "%time" +msgstr "%tid" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "själv" + +#: cg_print.c:97 +msgid "descendants" +msgstr "ättlingar" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "namn" + +#: cg_print.c:100 +msgid "children" +msgstr "barn" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "index %% tid själv barn anropad namn\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <hela cykel %d> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontant>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontant>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"Index efter funktionsnamn\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<cykel %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: kunde inte öppna %s.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: kan inte tolka mappfilen %s.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: inte i a.out-format\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: kan inte hitta .text-sektion i %s\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: slut på utrymme för %lu byte textutrymme\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: kan inte göra -c\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c stöds inte på arkitekturen %s\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: filen \"%s\" har inga symboler\n" + +#: corefile.c:758 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%s: någon räknade fel: ltab.len=%d istället för %ld\n" + +#: gmon_io.c:82 +#, c-format +msgid "%s: address size has unexpected value of %u\n" +msgstr "%s: adresstorleken har ett oväntat värde på %u\n" + +#: gmon_io.c:345 gmon_io.c:440 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: filen är för kort för att vara en gmon-fil\n" + +#: gmon_io.c:355 gmon_io.c:483 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: filen \"%s\" har felaktigt magiskt tal\n" + +#: gmon_io.c:366 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: filen \"%s\" har version %d som inte stöds\n" + +#: gmon_io.c:396 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: hittade felaktig tagg %d (är filen skadad?)\n" + +#: gmon_io.c:462 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: profileringshastighet är inkompatibel med första gmon-filen\n" + +#: gmon_io.c:510 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: inkompatibel med första gmon-filen\n" + +#: gmon_io.c:538 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: filen \"%s\" verkar inte vara i gmon.out-format\n" + +# Man brukar tala om "bins" i hashtabeller +# +#: gmon_io.c:559 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: oväntat filslut efter läsning av %d/%d poster\n" + +#: gmon_io.c:592 +msgid "time is in ticks, not seconds\n" +msgstr "tiden är i tick, inte sekunder\n" + +#: gmon_io.c:598 gmon_io.c:775 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: vet inte hur fileformat %d ska hanteras\n" + +#: gmon_io.c:605 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "Filen \"%s\" (version %d) innehåller:\n" + +#: gmon_io.c:608 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d histogrampost\n" + +#: gmon_io.c:609 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d histogramposter\n" + +#: gmon_io.c:611 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d anropsgrafpost\n" + +#: gmon_io.c:612 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d anropsgrafposter\n" + +#: gmon_io.c:614 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d grundblocksräkningspost\n" + +#: gmon_io.c:615 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d grundblocksräkningsposter\n" + +#: gprof.c:163 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Användning: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][namn]]\n" +"\t[-I kataloger] [-d[tal]] [-k från/till] [-m minsta-antal]\n" +"\t[-t table-length] [--[no-]annotated-source[=namn]]\n" +"\t[--[no-]exec-counts[=namn]] [--[no-]flat-profile[=namn]]\n" +"\t[--[no-]graph[=namn]] [--[no-]time=namn] [--all-lines] [--brief]\n" +"\t[--debug[=nivå]] [--function-ordering] [--file-ordering]\n" +"\t[--directory-path=kataloger] [--display-unused-functions]\n" +"\t[--file-format=namn] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=längd] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STIL]] [--no-demangle]\n" +"\t[bildfil] [profilfil...]\n" + +#: gprof.c:179 +#, c-format +msgid "Report bugs to %s\n" +msgstr "" +"Rapportera fel till %s,\n" +"och synpunkter på översättningen till sv@li.org\n" + +#: gprof.c:253 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: felsökning stöds inte; -d ignorerades\n" + +#: gprof.c:333 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: okänt filformat %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:417 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:418 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "Baserat på BSD gprof, copyright 1983 Regents of the University of California.\n" + +#: gprof.c:419 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Detta program är fri programvara. Detta program har ingen som helst garanti.\n" + +#: gprof.c:460 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: okänd avmanglingsstil \"%s\"\n" + +#: gprof.c:480 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "%s: Endast en av --function-ordering och --file-ordering kan anges.\n" + +#: gprof.c:578 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: tyvärr, filformatet \"prof\" stöds inte än\n" + +#: gprof.c:639 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: gmon.out-filen saknar histogram\n" + +#: gprof.c:646 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: gmon.out-filen saknar anropsgrafdata\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: \"%s\" är inkompatibel med första gmon-filen\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "%s: %s: oväntat filslut efter läsning av %d av %d stickprov\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/anrop" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" för %.2f%% av %.2f %s\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Varje stickprov räknas som %g %s.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" ingen ackumulerad tid\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "kumulativ" + +#: hist.c:385 +msgid "self " +msgstr "själv" + +#: hist.c:385 +msgid "total " +msgstr "totalt" + +#: hist.c:388 +msgid "time" +msgstr "tid" + +#: hist.c:388 +msgid "calls" +msgstr "anrop" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"platt profil:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Platt profil:\n" + +#: mips.c:85 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:110 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: kunde inte hitta \"%s\"\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** Fil %s:\n" + +#: utils.c:109 +#, c-format +msgid " <cycle %d>" +msgstr " <cykel %d>" + +#~ msgid "%s: bfd_vma has unexpected size of %ld bytes\n" +#~ msgstr "%s: bfd_vma har en oväntad storlek på %ld byte\n" diff --git a/gprof/po/tr.gmo b/gprof/po/tr.gmo Binary files differnew file mode 100644 index 000000000000..37c1c4617fae --- /dev/null +++ b/gprof/po/tr.gmo diff --git a/gprof/po/tr.po b/gprof/po/tr.po new file mode 100644 index 000000000000..aae0c00d1e2b --- /dev/null +++ b/gprof/po/tr.po @@ -0,0 +1,576 @@ +# translation of gprof-2.14rel030712.tr.po to Turkish +# Copyright (C) 2003 Free Software Foundation, Inc. +# Deniz Akkus Kanca <deniz@arayan.com>, 2001,2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gprof 2.14rel030712\n" +"POT-Creation-Date: 2003-07-11 13:58+0930\n" +"PO-Revision-Date: 2003-08-17 15:08+0300\n" +"Last-Translator: Deniz Akkus Kanca <deniz@arayan.com>\n" +"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0\n" + +#: alpha.c:103 mips.c:57 +msgid "<indirect child>" +msgstr "<dolaylı ast>" + +#: alpha.c:120 mips.c:74 +#, c-format +msgid "[find_call] %s: 0x%lx to 0x%lx\n" +msgstr "[find_call] %s: 0x%lx'dan 0x%lx'a\n" + +#: alpha.c:142 +#, c-format +msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n" +msgstr "[find_call] 0x%lx: jsr%s <dolaylı_ast>\n" + +#: alpha.c:152 +#, c-format +msgid "[find_call] 0x%lx: bsr" +msgstr "[find_call] 0x%lx: bsr" + +#: basic_blocks.c:134 call_graph.c:94 hist.c:98 +#, c-format +msgid "%s: %s: unexpected end of file\n" +msgstr "%s: %s: beklenmeyen dosyasonu\n" + +#: basic_blocks.c:202 +#, c-format +msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n" +msgstr "%s: uyarı: temel blok yürütme sayıları yoksayıldı (-l veya --line kullanın)\n" + +#. FIXME: This only works if bfd_vma is unsigned long. +#: basic_blocks.c:295 basic_blocks.c:305 +#, c-format +msgid "%s:%d: (%s:0x%lx) %lu executions\n" +msgstr "%s:%d: (%s:0x%lx) %lu yürütme\n" + +#: basic_blocks.c:296 basic_blocks.c:306 +msgid "<unknown>" +msgstr "<bilinmeyen>" + +#: basic_blocks.c:553 +#, c-format +msgid "" +"\n" +"\n" +"Top %d Lines:\n" +"\n" +" Line Count\n" +"\n" +msgstr "" +"\n" +"\n" +"Tepe %d Satır:\n" +"\n" +" Satır Sayı\n" +"\n" + +#: basic_blocks.c:577 +msgid "" +"\n" +"Execution Summary:\n" +"\n" +msgstr "" +"\n" +"Yürütme Özeti:\n" +"\n" + +#: basic_blocks.c:578 +#, c-format +msgid "%9ld Executable lines in this file\n" +msgstr "%9ld yürütülür satır -- bu dosyada\n" + +#: basic_blocks.c:580 +#, c-format +msgid "%9ld Lines executed\n" +msgstr "%9ld Yürütülen Satır\n" + +#: basic_blocks.c:581 +#, c-format +msgid "%9.2f Percent of the file executed\n" +msgstr "%9.2f Dosyanın yürütülen kısım yüzdesi\n" + +#: basic_blocks.c:585 +#, c-format +msgid "" +"\n" +"%9lu Total number of line executions\n" +msgstr "" +"\n" +"%9lu Toplam satır yürütüş sayısı\n" + +#: basic_blocks.c:587 +#, c-format +msgid "%9.2f Average executions per line\n" +msgstr "%9.2f Satır başına ortalama yürütüş sayısı\n" + +#: call_graph.c:71 +#, c-format +msgid "[cg_tally] arc from %s to %s traversed %lu times\n" +msgstr "[cg_tally] %s'dan %s'a olan yay %lu defa geçildi\n" + +#: cg_print.c:73 +msgid "" +"\t\t Call graph (explanation follows)\n" +"\n" +msgstr "" +"\t\t ÇaÄŸrı grafiÄŸi (açıklama aÅŸağıda)\n" +"\n" + +#: cg_print.c:75 +msgid "" +"\t\t\tCall graph\n" +"\n" +msgstr "" +"\t\t\tÇaÄŸrı grafiÄŸi\n" +"\n" + +#: cg_print.c:78 hist.c:363 +#, c-format +msgid "" +"\n" +"granularity: each sample hit covers %ld byte(s)" +msgstr "" +"\n" +"Öğe boyu: her örnek %ld bayt içermektedir" + +#: cg_print.c:82 +#, c-format +msgid "" +" for %.2f%% of %.2f seconds\n" +"\n" +msgstr "" +"Toplam %2$.2f saniyenin %1$.2f%%'si için\n" +"\n" + +#: cg_print.c:86 +msgid "" +" no time propagated\n" +"\n" +msgstr "" +" zaman ilerletilmedi\n" +"\n" + +#: cg_print.c:95 cg_print.c:98 cg_print.c:100 +msgid "called" +msgstr "çaÄŸrıldı" + +#: cg_print.c:95 cg_print.c:100 +msgid "total" +msgstr "toplam" + +#: cg_print.c:95 +msgid "parents" +msgstr "üstler" + +#: cg_print.c:97 cg_print.c:98 +msgid "index" +msgstr "indeks" + +#: cg_print.c:97 +#, c-format +msgid "%time" +msgstr "%time" + +#: cg_print.c:97 cg_print.c:98 +msgid "self" +msgstr "kendisi" + +#: cg_print.c:97 +msgid "descendants" +msgstr "astlar" + +#: cg_print.c:98 hist.c:389 +msgid "name" +msgstr "isim" + +#: cg_print.c:100 +msgid "children" +msgstr "astlar" + +#: cg_print.c:105 +#, c-format +msgid "index %% time self children called name\n" +msgstr "indeks %% zaman kendi astlar çaÄŸrıldı isim\n" + +#: cg_print.c:129 +#, c-format +msgid " <cycle %d as a whole> [%d]\n" +msgstr " <%d'yi bütün olarak çevrimler> [%d]\n" + +#: cg_print.c:363 +#, c-format +msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <kendiliÄŸinden>\n" + +#: cg_print.c:364 +#, c-format +msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" +msgstr "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <kendiliÄŸinden>\n" + +#: cg_print.c:604 +msgid "" +"Index by function name\n" +"\n" +msgstr "" +"İşlev adına göre indeks\n" +"\n" + +#: cg_print.c:661 cg_print.c:670 +#, c-format +msgid "<cycle %d>" +msgstr "<çevrim %d>" + +#: corefile.c:64 +#, c-format +msgid "%s: could not open %s.\n" +msgstr "%s: %s açılamadı.\n" + +#: corefile.c:78 corefile.c:112 +#, c-format +msgid "%s: unable to parse mapping file %s.\n" +msgstr "%s: eÅŸlem dosyası %s ayrıştırılamadı.\n" + +#: corefile.c:155 +#, c-format +msgid "%s: %s: not in a.out format\n" +msgstr "%s: %s: a.out biçeminde deÄŸil\n" + +#: corefile.c:166 +#, c-format +msgid "%s: can't find .text section in %s\n" +msgstr "%s: %s içerisinde .text (metin) bölümü bulunamadı\n" + +#: corefile.c:225 +#, c-format +msgid "%s: ran out room for %lu bytes of text space\n" +msgstr "%s: %lu bayt metin yeri için yer bulunamadı\n" + +#: corefile.c:239 +#, c-format +msgid "%s: can't do -c\n" +msgstr "%s: -c yapılamıyor\n" + +#: corefile.c:276 +#, c-format +msgid "%s: -c not supported on architecture %s\n" +msgstr "%s: -c %s platformu üzerinde desteklenmiyor\n" + +#: corefile.c:447 +#, c-format +msgid "%s: file `%s' has no symbols\n" +msgstr "%s: `%s' dosyası sembol içermiyor\n" + +#: corefile.c:758 +#, c-format +msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n" +msgstr "%1$s: hatalı sayım: %3$ld yerine ltab.len=%2$d\n" + +#: gmon_io.c:82 +#, c-format +msgid "%s: address size has unexpected value of %u\n" +msgstr "%s: adres boyu, beklenmeyen %u deÄŸerine sahip\n" + +#: gmon_io.c:345 gmon_io.c:440 +#, c-format +msgid "%s: file too short to be a gmon file\n" +msgstr "%s: Dosya bir gmon dosyası olmak için çok kısa\n" + +#: gmon_io.c:355 gmon_io.c:483 +#, c-format +msgid "%s: file `%s' has bad magic cookie\n" +msgstr "%s: `%s' dosyasında kötü sihirli çerez var\n" + +#: gmon_io.c:366 +#, c-format +msgid "%s: file `%s' has unsupported version %d\n" +msgstr "%s: `%s' dosyası desteklenmeyen %d sürümünde\n" + +#: gmon_io.c:396 +#, c-format +msgid "%s: %s: found bad tag %d (file corrupted?)\n" +msgstr "%s: %s: Hatalı etiket %d bulundu (dosya bozuk mu?)\n" + +#: gmon_io.c:462 +#, c-format +msgid "%s: profiling rate incompatible with first gmon file\n" +msgstr "%s: profilleme hızı ilk gmon dosyası ile uyumlu deÄŸil\n" + +#: gmon_io.c:510 +#, c-format +msgid "%s: incompatible with first gmon file\n" +msgstr "%s: ilk gmon dosyası ile uyumlu deÄŸil\n" + +#: gmon_io.c:538 +#, c-format +msgid "%s: file '%s' does not appear to be in gmon.out format\n" +msgstr "%s: '%s' dosyası gmon.out biçeminde deÄŸil\n" + +#: gmon_io.c:559 +#, c-format +msgid "%s: unexpected EOF after reading %d/%d bins\n" +msgstr "%s: %d/%d sele okunduktan sonra beklenmeyen dosyasonu (EOF) bulundu\n" + +#: gmon_io.c:592 +msgid "time is in ticks, not seconds\n" +msgstr "zaman tık olarak veriliyor, saniye olarak deÄŸil\n" + +#: gmon_io.c:598 gmon_io.c:775 +#, c-format +msgid "%s: don't know how to deal with file format %d\n" +msgstr "%s: %d dosya biçeminin nasıl iÅŸleneceÄŸi bilinmiyor\n" + +#: gmon_io.c:605 +#, c-format +msgid "File `%s' (version %d) contains:\n" +msgstr "`%s' Dosyası (%d sürümü) aÅŸağıdakileri içeriyor:\n" + +#: gmon_io.c:608 +#, c-format +msgid "\t%d histogram record\n" +msgstr "\t%d geçmiÅŸ grafiÄŸi kaydı\n" + +#: gmon_io.c:609 +#, c-format +msgid "\t%d histogram records\n" +msgstr "\t%d geçmiÅŸ grafiÄŸi kayıtları\n" + +#: gmon_io.c:611 +#, c-format +msgid "\t%d call-graph record\n" +msgstr "\t%d çaÄŸrı grafiÄŸi kaydı\n" + +#: gmon_io.c:612 +#, c-format +msgid "\t%d call-graph records\n" +msgstr "\t%d çaÄŸrı grafiÄŸi kayıtları\n" + +#: gmon_io.c:614 +#, c-format +msgid "\t%d basic-block count record\n" +msgstr "\t%d temel blok sayım kaydı\n" + +#: gmon_io.c:615 +#, c-format +msgid "\t%d basic-block count records\n" +msgstr "\t%d temel blok sayım kayıtları\n" + +#: gprof.c:163 +#, c-format +msgid "" +"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n" +"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n" +"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n" +"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n" +"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n" +"\t[--function-ordering] [--file-ordering]\n" +"\t[--directory-path=dirs] [--display-unused-functions]\n" +"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n" +"\t[--no-static] [--print-path] [--separate-files]\n" +"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n" +"\t[--version] [--width=n] [--ignore-non-functions]\n" +"\t[--demangle[=STYLE]] [--no-demangle]\n" +"\t[image-file] [profile-file...]\n" +msgstr "" +"Kullanım: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][isim]] [-I dizinler]\n" +"\t[-d[sayı]] [-k hedeften/hedefe] [-m minimum-sayı] [-t tablo-uzunluÄŸu]\n" +"\t[--[no-]annotated-source[=isim]] açıklamalı kaynak kodunu gösterir/göstermez\n" +"\t[--[no-]exec-counts[=isim]] yürütme sayısını gösterir/göstermez\n" +"\t[--[no-]flat-profile[=isim]] düz profil çıktılar\n" +"\t[--[no-]graph[=isim]] grafik çıktılar\n" +"\t[--[no-]time=isim] zaman bilgisi çıktılar\n" +"\t[--all-lines] bütün satırları gösterir\n" +"\t[--brief] kısa çıktı verir\n" +"\t[--debug[=seviye]] hata ayıklama seviyesini atar\n" +"\t[--function-ordering] iÅŸlev adına göre sıralar\n" +"\t[--file-ordering] dosya adına göre sıralar\n" +"\t[--directory-path=dizinler] dizin adres yolunu belirtir\n" +"\t[--display-unused-functions] kullanılmayan iÅŸlevleri gösterir\n" +"\t[--file-format=isim] dosya biçemini belirtir\n" +"\t[--file-info] dosya bilgisini gösterir\n" +"\t[--help] yardım bilgisi gösterir\n" +"\t[--line] satır bilgisi gösterir\n" +"\t[--min-count=n] minimum sayıyı atar\n" +"\t[--no-static] statik iÅŸlemleri yoksayar\n" +"\t[--print-path] yazdırma yolu\n" +"\t[--separate-files] ayrı dosyalar\n" +"\t[--static-call-graph] statik çaÄŸrı grafiÄŸi\n" +"\t[--sum] toplam\n" +"\t[--table-length=uzunluk] tablo uzunluÄŸu\n" +"\t[--traditional] geleneksel\n" +"\t[--version] sürüm bilgisi gösterir\n" +"\t[--width=n] geniÅŸlik\n" +"\t[--ignore-non-functions] iÅŸlev olmayanları yoksayar\n" +"\t[--demangle[=TARZ]] düzeltme tarzı atar\n" +"\t[--no-demangle] düzeltme uygulamaz\n" +"\t[görüntü-dosyası] [profil-dosyası...]\n" + +#: gprof.c:179 +#, c-format +msgid "Report bugs to %s\n" +msgstr "" +"Yazılım hatalarını %s adresine,\n" +"çeviri hatalarını <gnu-tr-u12a@lists.sourceforge.net> adresine gönderin\n" + +#: gprof.c:253 +#, c-format +msgid "%s: debugging not supported; -d ignored\n" +msgstr "%s: hata ayıklama desteklenmiyor; -d yoksayıldı\n" + +#: gprof.c:333 +#, c-format +msgid "%s: unknown file format %s\n" +msgstr "%s: bilinmeyen dosya biçemi %s\n" + +#. This output is intended to follow the GNU standards document. +#: gprof.c:417 +#, c-format +msgid "GNU gprof %s\n" +msgstr "GNU gprof %s\n" + +#: gprof.c:418 +msgid "Based on BSD gprof, copyright 1983 Regents of the University of California.\n" +msgstr "BSD gprof baz alınmıştır. BSD gprof Telif Hakkı 1983 Regents of the University of California.\n" + +#: gprof.c:419 +msgid "This program is free software. This program has absolutely no warranty.\n" +msgstr "Bu yazılım bir serbest yazılımdır. Bu yazılımın herhangi bir garantisi yoktur.\n" + +#: gprof.c:460 +#, c-format +msgid "%s: unknown demangling style `%s'\n" +msgstr "%s: bilinmeyen düzeltme tarzı `%s'\n" + +#: gprof.c:480 +#, c-format +msgid "%s: Only one of --function-ordering and --file-ordering may be specified.\n" +msgstr "" +"%s: --function-ordering (iÅŸleve göre sırala) ve\n" +" --file-ordering (dosyaya göre sırala) seçeneklerinin biri seçilebilir.\n" + +#: gprof.c:578 +#, c-format +msgid "%s: sorry, file format `prof' is not yet supported\n" +msgstr "%s: `prof' dosya biçemi henüz desteklenmiyor\n" + +#: gprof.c:639 +#, c-format +msgid "%s: gmon.out file is missing histogram\n" +msgstr "%s: gmon.out dosyasında geçmiÅŸ grafiÄŸi yok\n" + +#: gprof.c:646 +#, c-format +msgid "%s: gmon.out file is missing call-graph data\n" +msgstr "%s: gmon.out dosyasında çaÄŸrı grafik verisi yok\n" + +#: hist.c:127 +#, c-format +msgid "%s: `%s' is incompatible with first gmon file\n" +msgstr "%s: `%s' ilk gmon dosyası ile uyumlu deÄŸil\n" + +#: hist.c:143 +#, c-format +msgid "%s: %s: unexpected EOF after reading %d of %d samples\n" +msgstr "" +"%1$s: %2$s: Toplam %4$d örneÄŸin %3$d'si okunduktan sonra\n" +"beklenmeyen dosyasonu(EOF) bulundu\n" + +#: hist.c:359 +#, c-format +msgid "%c%c/call" +msgstr "%c%c/çaÄŸrı" + +#: hist.c:367 +#, c-format +msgid "" +" for %.2f%% of %.2f %s\n" +"\n" +msgstr "" +" Toplam %2$.2f %3$s'nin %1$.2f%%'si okundu\n" +"\n" + +#: hist.c:373 +#, c-format +msgid "" +"\n" +"Each sample counts as %g %s.\n" +msgstr "" +"\n" +"Her örnek %g %s sayılıyor.\n" + +#: hist.c:378 +msgid "" +" no time accumulated\n" +"\n" +msgstr "" +" zamanlama deÄŸeri biriktirilemedi\n" +"\n" + +#: hist.c:385 +msgid "cumulative" +msgstr "birikmiÅŸ" + +#: hist.c:385 +msgid "self " +msgstr "kendisi " + +#: hist.c:385 +msgid "total " +msgstr "toplam " + +#: hist.c:388 +msgid "time" +msgstr "zaman" + +#: hist.c:388 +msgid "calls" +msgstr "çaÄŸrı" + +#: hist.c:481 +msgid "" +"\n" +"\n" +"\n" +"flat profile:\n" +msgstr "" +"\n" +"\n" +"\n" +"düz profil:\n" + +#: hist.c:487 +msgid "Flat profile:\n" +msgstr "Düz profil:\n" + +#: mips.c:85 +#, c-format +msgid "[find_call] 0x%lx: jal" +msgstr "[find_call] 0x%lx: jal" + +#: mips.c:110 +#, c-format +msgid "[find_call] 0x%lx: jalr\n" +msgstr "[find_call] 0x%lx: jalr\n" + +#: source.c:166 +#, c-format +msgid "%s: could not locate `%s'\n" +msgstr "%s: `%s' bulunamadı\n" + +#: source.c:241 +#, c-format +msgid "*** File %s:\n" +msgstr "*** %s Dosyası:\n" + +#: utils.c:109 +#, c-format +msgid " <cycle %d>" +msgstr " <çevrim %d>" + +#~ msgid "%s: bfd_vma has unexpected size of %ld bytes\n" +#~ msgstr "%s: beklenmeyen boyut: bfd_vma'nın boyutu %ld bayt\n" diff --git a/gprof/search_list.c b/gprof/search_list.c new file mode 100644 index 000000000000..50b4cf2e3d89 --- /dev/null +++ b/gprof/search_list.c @@ -0,0 +1,62 @@ +/* search-list.c + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "gprof.h" +#include "search_list.h" + + +void +search_list_append (list, paths) + Search_List *list; + const char *paths; +{ + Search_List_Elem *new_el; + const char *beg, *colon; + unsigned int len; + + colon = paths - 1; + do + { + beg = colon + 1; + colon = strchr (beg, PATH_SEP_CHAR); + + if (colon) + len = colon - beg; + else + len = strlen (beg); + + new_el = (Search_List_Elem *) xmalloc (sizeof (*new_el) + len); + memcpy (new_el->path, beg, len); + new_el->path[len] = '\0'; + + /* Append new path at end of list. */ + new_el->next = 0; + + if (list->tail) + list->tail->next = new_el; + else + list->head = new_el; + + list->tail = new_el; + } + while (colon); +} diff --git a/gprof/search_list.h b/gprof/search_list.h new file mode 100644 index 000000000000..56361df3f74d --- /dev/null +++ b/gprof/search_list.h @@ -0,0 +1,48 @@ +/* search-list.h + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef search_list_h +#define search_list_h + +/* Non-Posix systems use semi-colon as directory separator in lists, + since colon is part of drive letter spec. */ +#if defined (__MSDOS__) || defined (_WIN32) +#define PATH_SEP_CHAR ';' +#else +#define PATH_SEP_CHAR ':' +#endif + +typedef struct search_list_elem + { + struct search_list_elem *next; + char path[1]; + } +Search_List_Elem; + +typedef struct + { + struct search_list_elem *head; + struct search_list_elem *tail; + } +Search_List; + +extern void search_list_append PARAMS ((Search_List *, const char *)); + +#endif /* search_list_h */ diff --git a/gprof/source.c b/gprof/source.c new file mode 100644 index 000000000000..4074b2ba0cdb --- /dev/null +++ b/gprof/source.c @@ -0,0 +1,267 @@ +/* source.c - Keep track of source files. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "gprof.h" +#include "libiberty.h" +#include "filenames.h" +#include "search_list.h" +#include "source.h" + +#define EXT_ANNO "-ann" /* Postfix of annotated files. */ + +/* Default option values. */ +bfd_boolean create_annotation_files = FALSE; + +Search_List src_search_list = {0, 0}; +Source_File *first_src_file = 0; + + +Source_File * +source_file_lookup_path (path) + const char *path; +{ + Source_File *sf; + + for (sf = first_src_file; sf; sf = sf->next) + { + if (FILENAME_CMP (path, sf->name) == 0) + break; + } + + if (!sf) + { + /* Create a new source file descriptor. */ + sf = (Source_File *) xmalloc (sizeof (*sf)); + + memset (sf, 0, sizeof (*sf)); + + sf->name = xstrdup (path); + sf->next = first_src_file; + first_src_file = sf; + } + + return sf; +} + + +Source_File * +source_file_lookup_name (filename) + const char *filename; +{ + const char *fname; + Source_File *sf; + + /* The user cannot know exactly how a filename will be stored in + the debugging info (e.g., ../include/foo.h + vs. /usr/include/foo.h). So we simply compare the filename + component of a path only. */ + for (sf = first_src_file; sf; sf = sf->next) + { + fname = strrchr (sf->name, '/'); + + if (fname) + ++fname; + else + fname = sf->name; + + if (FILENAME_CMP (filename, fname) == 0) + break; + } + + return sf; +} + + +FILE * +annotate_source (sf, max_width, annote, arg) + Source_File *sf; + unsigned int max_width; + void (*annote) PARAMS ((char *, unsigned int, int, void *)); + void *arg; +{ + static bfd_boolean first_file = TRUE; + int i, line_num, nread; + bfd_boolean new_line; + char buf[8192]; + char fname[PATH_MAX]; + char *annotation, *name_only; + FILE *ifp, *ofp; + Search_List_Elem *sle = src_search_list.head; + + /* Open input file. If open fails, walk along search-list until + open succeeds or reaching end of list. */ + strcpy (fname, sf->name); + + if (IS_ABSOLUTE_PATH (sf->name)) + sle = 0; /* Don't use search list for absolute paths. */ + + name_only = 0; + while (TRUE) + { + DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n", + sf->name, fname)); + + ifp = fopen (fname, FOPEN_RB); + if (ifp) + break; + + if (!sle && !name_only) + { + name_only = strrchr (sf->name, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + { + char *bslash = strrchr (sf->name, '\\'); + if (name_only == NULL || (bslash != NULL && bslash > name_only)) + name_only = bslash; + if (name_only == NULL && sf->name[0] != '\0' && sf->name[1] == ':') + name_only = (char *)sf->name + 1; + } +#endif + if (name_only) + { + /* Try search-list again, but this time with name only. */ + ++name_only; + sle = src_search_list.head; + } + } + + if (sle) + { + strcpy (fname, sle->path); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* d:foo is not the same thing as d:/foo! */ + if (fname[strlen (fname) - 1] == ':') + strcat (fname, "."); +#endif + strcat (fname, "/"); + + if (name_only) + strcat (fname, name_only); + else + strcat (fname, sf->name); + + sle = sle->next; + } + else + { + if (errno == ENOENT) + fprintf (stderr, _("%s: could not locate `%s'\n"), + whoami, sf->name); + else + perror (sf->name); + + return 0; + } + } + + ofp = stdout; + + if (create_annotation_files) + { + /* Try to create annotated source file. */ + const char *filename; + + /* Create annotation files in the current working directory. */ + filename = strrchr (sf->name, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + { + char *bslash = strrchr (sf->name, '\\'); + if (filename == NULL || (bslash != NULL && bslash > filename)) + filename = bslash; + if (filename == NULL && sf->name[0] != '\0' && sf->name[1] == ':') + filename = sf->name + 1; + } +#endif + if (filename) + ++filename; + else + filename = sf->name; + + strcpy (fname, filename); + strcat (fname, EXT_ANNO); +#ifdef __MSDOS__ + { + /* foo.cpp-ann can overwrite foo.cpp due to silent truncation of + file names on 8+3 filesystems. Their `stat' better be good... */ + struct stat buf1, buf2; + + if (stat (filename, &buf1) == 0 + && stat (fname, &buf2) == 0 + && buf1.st_ino == buf2.st_ino) + { + char *dot = strrchr (fname, '.'); + + if (dot) + *dot = '\0'; + strcat (fname, ".ann"); + } + } +#endif + ofp = fopen (fname, "w"); + + if (!ofp) + { + perror (fname); + return 0; + } + } + + /* Print file names if output goes to stdout + and there are more than one source file. */ + if (ofp == stdout) + { + if (first_file) + first_file = FALSE; + else + fputc ('\n', ofp); + + if (first_output) + first_output = FALSE; + else + fprintf (ofp, "\f\n"); + + fprintf (ofp, _("*** File %s:\n"), sf->name); + } + + annotation = xmalloc (max_width + 1); + line_num = 1; + new_line = TRUE; + + while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0) + { + for (i = 0; i < nread; ++i) + { + if (new_line) + { + (*annote) (annotation, max_width, line_num, arg); + fputs (annotation, ofp); + ++line_num; + new_line = FALSE; + } + + new_line = (buf[i] == '\n'); + fputc (buf[i], ofp); + } + } + + free (annotation); + return ofp; +} diff --git a/gprof/source.h b/gprof/source.h new file mode 100644 index 000000000000..53eac5eca737 --- /dev/null +++ b/gprof/source.h @@ -0,0 +1,62 @@ +/* source.h + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef source_h +#define source_h + +typedef struct source_file + { + struct source_file *next; + const char *name; /* Name of source file. */ + unsigned long ncalls; /* # of "calls" to this file. */ + int num_lines; /* # of lines in file. */ + int nalloced; /* Number of lines allocated. */ + void **line; /* Usage-dependent per-line data. */ + } +Source_File; + +/* Options. */ + +/* Create annotated output files? */ +extern bfd_boolean create_annotation_files; + +/* List of directories to search for source files. */ +extern Search_List src_search_list; + +/* Chain of source-file descriptors. */ +extern Source_File *first_src_file; + +/* Returns pointer to source file descriptor for PATH/FILENAME. */ +extern Source_File *source_file_lookup_path PARAMS ((const char *)); +extern Source_File *source_file_lookup_name PARAMS ((const char *)); + +/* Read source file SF output annotated source. The annotation is at + MAX_WIDTH characters wide and for each source-line an annotation is + obtained by invoking function ANNOTE. ARG is an argument passed to + ANNOTE that is left uninterpreted by annotate_source(). + + Returns a pointer to the output file (which maybe stdout) such + that summary statistics can be printed. If the returned file + is not stdout, it should be closed when done with it. */ +extern FILE *annotate_source + PARAMS ((Source_File *sf, unsigned int max_width, + void (*annote) (char *, unsigned int, int, PTR arg), + PTR arg)); +#endif /* source_h */ diff --git a/gprof/sparc.c b/gprof/sparc.c new file mode 100644 index 000000000000..7fb9b1957446 --- /dev/null +++ b/gprof/sparc.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" + + /* + * opcode of the `callf' instruction + */ +#define CALL (0xc0000000) + +void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +void +sparc_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + bfd_vma pc, dest_pc; + unsigned int insn; + Sym *child; + + if (core_text_space == 0) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", + parent->name, (unsigned long) p_lowpc, + (unsigned long) p_highpc)); + for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4) + { + insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space + + pc - core_text_sect->vma)); + if (insn & CALL) + { + DBG (CALLDEBUG, + printf ("[find_call] 0x%lx: callf", (unsigned long) pc)); + /* + * Regular pc relative addressing check that this is the + * address of a function. + */ + dest_pc = pc + (((bfd_signed_vma) (insn & 0x3fffffff) + ^ 0x20000000) - 0x20000000); + if (dest_pc >= s_lowpc && dest_pc <= s_highpc) + { + child = sym_lookup (&symtab, dest_pc); + DBG (CALLDEBUG, + printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n", + (unsigned long) dest_pc, child->name, + (unsigned long) child->addr)); + if (child->addr == dest_pc) + { + /* a hit: */ + arc_add (parent, child, (unsigned long) 0); + continue; + } + } + /* + * Something funny going on. + */ + DBG (CALLDEBUG, printf ("\tbut it's a botch\n")); + } + } +} diff --git a/gprof/stamp-h.in b/gprof/stamp-h.in new file mode 100644 index 000000000000..9788f70238c9 --- /dev/null +++ b/gprof/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/gprof/sym_ids.c b/gprof/sym_ids.c new file mode 100644 index 000000000000..f75088a30ea8 --- /dev/null +++ b/gprof/sym_ids.c @@ -0,0 +1,391 @@ +/* sym_ids.c + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "libiberty.h" +#include "safe-ctype.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "sym_ids.h" + +struct sym_id + { + struct sym_id *next; + char *spec; /* Parsing modifies this. */ + Table_Id which_table; + bfd_boolean has_right; + + struct match + { + int prev_index; /* Index of prev match. */ + Sym *prev_match; /* Previous match. */ + Sym *first_match; /* Chain of all matches. */ + Sym sym; + } + left, right; + } + *id_list; + +static void parse_spec + PARAMS ((char *, Sym *)); +static void parse_id + PARAMS ((struct sym_id *)); +static bfd_boolean match + PARAMS ((Sym *, Sym *)); +static void extend_match + PARAMS ((struct match *, Sym *, Sym_Table *, bfd_boolean)); + + +Sym_Table syms[NUM_TABLES]; + +#ifdef DEBUG +const char *table_name[] = +{ + "INCL_GRAPH", "EXCL_GRAPH", + "INCL_ARCS", "EXCL_ARCS", + "INCL_FLAT", "EXCL_FLAT", + "INCL_TIME", "EXCL_TIME", + "INCL_ANNO", "EXCL_ANNO", + "INCL_EXEC", "EXCL_EXEC" +}; +#endif /* DEBUG */ + +/* This is the table in which we keep all the syms that match + the right half of an arc id. It is NOT sorted according + to the addresses, because it is accessed only through + the left half's CHILDREN pointers (so it's crucial not + to reorder this table once pointers into it exist). */ +static Sym_Table right_ids; + +static Source_File non_existent_file = +{ + 0, "<non-existent-file>", 0, 0, 0, NULL +}; + + +void +sym_id_add (spec, which_table) + const char *spec; + Table_Id which_table; +{ + struct sym_id *id; + int len = strlen (spec); + + id = (struct sym_id *) xmalloc (sizeof (*id) + len + 1); + memset (id, 0, sizeof (*id)); + + id->spec = (char *) id + sizeof (*id); + strcpy (id->spec, spec); + id->which_table = which_table; + + id->next = id_list; + id_list = id; +} + + +/* A spec has the syntax FILENAME:(FUNCNAME|LINENUM). As a convenience + to the user, a spec without a colon is interpreted as: + + (i) a FILENAME if it contains a dot + (ii) a FUNCNAME if it starts with a non-digit character + (iii) a LINENUM if it starts with a digit + + A FUNCNAME containing a dot can be specified by :FUNCNAME, a + FILENAME not containing a dot can be specified by FILENAME. */ + +static void +parse_spec (spec, sym) + char *spec; + Sym *sym; +{ + char *colon; + + sym_init (sym); + colon = strrchr (spec, ':'); + + if (colon) + { + *colon = '\0'; + + if (colon > spec) + { + sym->file = source_file_lookup_name (spec); + + if (!sym->file) + sym->file = &non_existent_file; + } + + spec = colon + 1; + + if (strlen (spec)) + { + if (ISDIGIT (spec[0])) + sym->line_num = atoi (spec); + else + sym->name = spec; + } + } + else if (strlen (spec)) + { + /* No colon: spec is a filename if it contains a dot. */ + if (strchr (spec, '.')) + { + sym->file = source_file_lookup_name (spec); + + if (!sym->file) + sym->file = &non_existent_file; + } + else if (ISDIGIT (*spec)) + { + sym->line_num = atoi (spec); + } + else if (strlen (spec)) + { + sym->name = spec; + } + } +} + + +/* A symbol id has the syntax SPEC[/SPEC], where SPEC is is defined + by parse_spec(). */ + +static void +parse_id (id) + struct sym_id *id; +{ + char *slash; + + DBG (IDDEBUG, printf ("[parse_id] %s -> ", id->spec)); + + slash = strchr (id->spec, '/'); + if (slash) + { + parse_spec (slash + 1, &id->right.sym); + *slash = '\0'; + id->has_right = TRUE; + } + parse_spec (id->spec, &id->left.sym); + +#ifdef DEBUG + if (debug_level & IDDEBUG) + { + printf ("%s:", id->left.sym.file ? id->left.sym.file->name : "*"); + + if (id->left.sym.name) + printf ("%s", id->left.sym.name); + else if (id->left.sym.line_num) + printf ("%d", id->left.sym.line_num); + else + printf ("*"); + + if (id->has_right) + { + printf ("/%s:", + id->right.sym.file ? id->right.sym.file->name : "*"); + + if (id->right.sym.name) + printf ("%s", id->right.sym.name); + else if (id->right.sym.line_num) + printf ("%d", id->right.sym.line_num); + else + printf ("*"); + } + + printf ("\n"); + } +#endif +} + + +/* Return TRUE iff PATTERN matches SYM. */ + +static bfd_boolean +match (pattern, sym) + Sym *pattern; + Sym *sym; +{ + return (pattern->file ? pattern->file == sym->file : TRUE) + && (pattern->line_num ? pattern->line_num == sym->line_num : TRUE) + && (pattern->name + ? strcmp (pattern->name, + sym->name+(discard_underscores && sym->name[0] == '_')) == 0 + : TRUE); +} + + +static void +extend_match (m, sym, tab, second_pass) + struct match *m; + Sym *sym; + Sym_Table *tab; + bfd_boolean second_pass; +{ + if (m->prev_match != sym - 1) + { + /* Discontinuity: add new match to table. */ + if (second_pass) + { + tab->base[tab->len] = *sym; + m->prev_index = tab->len; + + /* Link match into match's chain. */ + tab->base[tab->len].next = m->first_match; + m->first_match = &tab->base[tab->len]; + } + + ++tab->len; + } + + /* Extend match to include this symbol. */ + if (second_pass) + tab->base[m->prev_index].end_addr = sym->end_addr; + + m->prev_match = sym; +} + + +/* Go through sym_id list produced by option processing and fill + in the various symbol tables indicating what symbols should + be displayed or suppressed for the various kinds of outputs. + + This can potentially produce huge tables and in particulars + tons of arcs, but this happens only if the user makes silly + requests---you get what you ask for! */ + +void +sym_id_parse () +{ + Sym *sym, *left, *right; + struct sym_id *id; + Sym_Table *tab; + + /* Convert symbol ids into Syms, so we can deal with them more easily. */ + for (id = id_list; id; id = id->next) + parse_id (id); + + /* First determine size of each table. */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + for (id = id_list; id; id = id->next) + { + if (match (&id->left.sym, sym)) + extend_match (&id->left, sym, &syms[id->which_table], FALSE); + + if (id->has_right && match (&id->right.sym, sym)) + extend_match (&id->right, sym, &right_ids, FALSE); + } + } + + /* Create tables of appropriate size and reset lengths. */ + for (tab = syms; tab < &syms[NUM_TABLES]; ++tab) + { + if (tab->len) + { + tab->base = (Sym *) xmalloc (tab->len * sizeof (Sym)); + tab->limit = tab->base + tab->len; + tab->len = 0; + } + } + + if (right_ids.len) + { + right_ids.base = (Sym *) xmalloc (right_ids.len * sizeof (Sym)); + right_ids.limit = right_ids.base + right_ids.len; + right_ids.len = 0; + } + + /* Make a second pass through symtab, creating syms as necessary. */ + for (sym = symtab.base; sym < symtab.limit; ++sym) + { + for (id = id_list; id; id = id->next) + { + if (match (&id->left.sym, sym)) + extend_match (&id->left, sym, &syms[id->which_table], TRUE); + + if (id->has_right && match (&id->right.sym, sym)) + extend_match (&id->right, sym, &right_ids, TRUE); + } + } + + /* Go through ids creating arcs as needed. */ + for (id = id_list; id; id = id->next) + { + if (id->has_right) + { + for (left = id->left.first_match; left; left = left->next) + { + for (right = id->right.first_match; right; right = right->next) + { + DBG (IDDEBUG, + printf ( + "[sym_id_parse]: arc %s:%s(%lx-%lx) -> %s:%s(%lx-%lx) to %s\n", + left->file ? left->file->name : "*", + left->name ? left->name : "*", + (unsigned long) left->addr, + (unsigned long) left->end_addr, + right->file ? right->file->name : "*", + right->name ? right->name : "*", + (unsigned long) right->addr, + (unsigned long) right->end_addr, + table_name[id->which_table])); + + arc_add (left, right, (unsigned long) 0); + } + } + } + } + + /* Finally, we can sort the tables and we're done. */ + for (tab = &syms[0]; tab < &syms[NUM_TABLES]; ++tab) + { + DBG (IDDEBUG, printf ("[sym_id_parse] syms[%s]:\n", + table_name[tab - &syms[0]])); + symtab_finalize (tab); + } +} + + +/* Symbol tables storing the FROM symbols of arcs do not necessarily + have distinct address ranges. For example, somebody might request + -k /_mcount to suppress any arcs into _mcount, while at the same + time requesting -k a/b. Fortunately, those symbol tables don't get + very big (the user has to type them!), so a linear search is probably + tolerable. */ +bfd_boolean +sym_id_arc_is_present (sym_tab, from, to) + Sym_Table *sym_tab; + Sym *from; + Sym *to; +{ + Sym *sym; + + for (sym = sym_tab->base; sym < sym_tab->limit; ++sym) + { + if (from->addr >= sym->addr && from->addr <= sym->end_addr + && arc_lookup (sym, to)) + return TRUE; + } + + return FALSE; +} diff --git a/gprof/sym_ids.h b/gprof/sym_ids.h new file mode 100644 index 000000000000..634ac969de92 --- /dev/null +++ b/gprof/sym_ids.h @@ -0,0 +1,42 @@ +/* sym_ids.h + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef sym_ids_h +#define sym_ids_h + +typedef enum + { + INCL_GRAPH = 0, EXCL_GRAPH, + INCL_ARCS, EXCL_ARCS, + INCL_FLAT, EXCL_FLAT, + INCL_TIME, EXCL_TIME, + INCL_ANNO, EXCL_ANNO, + INCL_EXEC, EXCL_EXEC, + NUM_TABLES + } +Table_Id; + +extern Sym_Table syms[NUM_TABLES]; + +extern void sym_id_add PARAMS ((const char *, Table_Id)); +extern void sym_id_parse PARAMS ((void)); +extern bfd_boolean sym_id_arc_is_present PARAMS ((Sym_Table *, Sym *, Sym *)); + +#endif /* sym_ids_h */ diff --git a/gprof/symtab.c b/gprof/symtab.c new file mode 100644 index 000000000000..c4ce7ed21598 --- /dev/null +++ b/gprof/symtab.c @@ -0,0 +1,280 @@ +/* symtab.c + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" + +static int cmp_addr PARAMS ((const PTR, const PTR)); + +Sym_Table symtab; + + +/* Initialize a symbol (so it's empty). */ + +void +sym_init (sym) + Sym *sym; +{ + memset (sym, 0, sizeof (*sym)); + + /* It is not safe to assume that a binary zero corresponds + to a floating-point 0.0, so initialize floats explicitly. */ + sym->hist.time = 0.0; + sym->cg.child_time = 0.0; + sym->cg.prop.fract = 0.0; + sym->cg.prop.self = 0.0; + sym->cg.prop.child = 0.0; +} + + +/* Compare the function entry-point of two symbols and return <0, =0, + or >0 depending on whether the left value is smaller than, equal + to, or greater than the right value. If two symbols are equal + but one has is_func set and the other doesn't, we make the + non-function symbol one "bigger" so that the function symbol will + survive duplicate removal. Finally, if both symbols have the + same is_func value, we discriminate against is_static such that + the global symbol survives. */ + +static int +cmp_addr (lp, rp) + const PTR lp; + const PTR rp; +{ + const Sym *left = (const Sym *) lp; + const Sym *right = (const Sym *) rp; + + if (left->addr > right->addr) + return 1; + else if (left->addr < right->addr) + return -1; + + if (left->is_func != right->is_func) + return right->is_func - left->is_func; + + return left->is_static - right->is_static; +} + + +void +symtab_finalize (tab) + Sym_Table *tab; +{ + Sym *src, *dst; + bfd_vma prev_addr; + + if (!tab->len) + return; + + /* Sort symbol table in order of increasing function addresses. */ + qsort (tab->base, tab->len, sizeof (Sym), cmp_addr); + + /* Remove duplicate entries to speed-up later processing and + set end_addr if its not set yet. */ + prev_addr = tab->base[0].addr + 1; + + for (src = dst = tab->base; src < tab->limit; ++src) + { + if (src->addr == prev_addr) + { + /* If same address, favor global symbol over static one, + then function over line number. If both symbols are + either static or global and either function or line, check + whether one has name beginning with underscore while + the other doesn't. In such cases, keep sym without + underscore. This takes cares of compiler generated + symbols (such as __gnu_compiled, __c89_used, etc.). */ + if ((!src->is_static && dst[-1].is_static) + || ((src->is_static == dst[-1].is_static) + && ((src->is_func && !dst[-1].is_func) + || ((src->is_func == dst[-1].is_func) + && ((src->name[0] != '_' && dst[-1].name[0] == '_') + || (src->name[0] + && src->name[1] != '_' + && dst[-1].name[1] == '_')))))) + { + DBG (AOUTDEBUG | IDDEBUG, + printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c", + src->name, src->is_static ? 't' : 'T', + src->is_func ? 'F' : 'f', + dst[-1].name, dst[-1].is_static ? 't' : 'T', + dst[-1].is_func ? 'F' : 'f'); + printf (" (addr=%lx)\n", (unsigned long) src->addr)); + + dst[-1] = *src; + } + else + { + DBG (AOUTDEBUG | IDDEBUG, + printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c", + dst[-1].name, dst[-1].is_static ? 't' : 'T', + dst[-1].is_func ? 'F' : 'f', + src->name, src->is_static ? 't' : 'T', + src->is_func ? 'F' : 'f'); + printf (" (addr=%lx)\n", (unsigned long) src->addr)); + } + } + else + { + if (dst > tab->base && dst[-1].end_addr == 0) + dst[-1].end_addr = src->addr - 1; + + /* Retain sym only if it has a non-empty address range. */ + if (!src->end_addr || src->addr <= src->end_addr) + { + *dst = *src; + dst++; + prev_addr = src->addr; + } + } + } + + if (tab->len > 0 && dst[-1].end_addr == 0) + dst[-1].end_addr = core_text_sect->vma + core_text_sect->_raw_size - 1; + + DBG (AOUTDEBUG | IDDEBUG, + printf ("[symtab_finalize]: removed %d duplicate entries\n", + tab->len - (int) (dst - tab->base))); + + tab->limit = dst; + tab->len = tab->limit - tab->base; + + DBG (AOUTDEBUG | IDDEBUG, + unsigned int j; + + for (j = 0; j < tab->len; ++j) + { + printf ("[symtab_finalize] 0x%lx-0x%lx\t%s\n", + (long) tab->base[j].addr, (long) tab->base[j].end_addr, + tab->base[j].name); + } + ); +} + + +#ifdef DEBUG + +Sym * +dbg_sym_lookup (sym_tab, address) + Sym_Table *sym_tab; + bfd_vma address; +{ + long low, mid, high; + Sym *sym; + + fprintf (stderr, "[dbg_sym_lookup] address 0x%lx\n", + (unsigned long) address); + + sym = sym_tab->base; + for (low = 0, high = sym_tab->len - 1; low != high;) + { + mid = (high + low) >> 1; + + fprintf (stderr, "[dbg_sym_lookup] low=0x%lx, mid=0x%lx, high=0x%lx\n", + low, mid, high); + fprintf (stderr, "[dbg_sym_lookup] sym[m]=0x%lx sym[m + 1]=0x%lx\n", + (unsigned long) sym[mid].addr, + (unsigned long) sym[mid + 1].addr); + + if (sym[mid].addr <= address && sym[mid + 1].addr > address) + return &sym[mid]; + + if (sym[mid].addr > address) + high = mid; + else + low = mid + 1; + } + + fprintf (stderr, "[dbg_sym_lookup] binary search fails???\n"); + + return 0; +} + +#endif /* DEBUG */ + + +/* Look up an address in the symbol-table that is sorted by address. + If address does not hit any symbol, 0 is returned. */ +Sym * +sym_lookup (sym_tab, address) + Sym_Table *sym_tab; + bfd_vma address; +{ + long low, high; + long mid = -1; + Sym *sym; +#ifdef DEBUG + int probes = 0; +#endif /* DEBUG */ + + if (!sym_tab->len) + return 0; + + sym = sym_tab->base; + for (low = 0, high = sym_tab->len - 1; low != high;) + { + DBG (LOOKUPDEBUG, ++probes); + mid = (high + low) / 2; + + if (sym[mid].addr <= address && sym[mid + 1].addr > address) + { + if (address > sym[mid].end_addr) + { + /* Address falls into gap between + sym[mid] and sym[mid + 1]. */ + return 0; + } + else + { + DBG (LOOKUPDEBUG, + printf ("[sym_lookup] %d probes (symtab->len=%u)\n", + probes, sym_tab->len - 1)); + return &sym[mid]; + } + } + + if (sym[mid].addr > address) + high = mid; + else + low = mid + 1; + } + + if (sym[mid + 1].addr <= address) + { + if (address > sym[mid + 1].end_addr) + { + /* Address is beyond end of sym[mid + 1]. */ + return 0; + } + else + { + DBG (LOOKUPDEBUG, printf ("[sym_lookup] %d (%u) probes, fall off\n", + probes, sym_tab->len - 1)); + return &sym[mid + 1]; + } + } + + return 0; +} diff --git a/gprof/symtab.h b/gprof/symtab.h new file mode 100644 index 000000000000..4ff507d1876d --- /dev/null +++ b/gprof/symtab.h @@ -0,0 +1,122 @@ +/* symtab.h + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef symtab_h +#define symtab_h + +/* For a profile to be intelligible to a human user, it is necessary + to map code-addresses into source-code information. Source-code + information can be any combination of: (i) function-name, (ii) + source file-name, and (iii) source line number. + + The symbol table is used to map addresses into source-code + information. */ + +#define NBBS 10 + +/* Symbol-entry. For each external in the specified file we gather + its address, the number of calls and compute its share of cpu time. */ +typedef struct sym + { + /* Common information: + + In the symbol-table, fields ADDR and FUNC_NAME are guaranteed + to contain valid information. FILE may be 0, if unknown and + LINE_NUM maybe 0 if unknown. */ + + bfd_vma addr; /* Address of entry point. */ + bfd_vma end_addr; /* End-address. */ + const char *name; /* Name of function this sym is from. */ + Source_File *file; /* Source file symbol comes from. */ + int line_num; /* Source line number. */ + unsigned int /* Boolean fields: */ + is_func:1, /* Is this a function entry point? */ + is_static:1, /* Is this a local (static) symbol? */ + is_bb_head:1, /* Is this the head of a basic-blk? */ + mapped:1, /* This symbol was mapped to another name. */ + has_been_placed:1; /* Have we placed this symbol? */ + unsigned long ncalls; /* How many times executed */ + int nuses; /* How many times this symbol appears in + a particular context. */ + bfd_vma bb_addr[NBBS]; /* Address of basic-block start. */ + unsigned long bb_calls[NBBS];/* How many times basic-block was called. */ + struct sym *next; /* For building chains of syms. */ + struct sym *prev; /* For building chains of syms. */ + + /* Profile specific information: */ + + /* Histogram specific information: */ + struct + { + double time; /* (Weighted) ticks in this routine. */ + bfd_vma scaled_addr; /* Scaled entry point. */ + } + hist; + + /* Call-graph specific information: */ + struct + { + unsigned long self_calls; /* How many calls to self. */ + double child_time; /* Cumulative ticks in children. */ + int index; /* Index in the graph list. */ + int top_order; /* Graph call chain top-sort order. */ + bfd_boolean print_flag; /* Should this be printed? */ + struct + { + double fract; /* What % of time propagates. */ + double self; /* How much self time propagates. */ + double child; /* How much child time propagates. */ + } + prop; + struct + { + int num; /* Internal number of cycle on. */ + struct sym *head; /* Head of cycle. */ + struct sym *next; /* Next member of cycle. */ + } + cyc; + struct arc *parents; /* List of caller arcs. */ + struct arc *children; /* List of callee arcs. */ + } + cg; + } +Sym; + +/* Symbol-tables are always assumed to be sorted + in increasing order of addresses. */ +typedef struct + { + unsigned int len; /* # of symbols in this table. */ + Sym *base; /* First element in symbol table. */ + Sym *limit; /* Limit = base + len. */ + } +Sym_Table; + +extern Sym_Table symtab; /* The symbol table. */ + +extern void sym_init PARAMS ((Sym *)); +extern void symtab_finalize PARAMS ((Sym_Table *)); +#ifdef DEBUG +extern Sym *dbg_sym_lookup PARAMS ((Sym_Table *, bfd_vma)); +#endif +extern Sym *sym_lookup PARAMS ((Sym_Table *, bfd_vma)); +extern void find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +#endif /* symtab_h */ diff --git a/gprof/tahoe.c b/gprof/tahoe.c new file mode 100644 index 000000000000..1e7da7df0ace --- /dev/null +++ b/gprof/tahoe.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 1983, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" + + /* + * opcode of the `callf' instruction + */ +#define CALLF 0xfe + + /* + * register for pc relative addressing + */ +#define PC 0xf + +enum tahoe_opermodes + { + literal, indexed, reg, regdef, autodec, autoinc, autoincdef, + bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef, + immediate, absolute, byterel, bytereldef, wordrel, wordreldef, + longrel, longreldef + }; +typedef enum tahoe_opermodes tahoe_operandenum; + +/* + * A symbol to be the child of indirect callf: + */ +static Sym indirectchild; + +static tahoe_operandenum tahoe_operandmode PARAMS ((unsigned char *)); +static char *tahoe_operandname PARAMS ((tahoe_operandenum)); +static long tahoe_operandlength PARAMS ((unsigned char *)); +static bfd_signed_vma tahoe_offset PARAMS ((unsigned char *)); +void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +static tahoe_operandenum +tahoe_operandmode (modep) + unsigned char *modep; +{ + long usesreg = *modep & 0xf; + + switch ((*modep >> 4) & 0xf) + { + case 0: + case 1: + case 2: + case 3: + return literal; + case 4: + return indexed; + case 5: + return reg; + case 6: + return regdef; + case 7: + return autodec; + case 8: + return usesreg != 0xe ? autoinc : immediate; + case 9: + return usesreg != PC ? autoincdef : absolute; + case 10: + return usesreg != PC ? bytedisp : byterel; + case 11: + return usesreg != PC ? bytedispdef : bytereldef; + case 12: + return usesreg != PC ? worddisp : wordrel; + case 13: + return usesreg != PC ? worddispdef : wordreldef; + case 14: + return usesreg != PC ? longdisp : longrel; + case 15: + return usesreg != PC ? longdispdef : longreldef; + } + /* NOTREACHED */ + abort (); +} + +static char * +tahoe_operandname (mode) + tahoe_operandenum mode; +{ + + switch (mode) + { + case literal: + return "literal"; + case indexed: + return "indexed"; + case reg: + return "register"; + case regdef: + return "register deferred"; + case autodec: + return "autodecrement"; + case autoinc: + return "autoincrement"; + case autoincdef: + return "autoincrement deferred"; + case bytedisp: + return "byte displacement"; + case bytedispdef: + return "byte displacement deferred"; + case byterel: + return "byte relative"; + case bytereldef: + return "byte relative deferred"; + case worddisp: + return "word displacement"; + case worddispdef: + return "word displacement deferred"; + case wordrel: + return "word relative"; + case wordreldef: + return "word relative deferred"; + case immediate: + return "immediate"; + case absolute: + return "absolute"; + case longdisp: + return "long displacement"; + case longdispdef: + return "long displacement deferred"; + case longrel: + return "long relative"; + case longreldef: + return "long relative deferred"; + } + /* NOTREACHED */ + abort (); +} + +static long +tahoe_operandlength (modep) + unsigned char *modep; +{ + + switch (tahoe_operandmode (modep)) + { + case literal: + case reg: + case regdef: + case autodec: + case autoinc: + case autoincdef: + return 1; + case bytedisp: + case bytedispdef: + case byterel: + case bytereldef: + return 2; + case worddisp: + case worddispdef: + case wordrel: + case wordreldef: + return 3; + case immediate: + case absolute: + case longdisp: + case longdispdef: + case longrel: + case longreldef: + return 5; + case indexed: + return 1 + tahoe_operandlength (modep + 1); + } + /* NOTREACHED */ + abort (); +} + +static bfd_signed_vma +tahoe_offset (modep) + unsigned char *modep; +{ + tahoe_operandenum mode = tahoe_operandmode (modep); + + ++modep; /* skip over the mode */ + switch (mode) + { + default: + fprintf (stderr, "[reladdr] not relative address\n"); + return 0; + case byterel: + return 1 + bfd_get_signed_8 (core_bfd, modep); + case wordrel: + return 2 + bfd_get_signed_16 (core_bfd, modep); + case longrel: + return 4 + bfd_get_signed_32 (core_bfd, modep); + } +} + +void +tahoe_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + unsigned char *instructp; + long length; + Sym *child; + tahoe_operandenum mode; + tahoe_operandenum firstmode; + bfd_vma pc, destpc; + static bfd_boolean inited = FALSE; + + if (!inited) + { + inited = TRUE; + sym_init (&indirectchild); + indirectchild.cg.prop.fract = 1.0; + indirectchild.cg.cyc.head = &indirectchild; + } + + if (core_text_space == 0) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", + parent->name, (unsigned long) p_lowpc, + (unsigned long) p_highpc)); + for (pc = p_lowpc; pc < p_highpc; pc += length) + { + length = 1; + instructp = ((unsigned char *) core_text_space + + pc - core_text_sect->vma); + if ((*instructp & 0xff) == CALLF) + { + /* + * maybe a callf, better check it out. + * skip the count of the number of arguments. + */ + DBG (CALLDEBUG, printf ("[findcall]\t0x%lx:callf", + (unsigned long) pc)); + firstmode = tahoe_operandmode (instructp + length); + switch (firstmode) + { + case literal: + case immediate: + break; + default: + goto botched; + } + length += tahoe_operandlength (instructp + length); + mode = tahoe_operandmode (instructp + length); + DBG (CALLDEBUG, + printf ("\tfirst operand is %s", tahoe_operandname (firstmode)); + printf ("\tsecond operand is %s\n", tahoe_operandname (mode)); + ); + switch (mode) + { + case regdef: + case bytedispdef: + case worddispdef: + case longdispdef: + case bytereldef: + case wordreldef: + case longreldef: + /* + * indirect call: call through pointer + * either *d(r) as a parameter or local + * (r) as a return value + * *f as a global pointer + * [are there others that we miss?, + * e.g. arrays of pointers to functions???] + */ + arc_add (parent, &indirectchild, (unsigned long) 0); + length += tahoe_operandlength (instructp + length); + continue; + case byterel: + case wordrel: + case longrel: + /* + * regular pc relative addressing + * check that this is the address of + * a function. + */ + destpc = pc + tahoe_offset (instructp + length); + if (destpc >= s_lowpc && destpc <= s_highpc) + { + child = sym_lookup (&symtab, destpc); + DBG (CALLDEBUG, + printf ("[findcall]\tdestpc 0x%lx", + (unsigned long) destpc); + printf (" child->name %s", child->name); + printf (" child->addr 0x%lx\n", + (unsigned long) child->addr); + ); + if (child->addr == destpc) + { + /* + * a hit + */ + arc_add (parent, child, (unsigned long) 0); + length += tahoe_operandlength (instructp + length); + continue; + } + goto botched; + } + /* + * else: + * it looked like a callf, + * but it wasn't to anywhere. + */ + goto botched; + default: + botched: + /* + * something funny going on. + */ + DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n")); + length = 1; + continue; + } + } + } +} diff --git a/gprof/utils.c b/gprof/utils.c new file mode 100644 index 000000000000..0f54a61fd11b --- /dev/null +++ b/gprof/utils.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1983, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "demangle.h" +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "utils.h" + + +/* + * Print name of symbol. Return number of characters printed. + */ +int +print_name_only (self) + Sym *self; +{ + const char *name = self->name; + const char *filename; + char *demangled = 0; + char buf[PATH_MAX]; + int size = 0; + + if (name) + { + if (!bsd_style_output) + { + if (name[0] == '_' && name[1] && discard_underscores) + { + name++; + } + if (demangle) + { + demangled = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); + if (demangled) + { + name = demangled; + } + } + } + printf ("%s", name); + size = strlen (name); + if (line_granularity && self->file) + { + filename = self->file->name; + if (!print_path) + { + filename = strrchr (filename, '/'); + if (filename) + { + ++filename; + } + else + { + filename = self->file->name; + } + } + sprintf (buf, " (%s:%d @ %lx)", filename, self->line_num, + (unsigned long) self->addr); + printf ("%s", buf); + size += strlen (buf); + } + if (demangled) + { + free (demangled); + } + DBG (DFNDEBUG, printf ("{%d} ", self->cg.top_order)); + DBG (PROPDEBUG, printf ("%4.0f%% ", 100.0 * self->cg.prop.fract)); + } + return size; +} + + +void +print_name (self) + Sym *self; +{ + print_name_only (self); + + if (self->cg.cyc.num != 0) + { + printf (_(" <cycle %d>"), self->cg.cyc.num); + } + if (self->cg.index != 0) + { + if (self->cg.print_flag) + { + printf (" [%d]", self->cg.index); + } + else + { + printf (" (%d)", self->cg.index); + } + } +} diff --git a/gprof/utils.h b/gprof/utils.h new file mode 100644 index 000000000000..27fb9c673496 --- /dev/null +++ b/gprof/utils.h @@ -0,0 +1,7 @@ +#ifndef utils_h +#define utils_h + +extern int print_name_only PARAMS ((Sym * self)); +extern void print_name PARAMS ((Sym * self)); + +#endif /* utils_h */ diff --git a/gprof/vax.c b/gprof/vax.c new file mode 100644 index 000000000000..56f5f4f0ceb3 --- /dev/null +++ b/gprof/vax.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 1983, 1993, 2001 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "gprof.h" +#include "search_list.h" +#include "source.h" +#include "symtab.h" +#include "cg_arcs.h" +#include "corefile.h" +#include "hist.h" + + /* + * opcode of the `calls' instruction + */ +#define CALLS 0xfb + + /* + * register for pc relative addressing + */ +#define PC 0xf + +enum opermodes + { + literal, indexed, reg, regdef, autodec, autoinc, autoincdef, + bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef, + immediate, absolute, byterel, bytereldef, wordrel, wordreldef, + longrel, longreldef + }; +typedef enum opermodes operandenum; + +#if 0 +/* Here to document only. We can't use this when cross compiling as + the bitfield layout might not be the same as native. */ +struct modebyte + { + unsigned int regfield:4; + unsigned int modefield:4; + }; +#endif + +/* + * A symbol to be the child of indirect calls: + */ +static Sym indirectchild; + +static operandenum vax_operandmode PARAMS ((unsigned char *)); +static char *vax_operandname PARAMS ((operandenum)); +static long vax_operandlength PARAMS ((unsigned char *)); +static bfd_signed_vma vax_offset PARAMS ((unsigned char *)); +void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma)); + +static operandenum +vax_operandmode (modep) + unsigned char *modep; +{ + int usesreg = *modep & 0xf; + + switch ((*modep >> 4) & 0xf) + { + case 0: + case 1: + case 2: + case 3: + return literal; + case 4: + return indexed; + case 5: + return reg; + case 6: + return regdef; + case 7: + return autodec; + case 8: + return usesreg != PC ? autoinc : immediate; + case 9: + return usesreg != PC ? autoincdef : absolute; + case 10: + return usesreg != PC ? bytedisp : byterel; + case 11: + return usesreg != PC ? bytedispdef : bytereldef; + case 12: + return usesreg != PC ? worddisp : wordrel; + case 13: + return usesreg != PC ? worddispdef : wordreldef; + case 14: + return usesreg != PC ? longdisp : longrel; + case 15: + return usesreg != PC ? longdispdef : longreldef; + } + /* NOTREACHED */ + abort (); +} + +static char * +vax_operandname (mode) + operandenum mode; +{ + + switch (mode) + { + case literal: + return "literal"; + case indexed: + return "indexed"; + case reg: + return "register"; + case regdef: + return "register deferred"; + case autodec: + return "autodecrement"; + case autoinc: + return "autoincrement"; + case autoincdef: + return "autoincrement deferred"; + case bytedisp: + return "byte displacement"; + case bytedispdef: + return "byte displacement deferred"; + case byterel: + return "byte relative"; + case bytereldef: + return "byte relative deferred"; + case worddisp: + return "word displacement"; + case worddispdef: + return "word displacement deferred"; + case wordrel: + return "word relative"; + case wordreldef: + return "word relative deferred"; + case immediate: + return "immediate"; + case absolute: + return "absolute"; + case longdisp: + return "long displacement"; + case longdispdef: + return "long displacement deferred"; + case longrel: + return "long relative"; + case longreldef: + return "long relative deferred"; + } + /* NOTREACHED */ + abort (); +} + +static long +vax_operandlength (modep) + unsigned char *modep; +{ + + switch (vax_operandmode (modep)) + { + case literal: + case reg: + case regdef: + case autodec: + case autoinc: + case autoincdef: + return 1; + case bytedisp: + case bytedispdef: + case byterel: + case bytereldef: + return 2; + case worddisp: + case worddispdef: + case wordrel: + case wordreldef: + return 3; + case immediate: + case absolute: + case longdisp: + case longdispdef: + case longrel: + case longreldef: + return 5; + case indexed: + return 1 + vax_operandlength (modep + 1); + } + /* NOTREACHED */ + abort (); +} + +static bfd_signed_vma +vax_offset (modep) + unsigned char *modep; +{ + operandenum mode = vax_operandmode (modep); + + ++modep; /* skip over the mode */ + switch (mode) + { + default: + fprintf (stderr, "[reladdr] not relative address\n"); + return 0; + case byterel: + return 1 + bfd_get_signed_8 (core_bfd, modep); + case wordrel: + return 2 + bfd_get_signed_16 (core_bfd, modep); + case longrel: + return 4 + bfd_get_signed_32 (core_bfd, modep); + } +} + + +void +vax_find_call (parent, p_lowpc, p_highpc) + Sym *parent; + bfd_vma p_lowpc; + bfd_vma p_highpc; +{ + unsigned char *instructp; + long length; + Sym *child; + operandenum mode; + operandenum firstmode; + bfd_vma pc, destpc; + static bfd_boolean inited = FALSE; + + if (!inited) + { + inited = TRUE; + sym_init (&indirectchild); + indirectchild.cg.prop.fract = 1.0; + indirectchild.cg.cyc.head = &indirectchild; + } + + if (core_text_space == 0) + { + return; + } + if (p_lowpc < s_lowpc) + { + p_lowpc = s_lowpc; + } + if (p_highpc > s_highpc) + { + p_highpc = s_highpc; + } + DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n", + parent->name, (unsigned long) p_lowpc, + (unsigned long) p_highpc)); + for (pc = p_lowpc; pc < p_highpc; pc += length) + { + length = 1; + instructp = ((unsigned char *) core_text_space + + pc - core_text_sect->vma); + if ((*instructp & 0xff) == CALLS) + { + /* + * maybe a calls, better check it out. + * skip the count of the number of arguments. + */ + DBG (CALLDEBUG, + printf ("[findcall]\t0x%lx:calls", (unsigned long) pc)); + firstmode = vax_operandmode (instructp + length); + switch (firstmode) + { + case literal: + case immediate: + break; + default: + goto botched; + } + length += vax_operandlength (instructp + length); + mode = vax_operandmode (instructp + length); + DBG (CALLDEBUG, + printf ("\tfirst operand is %s", vax_operandname (firstmode)); + printf ("\tsecond operand is %s\n", vax_operandname (mode))); + switch (mode) + { + case regdef: + case bytedispdef: + case worddispdef: + case longdispdef: + case bytereldef: + case wordreldef: + case longreldef: + /* + * indirect call: call through pointer + * either *d(r) as a parameter or local + * (r) as a return value + * *f as a global pointer + * [are there others that we miss?, + * e.g. arrays of pointers to functions???] + */ + arc_add (parent, &indirectchild, (unsigned long) 0); + length += vax_operandlength (instructp + length); + continue; + case byterel: + case wordrel: + case longrel: + /* + * regular pc relative addressing + * check that this is the address of + * a function. + */ + destpc = pc + vax_offset (instructp + length); + if (destpc >= s_lowpc && destpc <= s_highpc) + { + child = sym_lookup (&symtab, destpc); + DBG (CALLDEBUG, + printf ("[findcall]\tdestpc 0x%lx", + (unsigned long) destpc); + printf (" child->name %s", child->name); + printf (" child->addr 0x%lx\n", + (unsigned long) child->addr); + ); + if (child->addr == destpc) + { + /* + * a hit + */ + arc_add (parent, child, (unsigned long) 0); + length += vax_operandlength (instructp + length); + continue; + } + goto botched; + } + /* + * else: + * it looked like a calls, + * but it wasn't to anywhere. + */ + goto botched; + default: + botched: + /* + * something funny going on. + */ + DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n")); + length = 1; + continue; + } + } + } +} |