OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / genchecksum.c
1 /* Generate checksums of executables for PCH validation
2    Copyright (C) 2005, 2007, 2009, 2010
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "bconfig.h"
22 #include "system.h"
23 #include "md5.h"
24
25 static void
26 usage (void)
27 {
28   fputs ("Usage: genchecksums <filename> ...\n", stderr);
29 }
30
31 /* Important: BLOCKSIZE must be a multiple of 64.  */
32 #define BLOCKSIZE 4096
33
34 static void
35 dosum (struct md5_ctx *ctx, const char *file)
36 {
37   FILE *f;
38   char buffer[BLOCKSIZE + 72];
39   size_t sum;
40
41   f = fopen (file, "rb");
42   if (!f)
43     {
44       fprintf (stderr, "opening %s: %s\n", file, xstrerror (errno));
45       exit (1);
46     }
47
48   /* Some executable formats have timestamps in the first 16 bytes, yuck.  */
49   if (fseek (f, 16, SEEK_SET) != 0)
50      {
51       fprintf (stderr, "seeking in %s: %s\n", file, xstrerror (errno));
52       exit (1);
53     }
54
55   /* Iterate over full file contents.  */
56   while (1)
57     {
58       /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
59          computation function processes the whole buffer so that with the
60          next round of the loop another block can be read.  */
61       size_t n;
62       sum = 0;
63
64       /* Read block.  Take care for partial reads.  */
65       do
66         {
67           n = fread (buffer + sum, 1, BLOCKSIZE - sum, f);
68
69           sum += n;
70         }
71       while (sum < BLOCKSIZE && n != 0);
72       if (n == 0 && ferror (f))
73         exit (1);
74
75       /* If end of file is reached, end the loop.  */
76       if (n == 0)
77         break;
78
79       /* Process buffer with BLOCKSIZE bytes.  Note that
80                         BLOCKSIZE % 64 == 0
81        */
82       md5_process_block (buffer, BLOCKSIZE, ctx);
83     }
84
85   /* Add the last bytes if necessary.  */
86   if (sum > 0)
87     md5_process_bytes (buffer, sum, ctx);
88
89   if (fclose (f) != 0)
90      {
91       fprintf (stderr, "reading %s: %s\n", file, xstrerror (errno));
92       exit (1);
93     }
94 }
95
96 int
97 main (int argc, char ** argv)
98 {
99   struct md5_ctx ctx;
100   unsigned char result[16];
101   int i;
102
103   if (argc < 2)
104     {
105       usage ();
106       return 1;
107     }
108
109   md5_init_ctx (&ctx);
110   for (i = 1; i < argc; i++) 
111     dosum (&ctx, argv[i]);
112   md5_finish_ctx (&ctx, result);
113
114   puts ("#include \"config.h\"");
115   puts ("#include \"system.h\"");
116   fputs ("EXPORTED_CONST unsigned char executable_checksum[16] = { ", stdout);
117   for (i = 0; i < 16; i++)
118     printf ("0x%02x%s", result[i], i == 15 ? " };\n" : ", ");
119
120   return 0;
121 }