[Hat] Update hat-check for 64 bits

nlavine at haverford.edu nlavine at haverford.edu
Thu Jun 19 09:19:03 EDT 2008


Hat-check assumes that sizeof(unsigned long) is 32 bits, with the result
that it can't read trace files correctly on 64 bit machines. This patch
changes unsigned longs to FileOffsets. Experimentally, it now works in 64
bits, although there are still some assumptions about sizeof(float) and
sizeof(double) that might make files unportable - I don't know how much
those change across architectures.

Noah Lavine

--- hat-check.c	2006-10-10 09:57:51.000000000 -0400
+++ hat-check.c	2008-06-19 09:14:03.694050843 -0400
@@ -20,6 +20,17 @@
  *   Added -g option to generate dot-code for graph diagram.
  * 4 August 2004 - Olaf
  *   Update to extended position format (begin and end location).
+ * 18 June 2008 - Noah Lavine
+ *   Change (unsigned long) to (FileOffset) for compatibility with 64-bit
+ *   system.
+ * /
+
+/*   Further changes that would be good - remove assumption that
sizeof(char)
+ *   is one byte. Add range checks (for -n <offset>, the file size, maybe
other
+ *   things too). Look at readfloat() and readdouble(), maybe set definitive
+ *   size (right now hat files are not portable across platforms with
different
+ *   sizeof(float) and sizeof(double)). make sure (unsigned long) is at
least
+ *   as big as both (FileOffset) and (unsigned int), for function pc().
  */

 /* #include <unistd.h> */
@@ -27,6 +38,7 @@
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <signal.h>

@@ -48,9 +60,9 @@
 void header (void);
 void nodes (void);
 void nextnode (void);
-void markfromheader (unsigned long *buf);
-void markfromoutput (char *bridgefile, unsigned long *buf);
-void markfrom (unsigned long root, unsigned long *buf);
+void markfromheader (FileOffset *buf);
+void markfromoutput (char *bridgefile, FileOffset *buf);
+void markfrom (FileOffset root, FileOffset *buf);

 /* strings for symbolic constants */
 char*
@@ -112,7 +124,7 @@
  */

 FILE* f;             /* file descriptor for archive */
-unsigned long nextoffset=0;	/* current position in file */
+FileOffset nextoffset=0;	/* current position in file */

 int vmode = 0;       /* verify -- check tag-types of pointer destinations */
 int smode = 0;       /* statistics -- counts and space usage for node
types */
@@ -122,7 +134,7 @@
 int rmode = 0;       /* reachable -- show how many nodes are reachable */
 int xmode = 0;       /* exit mode -- cleanup after signal to halt */

-unsigned filesize = 0; /* used in precondition for seeks ... */
+FileOffset filesize = 0; /* used in precondition for seeks ... */
 struct stat statbuf;   /* ... to catch seek beyond EOF */

 #define FILENAMESIZE 200
@@ -130,7 +142,7 @@

 /* byte buffer for use in reachability mark-phase */
 #define BUFFERSIZE 100000
-unsigned long buffer[BUFFERSIZE];
+FileOffset buffer[BUFFERSIZE];

 /* signal handler -- only installed for -r */
 void
@@ -139,8 +151,8 @@
   fprintf(stderr, "hat-check cleaning up -- please wait\n");
   amode = 0; rmode = 0; smode = 0; vmode = 0;
   xmode = 1;
-  fseek(f,0,SEEK_SET);
-  nextoffset = 0;
+  fseek(f,(long int)(FileOffset)0,SEEK_SET);
+  nextoffset = (FileOffset)0;
   header();
   nodes();
   exit(1);
@@ -199,7 +211,7 @@
       fprintf(stderr,"   but this tool deals with format version
%s\n",FILEVERSION);
       fprintf(stderr,"   I'm continuing, but there may be unexpected
errors.\n");
     }
-    fseek(f,0,SEEK_SET);	/* reset to beginning of file */
+    fseek(f,(long int)(FileOffset)0,SEEK_SET);	/* reset to beginning of
file */
     free(header);
   }

@@ -210,7 +222,7 @@
     }
     amode = 1; rmode = 0; smode = 0;
   } else {
-    nextoffset = 0L;
+    nextoffset = (FileOffset)0;
   }
   if (rmode) {
     signal(SIGINT, restoretags);
@@ -220,9 +232,9 @@
     markfromheader(buffer);
     strcat(filename, ".bridge");
     markfromoutput(filename,buffer);
-    fseek(f,0,SEEK_SET);
+    fseek(f,(long int)(FileOffset)0,SEEK_SET);
   }
-  fseek(f,nextoffset,SEEK_SET);
+  fseek(f,(long int)nextoffset,SEEK_SET);
   if (nmode) {
     nextnode();
   } else {
@@ -258,8 +270,8 @@

 #define MAX_TAG 32
 unsigned int count[MAX_TAG]; /* indexed by tag byte: Module, SrcPos, etc */
-unsigned long space[MAX_TAG];/* ditto */
-unsigned long headspace;     /* space oocupied by header */
+FileOffset space[MAX_TAG];/* ditto */
+FileOffset headspace;     /* space oocupied by header */
 unsigned int reachcount[MAX_TAG];

 void
@@ -284,7 +296,7 @@
 {
   unsigned int grandcount = 1;
   unsigned int grandreachcount = 1;
-  unsigned long grandspace = headspace;
+  FileOffset grandspace = headspace;
   int k;
   for (k=0; k<MAX_TAG; k++) {
     grandcount += count[k];
@@ -296,12 +308,14 @@
     "Number", "Description", "Bytes", "% Space");
   if (rmode) printf("%7.1f", pc(1,1));
   printf("%10u   %-20s%12u%10.1f\n",
-    1, "header", headspace, pc(headspace,grandspace));
+    1, "header", headspace,
+    pc((unsigned long)headspace,(unsigned long)grandspace));
   for (k=0; k<=ListCons; (k==ExpDoStmt? k=AtomVariable: k++)) {
-    if (rmode) printf("%7.1f", pc(reachcount[k], count[k]));
+    if (rmode) printf("%7.1f", pc((unsigned long)reachcount[k],
+                                  (unsigned long)count[k]));
     printf("%10u   %-20s%12u%10.1f\n",
       count[k], tag2str(k), space[k],
-      pc(space[k],grandspace));
+      pc((unsigned long)space[k],(unsigned long)grandspace));
   }
   { int w;
     putchar('\n');
@@ -309,9 +323,11 @@
     for (w=0; w<55; w++) putchar(w<13 ? ' ' : '-');
     putchar('\n');
   }
-  if (rmode) printf("%7.1f", pc(grandreachcount,grandcount));
+  if (rmode) printf("%7.1f", pc((unsigned long)grandreachcount,
+                                (unsigned long)grandcount));
   printf("%10u   %-20s%12u%10.1f\n",
-    grandcount, "whole trace file", grandspace, pc(grandspace,grandspace));
+    grandcount, "whole trace file", grandspace, pc((unsigned
long)grandspace,
+                                                   (unsigned
long)grandspace));
 }

 char
@@ -360,7 +376,7 @@
   return buf;
 }

-typedef unsigned long fourbytes;
+typedef uint32_t fourbytes;

 fourbytes
 readfourbytes (void)
@@ -384,16 +400,16 @@
 char*
 readposn (void)
 {
-  unsigned long begin = readfourbytes();
-  unsigned long end = readfourbytes();
+  FileOffset begin = (FileOffset)readfourbytes();
+  FileOffset end = (FileOffset)readfourbytes();
   sprintf(posnbuf, "position %u:%u-%u:%u,",
           begin/10000, begin%10000, end/10000, end%10000);
   return posnbuf;
 }

-unsigned long
+FileOffset
 readpointer (void)
-{ return readfourbytes(); }
+{ return (FileOffset)readfourbytes(); }

 char
 readchar (void)
@@ -401,7 +417,7 @@

 int
 readint (void)
-{ return readfourbytes(); }
+{ return (int)readfourbytes(); }

 char*
 readinteger (void)
@@ -487,25 +503,25 @@
 }

 int
-tagat (unsigned long offset)
+tagat (FileOffset offset)
 {
   char byte[1];
   int i;
   if (offset <= filesize) {
-    fseek(f, offset, SEEK_SET);
+    fseek(f, (long int)offset, SEEK_SET);
     i = fread(byte,sizeof(char),1,f);
-    fseek(f, nextoffset, SEEK_SET);
+    fseek(f, (long int)nextoffset, SEEK_SET);
     if (rmode) cleartag(byte);
     return (i==1 ? lo5(*byte) : INVALID);
   } else return BEYOND;
 }

 void
-newtagat (char *t, unsigned long offset)
+newtagat (char *t, FileOffset offset)
 {
-  fseek(f, offset, SEEK_SET);
+  fseek(f, (FileOffset)offset, SEEK_SET);
   fwrite(t,sizeof(char),1,f);
-  fseek(f, nextoffset, SEEK_SET);
+  fseek(f, (FileOffset)nextoffset, SEEK_SET);
 }


@@ -525,8 +541,8 @@

 void
 dopointer (int okzero,
-           int requiretag, unsigned long requireoffset,
-           int contexttag, unsigned long contextoffset,
+           int requiretag, FileOffset requireoffset,
+           int contexttag, FileOffset contextoffset,
 	   char *edgelabel)
 {
   if (vmode && ((okzero==NONZERO && requireoffset <= Interrupted)
@@ -590,9 +606,9 @@
   nextoffset = 8;
   if (amode) printf("%s", s);
   if (amode) printf("\nEntry point: ");
-  dopointer(MAYBEZERO, ANYEXP, readpointer(), HEADER, 0L, "");
+  dopointer(MAYBEZERO, ANYEXP, readpointer(), HEADER, (FileOffset)0, "");
   if (amode) printf("\nError message: ");
-  dopointer(MAYBEZERO, AtomAbstract, readpointer(), HEADER, 0L, "");
+  dopointer(MAYBEZERO, AtomAbstract, readpointer(), HEADER,
(FileOffset)0, "");
   if (amode) printf("\n");
   headspace = nextoffset;
 }
@@ -604,7 +620,7 @@
 void
 nextnode (void)
 {
-  unsigned long offset = nextoffset;
+  FileOffset offset = nextoffset;
   char b;
   int marked, err;
   err = fread(&b,sizeof(char),1,f); nextoffset+=1;
@@ -893,28 +909,28 @@
 /* Traverse the trail structure starting from output and error
  * roots, marking all reachable nodes.
  */
-unsigned long
-getpointer (unsigned long *buf)
+FileOffset
+getpointer (FileOffset *buf)
 {  return ntohl(*buf); }

 /* reading, checking and/or writing header and node information
  */
 void
-markfromheader (unsigned long *buf)
+markfromheader (FileOffset *buf)
 {
   fseek(f,8L,SEEK_SET);
-  fread(buf,sizeof(unsigned long),2,f);
+  fread(buf,sizeof(FileOffset),2,f);
   markfrom(getpointer(buf+1),buf+1);
   markfrom(getpointer(buf),  buf);
 }

 void
-markfromoutput (char *bridgefile, unsigned long *buf)
+markfromoutput (char *bridgefile, FileOffset *buf)
 {
   FILE* bridge = fopen(bridgefile, "rb");
   if (bridge==(FILE*)0) return;
   for (;;) {
-    int n = fread(buf,sizeof(unsigned long),1,bridge);
+    int n = fread(buf,sizeof(FileOffset),1,bridge);
     if (n<1) return;
     markfrom(getpointer(buf),buf);
   }
@@ -926,18 +942,18 @@
  * tag byte
  */
 void
-markfrom (unsigned long root, unsigned long *buf)
+markfrom (FileOffset root, FileOffset *buf)
 {
   char tag;
   if (root > 8 && root < filesize) {
     /* First read the tag byte.  If it is marked, return.
      * If it is not marked, then mark it now.
      */
-    fseek(f,root,SEEK_SET);
+    fseek(f,(long int)root,SEEK_SET);
     fread(&tag,sizeof(char),1,f);
     if (ismarked(tag)) return;
     marktag(&tag);
-    fseek(f,root,SEEK_SET);
+    fseek(f,(long int)root,SEEK_SET);
     fwrite(&tag,sizeof(char),1,f);
     cleartag(&tag);
     /* Examine the tag to determine the kind of node.
@@ -956,7 +972,7 @@
       }
       switch (k) {
         case ListCons:
-          fread(buf,sizeof(unsigned long),2,f);	/* two pointers */
+          fread(buf,sizeof(FileOffset),2,f);	/* two pointers */
           markfrom(getpointer(buf+1),buf+1);
           markfrom(getpointer(buf),buf);
 	  break;
@@ -966,41 +982,41 @@
         case SrcPos:
         case AtomVariable:
         case AtomConstructor: 	/* ignore fieldnames for now */
-          fread(buf,sizeof(unsigned long),1,f);	/* points to module mode */
+          fread(buf,sizeof(FileOffset),1,f);	/* points to module mode */
           markfrom(getpointer(buf),buf);
           break;

         default: {
           int pos = 0;
           if (hasSrcPos(tag)) {
-            fread(buf+pos,sizeof(unsigned long),1,f);
+            fread(buf+pos,sizeof(FileOffset),1,f);
             pos++;
           }
-          fread(buf+pos,sizeof(unsigned long),1,f);	/* parent pointer */
+          fread(buf+pos,sizeof(FileOffset),1,f);	/* parent pointer */
           pos++;
           switch (k) {
             case ExpApp:
-              fread(buf+pos,sizeof(unsigned long),2,f); /* result+fun */
+              fread(buf+pos,sizeof(FileOffset),2,f); /* result+fun */
               pos += 2;
               { unsigned char arity;
                 fread(&arity,sizeof(unsigned char),1,f);
-                fread(buf+pos,sizeof(unsigned long),(unsigned int)arity,f);
+                fread(buf+pos,sizeof(FileOffset),(unsigned int)arity,f);
                 pos += (int)arity;
               }
 	      break;
             case ExpValueApp:
-              fread(buf+pos,sizeof(unsigned long),1,f); /* fun */
+              fread(buf+pos,sizeof(FileOffset),1,f); /* fun */
               pos += 1;
               { unsigned char arity;
                 fread(&arity,sizeof(unsigned char),1,f);
-                fread(buf+pos,sizeof(unsigned long),(unsigned int)arity,f);
+                fread(buf+pos,sizeof(FileOffset),(unsigned int)arity,f);
                 pos += (int)arity;
               }
 	      break;
             case ExpValueUse:
             case ExpConstUse:
             case ExpProjection:
-              fread(buf+pos,sizeof(unsigned long),1,f);	/* one extra
pointer */
+              fread(buf+pos,sizeof(FileOffset),1,f);	/* one extra pointer */
               pos++;
 	      break;
             case ExpHidden:
@@ -1009,7 +1025,7 @@
             case ExpGuard:
             case ExpCase:
             case ExpIf:
-              fread(buf+pos,sizeof(unsigned long),2,f);	/* two pointers */
+              fread(buf+pos,sizeof(FileOffset),2,f);	/* two pointers */
               pos+=2;
 	      break;
             default: break;				/* no pointers */



More information about the Hat mailing list