OSDN Git Service

* config/sparc/sparc.c (sparc_option_override): If not set by the user,
[pf3gnuchains/gcc-fork.git] / gcc / genchecksum.c
index 465a4f6..e0c71f4 100644 (file)
@@ -1,12 +1,12 @@
 /* Generate checksums of executables for PCH validation
-   Copyright (C) 2005
+   Copyright (C) 2005, 2007, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC 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, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ 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 GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "bconfig.h"
 #include "system.h"
@@ -26,52 +25,97 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 static void
 usage (void)
 {
-  fputs ("Usage: genchecksums <filename>\n", stderr);
+  fputs ("Usage: genchecksums <filename> ...\n", stderr);
 }
 
+/* Important: BLOCKSIZE must be a multiple of 64.  */
+#define BLOCKSIZE 4096
+
 static void
-dosum (const char *file)
+dosum (struct md5_ctx *ctx, const char *file)
 {
   FILE *f;
-  unsigned char result[16];
-  int i;
-  
+  char buffer[BLOCKSIZE + 72];
+  size_t sum;
+
   f = fopen (file, "rb");
   if (!f)
     {
       fprintf (stderr, "opening %s: %s\n", file, xstrerror (errno));
       exit (1);
     }
-  
+
   /* Some executable formats have timestamps in the first 16 bytes, yuck.  */
   if (fseek (f, 16, SEEK_SET) != 0)
      {
       fprintf (stderr, "seeking in %s: %s\n", file, xstrerror (errno));
       exit (1);
     }
-  
-  if (md5_stream (f, result) != 0
-      || fclose (f) != 0)
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+        computation function processes the whole buffer so that with the
+        next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      do
+       {
+         n = fread (buffer + sum, 1, BLOCKSIZE - sum, f);
+
+         sum += n;
+       }
+      while (sum < BLOCKSIZE && n != 0);
+      if (n == 0 && ferror (f))
+        exit (1);
+
+      /* If end of file is reached, end the loop.  */
+      if (n == 0)
+       break;
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+                       BLOCKSIZE % 64 == 0
+       */
+      md5_process_block (buffer, BLOCKSIZE, ctx);
+    }
+
+  /* Add the last bytes if necessary.  */
+  if (sum > 0)
+    md5_process_bytes (buffer, sum, ctx);
+
+  if (fclose (f) != 0)
      {
       fprintf (stderr, "reading %s: %s\n", file, xstrerror (errno));
       exit (1);
     }
-
-  fputs ("const unsigned char executable_checksum[16] = { ", stdout);
-  for (i = 0; i < 16; i++)
-    printf ("%#02x%s", result[i], i == 15 ? " };\n" : ", ");
 }
 
 int
 main (int argc, char ** argv)
 {
-  if (argc != 2)
+  struct md5_ctx ctx;
+  unsigned char result[16];
+  int i;
+
+  if (argc < 2)
     {
       usage ();
       return 1;
     }
 
-  dosum (argv[1]);
+  md5_init_ctx (&ctx);
+  for (i = 1; i < argc; i++) 
+    dosum (&ctx, argv[i]);
+  md5_finish_ctx (&ctx, result);
+
+  puts ("#include \"config.h\"");
+  puts ("#include \"system.h\"");
+  fputs ("EXPORTED_CONST unsigned char executable_checksum[16] = { ", stdout);
+  for (i = 0; i < 16; i++)
+    printf ("0x%02x%s", result[i], i == 15 ? " };\n" : ", ");
 
   return 0;
 }