Index: TODO =================================================================== RCS file: /cvs/src/src/gprof/TODO,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 TODO *** TODO 1999/05/03 07:29:11 1.1.1.1 --- TODO 2002/01/26 23:14:30 *************** *** 1,7 **** - - gmon_io.c cannot deal with target architecture that have a pointer size - that is different from the host architectures pointer size---fix this - (gmon_out.h, and gmon_io.c) - 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) --- 1,4 ---- Index: acconfig.h =================================================================== RCS file: acconfig.h diff -N acconfig.h *** /sourceware/cvs-tmp/cvsKUqZpU Sat Jan 26 15:14:40 2002 --- /dev/null Tue May 5 13:32:27 1998 *************** *** 1,2 **** - /* Define as the size of a pointer in the target profile file format. */ - #undef GMON_PTR_SIZE --- 0 ---- Index: configure.in =================================================================== RCS file: /cvs/src/src/gprof/configure.in,v retrieving revision 1.13 diff -c -r1.13 configure.in *** configure.in 2002/01/07 17:37:54 1.13 --- configure.in 2002/01/26 23:14:39 *************** *** 31,61 **** AC_CHECK_HEADERS(sys/gmon_out.h) - AC_MSG_CHECKING(the size of gmon pointers) - AC_TRY_RUN([#include - #include - #if HAVE_SYS_GMON_OUT_H - #include - #endif - main() - { - #if HAVE_SYS_GMON_OUT_H - struct gmon_cg_arc_record arc; - FILE *f=fopen("conftestval", "w"); - if (!f) exit(1); - fprintf(f, "%d\n", sizeof(arc.from_pc)); - exit(0); - #else - FILE *f=fopen("conftestval", "w"); - if (!f) exit(1); - fprintf(f, "%d\n", (int) sizeof(char *)); - exit(1); - #endif - }], gmon_ptr_size=`cat conftestval`, gmon_ptr_size=4, gmon_ptr_size=4) - AC_MSG_RESULT($gmon_ptr_size) - - AC_DEFINE_UNQUOTED(GMON_PTR_SIZE, $gmon_ptr_size) - build_warnings="-W -Wall" AC_ARG_ENABLE(build-warnings, [ --enable-build-warnings Enable build-time compiler warnings if gcc is used], --- 31,36 ---- Index: gmon.h =================================================================== RCS file: /cvs/src/src/gprof/gmon.h,v retrieving revision 1.2 diff -c -r1.2 gmon.h *** gmon.h 2001/03/14 03:14:56 1.2 --- gmon.h 2002/01/26 23:14:40 *************** *** 35,71 **** #ifndef gmon_h #define gmon_h ! struct raw_phdr ! { ! /* FIXME: Checking a host compiler define means that we can't use ! a cross gprof to the alpha. */ ! char low_pc[GMON_PTR_SIZE]; /* base pc address of sample buffer */ ! char high_pc[GMON_PTR_SIZE];/* 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 */ ! }; #define GMONVERSION 0x00051879 ! struct old_raw_phdr ! { ! char low_pc[GMON_PTR_SIZE]; /* base pc address of sample buffer */ ! char high_pc[GMON_PTR_SIZE];/* max pc address of sampled buffer */ ! char ncnt[4]; /* size of sample buffer (plus this header) */ ! /* FIXME: Checking host compiler defines here means that we can't ! use a cross gprof alpha OSF. */ #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 ! }; /* * Histogram counters are unsigned shorts: --- 35,87 ---- #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: *************** *** 120,131 **** * as to get a packed representation (otherwise, different compilers * might introduce different padding): */ ! struct raw_arc ! { ! char from_pc[GMON_PTR_SIZE]; ! char self_pc[GMON_PTR_SIZE]; ! char count[4]; ! }; /* * General rounding functions: --- 136,149 ---- * 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: Index: gmon_io.c =================================================================== RCS file: /cvs/src/src/gprof/gmon_io.c,v retrieving revision 1.10 diff -c -r1.10 gmon_io.c *** gmon_io.c 2002/01/03 21:32:36 1.10 --- gmon_io.c 2002/01/26 23:14:40 *************** *** 1,6 **** /* gmon_io.c - Input and output from/to gmon.out files. ! Copyright 2000, 2001 Free Software Foundation, Inc. This file is part of GNU Binutils. --- 1,6 ---- /* 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. *************** *** 36,84 **** int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */ int ! DEFUN (gmon_io_read_vma, (ifp, valp), FILE * ifp AND bfd_vma *valp) { char buf[8]; ! bfd_vma val; ! switch (GMON_PTR_SIZE) { ! case 4: ! if (fread (buf, 1, 4, ifp) != 4) return 1; ! val = bfd_get_32 (core_bfd, buf); break; ! case 8: ! if (fread (buf, 1, 8, ifp) != 8) return 1; ! val = bfd_get_64 (core_bfd, buf); break; default: ! fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"), ! whoami, GMON_PTR_SIZE); done (1); } - *valp = val; return 0; } int ! DEFUN (gmon_io_read_32, (ifp, valp), FILE * ifp AND unsigned int *valp) { char buf[4]; ! if (fread (buf, 1, 4, ifp) != 4) return 1; - *valp = bfd_get_32 (core_bfd, buf); return 0; } int ! DEFUN (gmon_io_read, (ifp, buf, n), FILE * ifp AND char *buf AND size_t n) { ! if (fread (buf, 1, n, ifp) != n) return 1; return 0; } --- 36,116 ---- int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */ int ! DEFUN (gmon_io_read_32, (ifp, valp), FILE * ifp AND unsigned int *valp) { + char buf[4]; + + if (fread (buf, 1, 4, ifp) != 4) + return 1; + *valp = bfd_get_32 (core_bfd, buf); + return 0; + } + + int + DEFUN (gmon_io_read_64, (ifp, valp), FILE * ifp AND 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; ! } ! ! int ! DEFUN (gmon_io_read_vma, (ifp, valp), FILE * ifp AND bfd_vma *valp) ! { ! unsigned int val32; ! BFD_HOST_U_64_BIT val64; ! switch (bfd_arch_bits_per_address (core_bfd)) { ! case 32: ! if (gmon_io_read_32 (ifp, &val32)) return 1; ! *valp = val32; break; ! case 64: ! if (gmon_io_read_64 (ifp, &val64)) return 1; ! *valp = val64; break; default: ! fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); done (1); } return 0; } int ! DEFUN (gmon_io_read, (ifp, buf, n), FILE * ifp AND char *buf AND size_t n) ! { ! if (fread (buf, 1, n, ifp) != n) ! return 1; ! return 0; ! } ! ! int ! DEFUN (gmon_io_write_32, (ofp, val), FILE * ofp AND unsigned int val) { char buf[4]; ! bfd_put_32 (core_bfd, val, buf); ! if (fwrite (buf, 1, 4, ofp) != 4) return 1; return 0; } int ! DEFUN (gmon_io_write_64, (ofp, val), FILE * ofp AND BFD_HOST_U_64_BIT val) { ! char buf[8]; ! ! bfd_put_64 (core_bfd, val, buf); ! if (fwrite (buf, 1, 8, ofp) != 8) return 1; return 0; } *************** *** 86,127 **** int DEFUN (gmon_io_write_vma, (ofp, val), FILE * ofp AND bfd_vma val) { - char buf[8]; ! switch (GMON_PTR_SIZE) { ! case 4: ! bfd_put_32 (core_bfd, val, buf); ! if (fwrite (buf, 1, 4, ofp) != 4) return 1; break; ! case 8: ! bfd_put_64 (core_bfd, val, buf); ! if (fwrite (buf, 1, 8, ofp) != 8) return 1; break; default: ! fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"), ! whoami, GMON_PTR_SIZE); done (1); } return 0; } int - DEFUN (gmon_io_write_32, (ofp, val), FILE * ofp AND unsigned int val) - { - char buf[4]; - - bfd_put_32 (core_bfd, val, buf); - if (fwrite (buf, 1, 4, ofp) != 4) - return 1; - return 0; - } - - int DEFUN (gmon_io_write_8, (ofp, val), FILE * ofp AND unsigned char val) { char buf[1]; --- 118,145 ---- int DEFUN (gmon_io_write_vma, (ofp, val), FILE * ofp AND bfd_vma val) { ! switch (bfd_arch_bits_per_address (core_bfd)) { ! case 32: ! if (gmon_io_write_32 (ofp, (unsigned int) val)) return 1; break; ! case 64: ! if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val)) return 1; break; default: ! fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); done (1); } return 0; } int DEFUN (gmon_io_write_8, (ofp, val), FILE * ofp AND unsigned char val) { char buf[1]; *************** *** 139,178 **** return 1; return 0; } ! /* get_vma and put_vma are for backwards compatibility only */ ! static bfd_vma ! DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr) ! { ! switch (sizeof (char*)) ! { ! case 4: ! return bfd_get_32 (abfd, addr); ! case 8: ! return bfd_get_64 (abfd, addr); default: ! fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"), ! whoami, (long) sizeof (char*)); done (1); } } ! static void ! DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr) { ! switch (sizeof (char*)) { ! case 4: ! bfd_put_32 (abfd, val, addr); break; ! case 8: ! bfd_put_64 (abfd, val, addr); break; default: ! fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"), ! whoami, (long) sizeof (char*)); done (1); } } void --- 157,221 ---- return 1; return 0; } + + int + DEFUN (gmon_read_raw_arc, (ifp, fpc, spc, cnt), FILE * ifp AND bfd_vma * fpc AND bfd_vma * spc AND unsigned long * cnt) + { + BFD_HOST_U_64_BIT cnt64; + unsigned int cnt32; + + if (gmon_io_read_vma (ifp, fpc) + || gmon_io_read_vma (ifp, spc)) + return 1; + + switch (bfd_arch_bits_per_address (core_bfd)) + { + case 32: + if (gmon_io_read_32 (ifp, &cnt32)) + return 1; + *cnt = cnt32; + break; ! case 64: ! if (gmon_io_read_64 (ifp, &cnt64)) ! return 1; ! *cnt = cnt64; ! break; ! default: ! fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); done (1); } + return 0; } ! int ! DEFUN (gmon_write_raw_arc, (ofp, fpc, spc, cnt), FILE * ofp AND bfd_vma fpc AND bfd_vma spc AND unsigned long cnt) { ! ! if (gmon_io_write_vma (ofp, fpc) ! || gmon_io_write_vma (ofp, spc)) ! return 1; ! ! switch (bfd_arch_bits_per_address (core_bfd)) { ! case 32: ! if (gmon_io_write_32 (ofp, (unsigned int) cnt)) ! return 1; break; ! ! case 64: ! if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt)) ! return 1; break; + default: ! fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); done (1); } + return 0; } void *************** *** 274,284 **** int i, samp_bytes, header_size; unsigned long count; bfd_vma from_pc, self_pc; - struct raw_arc raw_arc; - struct raw_phdr raw; static struct hdr h; UNIT raw_bin_count; struct hdr tmp; /* Information from a gmon.out file is in two parts: an array of sampling hits within pc ranges, and the arcs. */ --- 317,326 ---- int i, samp_bytes, header_size; 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. */ *************** *** 293,317 **** done (1); } ! if (fread (&raw, 1, sizeof (struct raw_phdr), ifp) ! != sizeof (struct raw_phdr)) { ! fprintf (stderr, _("%s: file too short to be a gmon file\n"), filename); done (1); } ! tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]); ! tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]); ! tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]); ! if (bfd_get_32 (core_bfd, (bfd_byte *) &raw.version[0]) ! == GMONVERSION) { int profrate; /* 4.4BSD format header. */ ! profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]); if (!s_highpc) hz = profrate; --- 335,363 ---- 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; *************** *** 322,329 **** filename); done (1); } ! header_size = sizeof (struct raw_phdr); } else { --- 368,390 ---- filename); done (1); } + + switch (bfd_arch_bits_per_address (core_bfd)) + { + case 32: + header_size = GMON_HDRSIZE_BSD44_32; + break; + + case 64: + header_size = GMON_HDRSIZE_BSD44_64; + break; ! default: ! fprintf (stderr, ! _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); ! done (1); ! } } else { *************** *** 335,347 **** done (1); } ! if (fseek (ifp, sizeof (struct old_raw_phdr), SEEK_SET) < 0) { ! perror (filename); ! done (1); } ! header_size = sizeof (struct old_raw_phdr); } if (s_highpc && (tmp.low_pc != h.low_pc --- 396,424 ---- done (1); } ! switch (bfd_arch_bits_per_address (core_bfd)) { ! case 32: ! header_size = GMON_HDRSIZE_OLDBSD_32; ! break; ! ! case 64: ! header_size = GMON_HDRSIZE_OLDBSD_64; ! break; ! ! default: ! fprintf (stderr, ! _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); ! done (1); } + } ! /* 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 *************** *** 406,417 **** /* The rest of the file consists of a bunch of tuples. */ ! while (fread (&raw_arc, sizeof (raw_arc), 1, ifp) == 1) { ++narcs; - from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc); - self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc); - count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count); DBG (SAMPLEDEBUG, printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n", --- 483,491 ---- /* The rest of the file consists of a bunch of 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", *************** *** 501,543 **** } else if (file_format == FF_BSD || file_format == FF_BSD44) { - struct raw_arc raw_arc; UNIT raw_bin_count; ! struct raw_phdr h; ! int i; Arc *arc; Sym *sym; ! memset (&h, 0, sizeof h); ! put_vma (core_bfd, s_lowpc, (bfd_byte *) &h.low_pc); ! put_vma (core_bfd, s_highpc, (bfd_byte *) &h.high_pc); ! bfd_put_32 (core_bfd, ! hist_num_bins * sizeof (UNIT) + sizeof (struct raw_phdr), ! (bfd_byte *) &h.ncnt); ! ! /* Write header. Use new style BSD format is explicitly ! specified, or if the profiling rate is non-standard; ! otherwise, use the old BSD format. */ if (file_format == FF_BSD44 ! || hz != hertz ()) { ! bfd_put_32 (core_bfd, GMONVERSION, (bfd_byte *) &h.version); ! bfd_put_32 (core_bfd, hz, (bfd_byte *) &h.profrate); ! if (fwrite (&h, sizeof (struct raw_phdr), 1, ofp) != 1) { ! perror (filename); ! done (1); } } else { ! if (fwrite (&h, sizeof (struct old_raw_phdr), 1, ofp) != 1) { perror (filename); done (1); } } /* Dump the samples. */ for (i = 0; i < hist_num_bins; ++i) { --- 575,669 ---- } else if (file_format == FF_BSD || file_format == FF_BSD44) { UNIT raw_bin_count; ! int i, hdrsize, padsize; ! char pad[3*4]; Arc *arc; Sym *sym; + + memset (pad, 0, sizeof (pad)); ! /* 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 (bfd_arch_bits_per_address (core_bfd)) { ! case 32: ! hdrsize = GMON_HDRSIZE_BSD44_32; ! break; ! ! case 64: ! hdrsize = GMON_HDRSIZE_BSD44_64; ! break; ! ! default: ! fprintf (stderr, ! _("%s: bits per address has unexpected value of %u\n"), ! whoami, bfd_arch_bits_per_address (core_bfd)); ! done (1); } } else { ! padsize = 0; ! switch (bfd_arch_bits_per_address (core_bfd)) { + case 32: + hdrsize = GMON_HDRSIZE_OLDBSD_32; + break; + + case 64: + 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; + + default: + fprintf (stderr, + _("%s: bits per address has unexpected value of %u\n"), + whoami, bfd_arch_bits_per_address (core_bfd)); + done (1); + } + } + + /* 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, 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) { *************** *** 554,565 **** { for (arc = sym->cg.children; arc; arc = arc->next_child) { ! put_vma (core_bfd, arc->parent->addr, ! (bfd_byte *) raw_arc.from_pc); ! put_vma (core_bfd, arc->child->addr, ! (bfd_byte *) raw_arc.self_pc); ! bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count); ! if (fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1) { perror (filename); done (1); --- 680,687 ---- { 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);