When a merge does not work automatically, git prevents
[sfrench/cifs-2.6.git] / arch / ppc / boot / utils / addSystemMap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <byteswap.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 void xlate( char * inb, char * trb, unsigned len )
8 {
9     unsigned i;
10     for (  i=0; i<len; ++i ) {
11         char c = *inb++;
12         char c1 = c >> 4;
13         char c2 = c & 0xf;
14         if ( c1 > 9 )
15             c1 = c1 + 'A' - 10;
16         else
17             c1 = c1 + '0';
18         if ( c2 > 9 )
19             c2 = c2 + 'A' - 10;
20         else
21             c2 = c2 + '0';
22         *trb++ = c1;
23         *trb++ = c2;
24     }
25     *trb = 0;
26 }
27
28 #define ElfHeaderSize  (64 * 1024)
29 #define ElfPages  (ElfHeaderSize / 4096)
30 #define KERNELBASE (0xc0000000)
31
32 void get4k( /*istream *inf*/FILE *file, char *buf )
33 {
34     unsigned j;
35     unsigned num = fread(buf, 1, 4096, file);
36     for (  j=num; j<4096; ++j )
37         buf[j] = 0;
38 }
39
40 void put4k( /*ostream *outf*/FILE *file, char *buf )
41 {
42     fwrite(buf, 1, 4096, file);
43 }
44
45 int main(int argc, char **argv)
46 {
47     char inbuf[4096];
48     FILE *ramDisk = NULL;
49     FILE *inputVmlinux = NULL;
50     FILE *outputVmlinux = NULL;
51     unsigned i = 0;
52     unsigned long ramFileLen = 0;
53     unsigned long ramLen = 0;
54     unsigned long roundR = 0;
55     unsigned long kernelLen = 0;
56     unsigned long actualKernelLen = 0;
57     unsigned long round = 0;
58     unsigned long roundedKernelLen = 0;
59     unsigned long ramStartOffs = 0;
60     unsigned long ramPages = 0;
61     unsigned long roundedKernelPages = 0;
62     if ( argc < 2 ) {
63         printf("Name of System Map file missing.\n");
64         exit(1);
65     }
66
67     if ( argc < 3 ) {
68         printf("Name of vmlinux file missing.\n");
69         exit(1);
70     }
71
72     if ( argc < 4 ) {
73         printf("Name of vmlinux output file missing.\n");
74         exit(1);
75     }
76
77     ramDisk = fopen(argv[1], "r");
78     if ( ! ramDisk ) {
79         printf("System Map file \"%s\" failed to open.\n", argv[1]);
80         exit(1);
81     }
82     inputVmlinux = fopen(argv[2], "r");
83     if ( ! inputVmlinux ) {
84         printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
85         exit(1);
86     }
87     outputVmlinux = fopen(argv[3], "w");
88     if ( ! outputVmlinux ) {
89         printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
90         exit(1);
91     }
92     fseek(ramDisk, 0, SEEK_END);
93     ramFileLen = ftell(ramDisk);
94     fseek(ramDisk, 0, SEEK_SET);
95     printf("%s file size = %ld\n", argv[1], ramFileLen);
96
97     ramLen = ramFileLen;
98
99     roundR = 4096 - (ramLen % 4096);
100     if ( roundR ) {
101         printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
102         ramLen += roundR;
103     }
104
105     printf("Rounded System Map size is %ld\n", ramLen);
106     fseek(inputVmlinux, 0, SEEK_END);
107     kernelLen = ftell(inputVmlinux);
108     fseek(inputVmlinux, 0, SEEK_SET);
109     printf("kernel file size = %ld\n", kernelLen);
110     if ( kernelLen == 0 ) {
111         printf("You must have a linux kernel specified as argv[2]\n");
112         exit(1);
113     }
114
115     actualKernelLen = kernelLen - ElfHeaderSize;
116
117     printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen);
118
119     round = actualKernelLen % 4096;
120     roundedKernelLen = actualKernelLen;
121     if ( round )
122         roundedKernelLen += (4096 - round);
123
124     printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen);
125
126     ramStartOffs = roundedKernelLen;
127     ramPages = ramLen / 4096;
128
129     printf("System map pages to copy = %ld\n", ramPages);
130
131     // Copy 64K ELF header
132       for (i=0; i<(ElfPages); ++i) {
133           get4k( inputVmlinux, inbuf );
134           put4k( outputVmlinux, inbuf );
135       }
136
137
138
139     roundedKernelPages = roundedKernelLen / 4096;
140
141     fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
142
143     {
144         for ( i=0; i<roundedKernelPages; ++i ) {
145             get4k( inputVmlinux, inbuf );
146             if ( i == 0 ) {
147                 unsigned long * p;
148                 printf("Storing embedded_sysmap_start at 0x3c\n");
149                 p = (unsigned long *)(inbuf + 0x3c);
150
151 #if (BYTE_ORDER == __BIG_ENDIAN)
152                 *p = ramStartOffs;
153 #else
154                 *p = bswap_32(ramStartOffs);
155 #endif
156
157                 printf("Storing embedded_sysmap_end at 0x44\n");
158                 p = (unsigned long *)(inbuf + 0x44);
159 #if (BYTE_ORDER == __BIG_ENDIAN)
160                 *p = ramStartOffs + ramFileLen;
161 #else
162                 *p = bswap_32(ramStartOffs + ramFileLen);
163 #endif
164             }
165             put4k( outputVmlinux, inbuf );
166         }
167     }
168
169     {
170         for ( i=0; i<ramPages; ++i ) {
171             get4k( ramDisk, inbuf );
172             put4k( outputVmlinux, inbuf );
173         }
174     }
175
176
177     fclose(ramDisk);
178     fclose(inputVmlinux);
179     fclose(outputVmlinux);
180     /* Set permission to executable */
181     chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
182
183     return 0;
184
185 }
186