This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: struct gmon_cg_arc_record


Hi

I am Cc'ing the binutils list on this. To those of you on this list
who do not read libc-hacker, let me just give a brief description of
the problem:

Basically it looks like gprof was written with 32 bit architectures in
mind and the on disk format of gmon.out quite shows this. When
generating this format in memory on a machine like the ia64 we get
misaligned stores so it seemed like a good idea to change the format
at least for Linux/ia64. However it is not quite obvious whether
profile support actually works under Linux/Alpha at the moment since
there seems to be some inconsistency in the defines of the structures
gmon_cg_arc_record vs and raw_arc. Thus I have attached a patch that
cleans up the special casing of the struct formats for 64 bit
architestures as well as declare 'count' as a long under Linux. I
didn't dare to change this for OSF/1 etc.

>>>>> "Ulrich" == Ulrich Drepper <drepper@redhat.com> writes:

Ulrich> Jes Sorensen <jes@linuxcare.com> writes:
>> 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 count[4]; #endif };

Ulrich> Doesn't this mean profiling on Alpha doesn't work at all?
Ulrich> THen of course we should change it.

Hmmm that was the impression I got at first, however looking a bit
more at the gprof source I see that they operate on two formats, a
binary and a run time format. Ie. for the Alpha they expect a count of
4 on the disk but it is moved to a count of 8 internally. Grmbl grmbl
grmbl.

gprof clearly tries to work on OSF/1 as well, however I can't find a
definition of the structures on the OSF/1 box I searched on so I
cannot verify what it expects.

Ulrich> No, you misread the definition.  The hist_size field
Ulrich> corresponds to ncnt.  The prof_rate rate to version.  The
Ulrich> dimen and dimen_abbrev field correspond to the profrate and
Ulrich> spare field.

Ulrich> So we cannot simply add a new field, we would have to reorder
Ulrich> them.  The question is: was it always like this?  Profiling
Ulrich> certainly worked for x86.

Whoops, need to go study this some more I guess.

Anyway my conclusion would be to recommend that we change the binary
format for 64 bit arcitectures under Linux as you also recommended. It
sounds like Jakub agrees as well.

I have attached a patch for gprof for those who wants to play with it
and a patch for glibc.

Jes

2000-11-14  Jes Sorensen  <jes@linuxcare.com>

	* gmon.h: Make definitions of low_pc, high_pc, from_pc, self_pc
	sizeof(char *) to work on 64 bit architectures and not just the
	Alpha which was special cased.

	* gmon_out.h (struct gmon_cg_arc_record): count element should be
	64 bit on 64 bit architectures under Linux to match glibc-2.2.

--- gprof/gmong.h-old	Sun Apr  4 16:42:59 1999
+++ gprof/gmon.h	Tue Nov 14 17:04:31 2000
@@ -37,15 +37,8 @@
 
 struct 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[sizeof (char *)];	/* base pc address of sample buffer */
+    char high_pc[sizeof (char *)];	/* max pc address of sampled buffer */
     char ncnt[4];		/* size of sample buffer (plus this header) */
 
     char version[4];		/* version number */
@@ -57,15 +50,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[sizeof (char *)];	/* base pc address of sample buffer */
+    char high_pc[sizeof (char *)];	/* 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,15 +120,11 @@
  */
 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];
+    char from_pc[sizeof (char *)];
+    char self_pc[sizeof (char *)];
+#ifdef linux
+    char count[sizeof (char *)];
 #else
-    char from_pc[4];
-    char self_pc[4];
     char count[4];
 #endif
   };
--- gprof/gmon_out.h-old	Tue Nov 14 16:46:44 2000
+++ gprof/gmon_out.h	Tue Nov 14 17:01:14 2000
@@ -45,7 +45,11 @@
   {
     char from_pc[sizeof (char*)];	/* address within caller's body */
     char self_pc[sizeof (char*)];	/* address within callee's body */
+#ifdef linux
+    char count[sizeof (char*)];		/* number of arc traversals */
+#else
     char count[4];			/* number of arc traversals */
+#endif
   };
 
 #endif /* gmon_out_h */

----------------

For glibc:

2000-11-14  Jes Sorensen  <jes@linuxcare.com>

	* gmon/sys/gmon_out.h (struct gmon_cg_arc_record): Change size of
	count element to sizeof (char *).

        * gmon/gmon.c (write_call_graph): 

--- /home/jes/cygnus/libc-2.2/gmon/sys/gmon_out.h	Sun Aug 10 13:02:27 1997
+++ libc-2.2/gmon/sys/gmon_out.h	Tue Nov 14 17:06:10 2000
@@ -72,7 +72,7 @@
   {
     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 */
+    char count[sizeof (char *)];	/* number of arc traversals */
   };
 
 __END_DECLS
--- /home/jes/cygnus/libc-2.2/gmon/gmon.c	Tue Apr 18 22:39:11 2000
+++ libc-2.2/gmon/gmon.c	Tue Nov 14 17:23:55 2000
@@ -239,7 +239,7 @@
 	  *(char **) raw_arc[nfilled].from_pc = (char *) frompc;
 	  *(char **) raw_arc[nfilled].self_pc =
 	    (char *)_gmonparam.tos[to_index].selfpc;
-	  *(int *) raw_arc[nfilled].count = _gmonparam.tos[to_index].count;
+	  *(long *) raw_arc[nfilled].count = _gmonparam.tos[to_index].count;
 
 	  if (++nfilled == NARCS_PER_WRITEV)
 	    {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]