This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: gprof fix for IA-64 (and other platforms...)
>>>>> On Tue, 13 Mar 2001 18:24:59 +1100 (EST), Alan Modra <alan@linuxcare.com.au> said:
>> --- basic_blocks.c 2001/01/27 19:54:49 1.4 +++ basic_blocks.c
>> 2001/03/13 06:31:57 @@ -227,24 +216,16 @@ }
>>
>> /* Write header: */ - bfd_put_32 (core_bfd, nblocks, (bfd_byte *)
>> & nblocks); - if (fwrite (&tag, sizeof (tag), 1, ofp) != 1 - ||
>> fwrite (&nblocks, sizeof (nblocks), 1, ofp) != 1) - { - perror
>> (filename); - done (1); - } + gmon_io_write_8 (ofp,
>> GMON_TAG_BB_COUNT); + gmon_io_write_32 (ofp, nblocks);
Alan> perror?
>> +int +DEFUN (gmon_io_write_8, (ofp, valp), FILE * ofp AND
>> u_int8_t val)
Alan> One of those pesky newfangled integer types escaped
Alan> extermination.
Thanks for catching this. v3 is attached below (just for review, like
before...).
--david
2001-03-12 David Mosberger <davidm@hpl.hp.com>
* hist.c (hist_read_rec): If SAMPLEDEBUG, print each histogram bin count.
* gconfig.in: Mention and document GMON_PTR_SIZE.
* basic_blocks.c: Whitespace cleanup.
* 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.h: Ditto.
* sym_ids.c: Ditto.
* sym_ids.h: Ditto.
* symtab.c: Ditto.
* symtab.h: Ditto.
* tahoe.c: Ditto.
* vax.c: Ditto.
* hist.c: Declare hist_dimension[] as an array of 16 characters.
We never copy more than that many bytes anyhow, so this is safe
and preserves the existing behavior.
* gmon_out.h: Delete gmon_hist_hdr and gmon_cg_arc_record
structures (they're no longer used).
* configure.in: When determining value for GMON_PTR_SIZE, fall
back to using sizeof(char *) if the platform doesn't have its
own <sys/gmon_out.h>.
* Patch by Jes Sorensen:
* 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.
2000-04-07 David Mosberger <davidm@hpl.hp.com>
* 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.c (hist_write_hist): Ditto.
2000-05-04 David Mosberger <davidm@hpl.hp.com>
* call_graph.c (cg_read_rec): Adjust type of "count" from
"unsigned long" to "u_int32_t".
2001-03-12 David Mosberger <davidm@hpl.hp.com>
* bb_exit_func.c: Run it through "indent".
Index: basic_blocks.c
===================================================================
RCS file: /cvs/src/src/gprof/basic_blocks.c,v
retrieving revision 1.4
diff -u -w -r1.4 basic_blocks.c
--- basic_blocks.c 2001/01/27 19:54:49 1.4
+++ basic_blocks.c 2001/03/13 07:32:58
@@ -2,7 +2,7 @@
of basic-block info to/from gmon.out; computing and formatting of
basic-block related statistics.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -116,18 +116,17 @@
DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
{
int nblocks, b;
- bfd_vma addr;
- unsigned long ncalls;
+ bfd_vma addr, ncalls;
Sym *sym;
- if (fread (&nblocks, sizeof (nblocks), 1, ifp) != 1)
+ if (gmon_io_read_32 (ifp, &nblocks))
{
- fprintf (stderr, _("%s: %s: unexpected end of file\n"), whoami, filename);
+ 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);
@@ -149,24 +148,17 @@
done (1);
}
}
- else
- {
- if (fread (&addr, sizeof (addr), 1, ifp) != 1
- || fread (&ncalls, sizeof (ncalls), 1, ifp) != 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)
{
- /* Convert from target to host endianness: */
- addr = get_vma (core_bfd, (bfd_byte *) & addr);
- ncalls = bfd_get_32 (core_bfd, (bfd_byte *) &ncalls);
-
sym = sym_lookup (&symtab, addr);
if (sym)
@@ -211,10 +203,7 @@
void
DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
{
- const unsigned char tag = GMON_TAG_BB_COUNT;
int nblocks = 0;
- bfd_vma addr;
- unsigned long ncalls;
Sym *sym;
int i;
@@ -227,9 +216,8 @@
}
/* Write header: */
- bfd_put_32 (core_bfd, nblocks, (bfd_byte *) & nblocks);
- if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
- || fwrite (&nblocks, sizeof (nblocks), 1, ofp) != 1)
+ if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT)
+ || gmon_io_write_32 (ofp, nblocks))
{
perror (filename);
done (1);
@@ -240,11 +228,8 @@
{
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
{
- put_vma (core_bfd, sym->bb_addr[i], (bfd_byte *) & addr);
- bfd_put_32 (core_bfd, sym->bb_calls[i], (bfd_byte *) & ncalls);
-
- if (fwrite (&addr, sizeof (addr), 1, ofp) != 1
- || fwrite (&ncalls, sizeof (ncalls), 1, ofp) != 1)
+ if (gmon_io_write_vma (ofp, sym->bb_addr[i])
+ || gmon_io_write_vma (ofp, sym->bb_calls[i]))
{
perror (filename);
done (1);
Index: bb_exit_func.c
===================================================================
RCS file: /cvs/src/src/gprof/bb_exit_func.c,v
retrieving revision 1.2
diff -u -w -r1.2 bb_exit_func.c
--- bb_exit_func.c 2000/07/26 19:59:35 1.2
+++ bb_exit_func.c 2001/03/13 07:32:58
@@ -1,7 +1,7 @@
/* bb_exit_func.c - dumps all the basic-block statistics linked into
the bb_head chain to .d files.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -30,7 +30,8 @@
#include "gmon_out.h"
/* structure emitted by -a */
-struct bb {
+struct bb
+{
long zero_word;
const char *filename;
long *counts;
@@ -49,31 +50,31 @@
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").
- */
+ /* 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) {
+ if (!fp)
+ {
perror(OUT_NAME);
return;
- } /* if */
+ }
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) {
+ for (ptr = __bb_head; ptr != 0; ptr = ptr->next)
+ {
u_int ncounts = ptr->ncounts;
u_char tag;
u_int i;
@@ -82,12 +83,11 @@
fwrite(&tag, sizeof(tag), 1, fp);
fwrite(&ncounts, sizeof(ncounts), 1, fp);
- for (i = 0; i < ncounts; ++i) {
+ 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);
- } /* for */
- } /* for */
+ }
+ }
fclose (fp);
-} /* __bb_exit_func */
-
- /*** end of __bb_exit_func.c ***/
+}
Index: call_graph.c
===================================================================
RCS file: /cvs/src/src/gprof/call_graph.c,v
retrieving revision 1.3
diff -u -w -r1.3 call_graph.c
--- call_graph.c 2000/07/24 20:59:03 1.3
+++ call_graph.c 2001/03/13 07:32:58
@@ -1,6 +1,6 @@
/* call_graph.c - Create call graphs.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -78,22 +78,21 @@
DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
{
bfd_vma from_pc, self_pc;
- struct gmon_cg_arc_record arc;
- unsigned long count;
+ unsigned int count;
- if (fread (&arc, sizeof (arc), 1, ifp) != 1)
+ 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);
}
- from_pc = get_vma (core_bfd, (bfd_byte *) arc.from_pc);
- self_pc = get_vma (core_bfd, (bfd_byte *) arc.self_pc);
- count = bfd_get_32 (core_bfd, (bfd_byte *) arc.count);
DBG (SAMPLEDEBUG,
printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %lu\n",
- (unsigned long) from_pc, (unsigned long) self_pc, count));
+ (unsigned long) from_pc, (unsigned long) self_pc,
+ (unsigned long) count));
/* Add this arc: */
cg_tally (from_pc, self_pc, count);
}
@@ -105,8 +104,6 @@
void
DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
{
- const unsigned char tag = GMON_TAG_CG_ARC;
- struct gmon_cg_arc_record raw_arc;
Arc *arc;
Sym *sym;
@@ -114,11 +111,10 @@
{
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 (&tag, sizeof (tag), 1, ofp) != 1
- || fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
+ 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);
Index: configure.in
===================================================================
RCS file: /cvs/src/src/gprof/configure.in,v
retrieving revision 1.8
diff -u -w -r1.8 configure.in
--- configure.in 2001/02/27 06:43:55 1.8
+++ configure.in 2001/03/13 07:33:00
@@ -29,6 +29,33 @@
AM_MAINTAINER_MODE
AC_EXEEXT
+AC_CHECK_HEADERS(sys/gmon_out.h)
+
+AC_MSG_CHECKING(the size of gmon pointers)
+AC_TRY_RUN([#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_GMON_OUT_H
+#include <sys/gmon_out.h>
+#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],
Index: gconfig.in
===================================================================
RCS file: /cvs/src/src/gprof/gconfig.in,v
retrieving revision 1.4
diff -u -w -r1.4 gconfig.in
--- gconfig.in 2001/02/27 06:43:55 1.4
+++ gconfig.in 2001/03/13 07:33:00
@@ -130,3 +130,5 @@
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
+/* Define as the size of a pointer in the target profile file format. */
+#undef GMON_PTR_SIZE
Index: gmon.h
===================================================================
RCS file: /cvs/src/src/gprof/gmon.h,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 gmon.h
--- gmon.h 1999/05/03 07:29:11 1.1.1.1
+++ gmon.h 2001/03/13 07:33:00
@@ -39,13 +39,8 @@
{
/* FIXME: Checking a host compiler define means that we can't use
a cross gprof to the alpha. */
-#ifdef __alpha__
- char low_pc[8]; /* base pc address of sample buffer */
- char high_pc[8]; /* max pc address of sampled buffer */
-#else
- char low_pc[4]; /* base pc address of sample buffer */
- char high_pc[4]; /* max pc address of sampled buffer */
-#endif
+ 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 */
@@ -57,15 +52,8 @@
struct old_raw_phdr
{
- /* FIXME: Checking a host compiler define means that we can't use
- a cross gprof to the alpha. */
-#ifdef __alpha__
- char low_pc[8]; /* base pc address of sample buffer */
- char high_pc[8]; /* max pc address of sampled buffer */
-#else
- char low_pc[4]; /* base pc address of sample buffer */
- char high_pc[4]; /* max pc address of sampled buffer */
-#endif
+ 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
@@ -134,17 +122,9 @@
*/
struct raw_arc
{
- /* FIXME: Checking a host compiler define means that we can't use
- a cross gprof to the alpha. */
-#ifdef __alpha__
- char from_pc[8];
- char self_pc[8];
- char count[8];
-#else
- char from_pc[4];
- char self_pc[4];
+ char from_pc[GMON_PTR_SIZE];
+ char self_pc[GMON_PTR_SIZE];
char count[4];
-#endif
};
/*
Index: gmon_io.c
===================================================================
RCS file: /cvs/src/src/gprof/gmon_io.c,v
retrieving revision 1.5
diff -u -w -r1.5 gmon_io.c
--- gmon_io.c 2000/07/24 20:59:03 1.5
+++ gmon_io.c 2001/03/13 07:33:00
@@ -1,6 +1,6 @@
/* gmon_io.c - Input and output from/to gmon.out files.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -35,9 +35,113 @@
int gmon_input = 0;
int gmon_file_version = 0; /* 0 == old (non-versioned) file format. */
-/* This probably ought to be in libbfd. */
+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;
+}
-bfd_vma
+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, valp), 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_vma, (ofp, valp), 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, valp), 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, valp), FILE * ofp AND unsigned char val)
+{
+ char buf[1];
+
+ bfd_put_8 (core_bfd, val, buf);
+ if (fwrite (buf, 1, 1, ofp) != 1)
+ return 1;
+ return 0;
+}
+
+int
+DEFUN (gmon_io_write, (ofp, valp), FILE * ofp AND char *buf AND size_t n)
+{
+ if (fwrite (buf, 1, n, ofp) != n)
+ 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*))
@@ -52,11 +156,8 @@
done (1);
}
}
-
-/* This probably ought to be in libbfd. */
-
-void
+static void
DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr)
{
switch (sizeof (char*))
@@ -74,7 +175,6 @@
}
}
-
void
DEFUN (gmon_out_read, (filename), const char *filename)
{
@@ -109,8 +209,8 @@
done (1);
}
- if ((file_format == FF_MAGIC) ||
- (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
+ 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))
{
@@ -244,8 +344,8 @@
header_size = sizeof (struct old_raw_phdr);
}
- if (s_highpc && (tmp.low_pc != h.low_pc ||
- tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
+ 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);
Index: gmon_io.h
===================================================================
RCS file: /cvs/src/src/gprof/gmon_io.h,v
retrieving revision 1.3
diff -u -w -r1.3 gmon_io.h
--- gmon_io.h 2000/07/24 20:59:03 1.3
+++ gmon_io.h 2001/03/13 07:33:00
@@ -1,6 +1,6 @@
/* gmon_io.h
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -49,8 +49,14 @@
extern int gmon_input; /* What input did we see? */
extern int gmon_file_version; /* File version are we dealing with. */
-extern bfd_vma get_vma PARAMS ((bfd *, bfd_byte *));
-extern void put_vma PARAMS ((bfd *, bfd_vma, bfd_byte *));
+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 char 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 *));
Index: gmon_out.h
===================================================================
RCS file: /cvs/src/src/gprof/gmon_out.h,v
retrieving revision 1.2
diff -u -w -r1.2 gmon_out.h
--- gmon_out.h 2000/07/24 20:59:03 1.2
+++ gmon_out.h 2001/03/13 07:33:00
@@ -1,6 +1,6 @@
/* gmon_out.h
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -18,17 +18,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* This file specifies the format of gmon.out files. It should have
- as few external dependencies as possible as it is going to be
- included in many different programs. That is, minimize the
- number of #include's.
-
- A gmon.out file consists of a header (defined by gmon_hdr) followed
+/* 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
+#include <gconfig.h>
+
#define GMON_MAGIC "gmon" /* magic cookie */
#define GMON_VERSION 1 /* version number */
@@ -46,22 +43,5 @@
GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2
}
GMON_Record_Tag;
-
-struct gmon_hist_hdr
- {
- char low_pc[sizeof (char*)]; /* Base pc address of sample buffer. */
- char high_pc[sizeof (char*)]; /* Max pc address of sampled buffer. */
- char hist_size[4]; /* Size of sample buffer. */
- char prof_rate[4]; /* Profiling clock rate. */
- char dimen[15]; /* Phys. dim., usually "seconds". */
- char dimen_abbrev; /* Usually 's' for "seconds". */
- };
-
-struct gmon_cg_arc_record
- {
- char from_pc[sizeof (char*)]; /* Address within caller's body. */
- char self_pc[sizeof (char*)]; /* Address within callee's body. */
- char count[4]; /* Number of arc traversals. */
- };
#endif /* gmon_out_h */
Index: hist.c
===================================================================
RCS file: /cvs/src/src/gprof/hist.c,v
retrieving revision 1.3
diff -u -w -r1.3 hist.c
--- hist.c 2000/07/24 20:59:03 1.3
+++ hist.c 2001/03/13 07:33:00
@@ -1,6 +1,6 @@
/* hist.c - Histogram related operations.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -43,8 +43,7 @@
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[sizeof (((struct gmon_hist_hdr *) 0)->dimen) + 1] =
- "seconds";
+char hist_dimension[16] = "seconds";
char hist_dimension_abbrev = 's';
static double accum_time; /* Accumulated time so far for print_line(). */
@@ -59,50 +58,17 @@
}
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 */
+ { '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 */
};
@@ -112,26 +78,23 @@
void
DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
{
- struct gmon_hist_hdr hdr;
bfd_vma n_lowpc, n_highpc;
int i, ncnt, profrate;
UNIT count;
- if (fread (&hdr, sizeof (hdr), 1, ifp) != 1)
+ 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);
}
- n_lowpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.low_pc);
- n_highpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.high_pc);
- ncnt = bfd_get_32 (core_bfd, (bfd_byte *) hdr.hist_size);
- profrate = bfd_get_32 (core_bfd, (bfd_byte *) hdr.prof_rate);
- strncpy (hist_dimension, hdr.dimen, sizeof (hdr.dimen));
- hist_dimension[sizeof (hdr.dimen)] = '\0';
- hist_dimension_abbrev = hdr.dimen_abbrev;
-
if (!s_highpc)
{
/* This is the first histogram record. */
@@ -176,6 +139,9 @@
done (1);
}
hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
+ DBG (SAMPLEDEBUG,
+ printf ("[hist_read_rec] 0x%lx: %u\n",
+ n_lowpc + i*(n_highpc - n_lowpc)/ncnt, hist_sample[i]));
}
}
@@ -186,23 +152,18 @@
void
DEFUN (hist_write_hist, (ofp, filename), FILE * ofp AND const char *filename)
{
- struct gmon_hist_hdr hdr;
- unsigned char tag;
UNIT count;
int i;
/* Write header. */
-
- tag = GMON_TAG_TIME_HIST;
- put_vma (core_bfd, s_lowpc, (bfd_byte *) hdr.low_pc);
- put_vma (core_bfd, s_highpc, (bfd_byte *) hdr.high_pc);
- bfd_put_32 (core_bfd, hist_num_bins, (bfd_byte *) hdr.hist_size);
- bfd_put_32 (core_bfd, hz, (bfd_byte *) hdr.prof_rate);
- strncpy (hdr.dimen, hist_dimension, sizeof (hdr.dimen));
- hdr.dimen_abbrev = hist_dimension_abbrev;
- if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
- || fwrite (&hdr, sizeof (hdr), 1, ofp) != 1)
+ 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);
@@ -239,7 +200,8 @@
{
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;
+ bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - lowpc)
+ / hist_scale);
if (bin_of_entry < bin_of_code)
{
DBG (SAMPLEDEBUG,
@@ -410,7 +372,8 @@
}
printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
- "% ", _("cumulative"), _("self "), "", _("self "), _("total "), "");
+ "% ", _("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"));
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gprof/utils.c,v
retrieving revision 1.2
diff -u -w -r1.2 utils.c
--- utils.c 2000/01/26 23:11:48 1.2
+++ utils.c 2001/03/13 07:33:01
@@ -68,7 +68,8 @@
filename = self->file->name;
}
}
- sprintf (buf, " (%s:%d)", filename, self->line_num);
+ sprintf (buf, " (%s:%d @ %lx)", filename, self->line_num,
+ (unsigned long) self->addr);
printf ("%s", buf);
size += strlen (buf);
}