Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / util / zbin.c
1 #include <stdio.h>
2 #include <sys/stat.h>
3
4 #define ENCODE
5 #define VERBOSE
6 #include "nrv2b.c"
7 FILE *infile, *outfile;
8
9 #define DEBUG 0
10
11 struct input_file {
12         void *buf;
13         size_t len;
14 };
15
16 struct output_file {
17         void *buf;
18         size_t len;
19         size_t hdr_len;
20         size_t max_len;
21 };
22
23 struct zinfo_common {
24         char type[4];
25         char pad[12];
26 };
27
28 struct zinfo_copy {
29         char type[4];
30         uint32_t offset;
31         uint32_t len;
32         uint32_t align;
33 };
34
35 struct zinfo_pack {
36         char type[4];
37         uint32_t offset;
38         uint32_t len;
39         uint32_t align;
40 };
41
42 struct zinfo_payload {
43         char type[4];
44         uint32_t pad1;
45         uint32_t pad2;
46         uint32_t align;
47 };
48
49 struct zinfo_add {
50         char type[4];
51         uint32_t offset;
52         uint32_t divisor;
53         uint32_t pad;
54 };
55
56 union zinfo_record {
57         struct zinfo_common common;
58         struct zinfo_copy copy;
59         struct zinfo_pack pack;
60         struct zinfo_payload payload;
61         struct zinfo_add add;
62 };
63
64 struct zinfo_file {
65         union zinfo_record *zinfo;
66         unsigned int num_entries;
67 };
68
69 static unsigned long align ( unsigned long value, unsigned long align ) {
70         return ( ( value + align - 1 ) & ~( align - 1 ) );
71 }
72
73 static int read_file ( const char *filename, void **buf, size_t *len ) {
74         FILE *file;
75         struct stat stat;
76
77         file = fopen ( filename, "r" );
78         if ( ! file ) {
79                 fprintf ( stderr, "Could not open %s: %s\n", filename,
80                           strerror ( errno ) );
81                 goto err;
82         }
83
84         if ( fstat ( fileno ( file ), &stat ) < 0 ) {
85                 fprintf ( stderr, "Could not stat %s: %s\n", filename,
86                           strerror ( errno ) );
87                 goto err;
88         }
89
90         *len = stat.st_size;
91         *buf = malloc ( *len );
92         if ( ! *buf ) {
93                 fprintf ( stderr, "Could not malloc() %zd bytes for %s: %s\n",
94                           *len, filename, strerror ( errno ) );
95                 goto err;
96         }
97
98         if ( fread ( *buf, 1, *len, file ) != *len ) {
99                 fprintf ( stderr, "Could not read %zd bytes from %s: %s\n",
100                           *len, filename, strerror ( errno ) );
101                 goto err;
102         }
103
104         fclose ( file );
105         return 0;
106
107  err:
108         if ( file )
109                 fclose ( file );
110         return -1;
111 }
112
113 static int read_input_file ( const char *filename,
114                              struct input_file *input ) {
115         return read_file ( filename, &input->buf, &input->len );
116 }
117
118 static int read_zinfo_file ( const char *filename,
119                              struct zinfo_file *zinfo ) {
120         void *buf;
121         size_t len;
122
123         if ( read_file ( filename, &buf, &len ) < 0 )
124                 return -1;
125
126         if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) {
127                 fprintf ( stderr, ".zinfo file %s has invalid length %zd\n",
128                           filename, len );
129                 return -1;
130         }
131
132         zinfo->zinfo = buf;
133         zinfo->num_entries = ( len / sizeof ( *(zinfo->zinfo) ) );
134         return 0;
135 }
136
137 static int alloc_output_file ( size_t max_len, struct output_file *output ) {
138         output->len = 0;
139         output->max_len = ( max_len );
140         output->buf = malloc ( max_len );
141         if ( ! output->buf ) {
142                 fprintf ( stderr, "Could not allocate %zd bytes for output\n",
143                           max_len );
144                 return -1;
145         }
146         memset ( output->buf, 0xff, max_len );
147         return 0;
148 }
149
150 static int process_zinfo_copy ( struct input_file *input,
151                                 struct output_file *output,
152                                 union zinfo_record *zinfo ) {
153         struct zinfo_copy *copy = &zinfo->copy;
154         size_t offset = copy->offset;
155         size_t len = copy->len;
156
157         if ( ( offset + len ) > input->len ) {
158                 fprintf ( stderr, "Input buffer overrun on copy\n" );
159                 return -1;
160         }
161
162         output->len = align ( output->len, copy->align );
163         if ( ( output->len + len ) > output->max_len ) {
164                 fprintf ( stderr, "Output buffer overrun on copy\n" );
165                 return -1;
166         }
167
168         if ( DEBUG ) {
169                 fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n",
170                           offset, ( offset + len ), output->len,
171                           ( output->len + len ) );
172         }
173
174         memcpy ( ( output->buf + output->len ),
175                  ( input->buf + offset ), len );
176         output->len += len;
177         return 0;
178 }
179
180 static int process_zinfo_pack ( struct input_file *input,
181                                 struct output_file *output,
182                                 union zinfo_record *zinfo ) {
183         struct zinfo_pack *pack = &zinfo->pack;
184         size_t offset = pack->offset;
185         size_t len = pack->len;
186         unsigned long packed_len;
187
188         if ( ( offset + len ) > input->len ) {
189                 fprintf ( stderr, "Input buffer overrun on pack\n" );
190                 return -1;
191         }
192
193         output->len = align ( output->len, pack->align );
194         if ( output->len > output->max_len ) {
195                 fprintf ( stderr, "Output buffer overrun on pack\n" );
196                 return -1;
197         }
198
199         if ( ucl_nrv2b_99_compress ( ( input->buf + offset ), len,
200                                      ( output->buf + output->len ),
201                                      &packed_len, 0 ) != UCL_E_OK ) {
202                 fprintf ( stderr, "Compression failure\n" );
203                 return -1;
204         }
205
206         if ( DEBUG ) {
207                 fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
208                           offset, ( offset + len ), output->len,
209                           ( size_t )( output->len + packed_len ) );
210         }
211
212         output->len += packed_len;
213         if ( output->len > output->max_len ) {
214                 fprintf ( stderr, "Output buffer overrun on pack\n" );
215                 return -1;
216         }
217
218         return 0;
219 }
220
221 static int process_zinfo_payl ( struct input_file *input
222                                         __attribute__ (( unused )),
223                                 struct output_file *output,
224                                 union zinfo_record *zinfo ) {
225         struct zinfo_payload *payload = &zinfo->payload;
226
227         output->len = align ( output->len, payload->align );
228         output->hdr_len = output->len;
229
230         if ( DEBUG ) {
231                 fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len );
232         }
233         return 0;
234 }
235
236 static int process_zinfo_add ( struct input_file *input
237                                         __attribute__ (( unused )),
238                                struct output_file *output,
239                                size_t len,
240                                struct zinfo_add *add, size_t offset,
241                                size_t datasize ) {
242         void *target;
243         signed long addend;
244         unsigned long size;
245         signed long val;
246         unsigned long mask;
247
248         offset += add->offset;
249         if ( ( offset + datasize ) > output->len ) {
250                 fprintf ( stderr, "Add at %#zx outside output buffer\n",
251                           offset );
252                 return -1;
253         }
254
255         target = ( output->buf + offset );
256         size = ( align ( len, add->divisor ) / add->divisor );
257
258         switch ( datasize ) {
259         case 1:
260                 addend = *( ( int8_t * ) target );
261                 break;
262         case 2:
263                 addend = *( ( int16_t * ) target );
264                 break;
265         case 4:
266                 addend = *( ( int32_t * ) target );
267                 break;
268         default:
269                 fprintf ( stderr, "Unsupported add datasize %zd\n",
270                           datasize );
271                 return -1;
272         }
273
274         val = size + addend;
275
276         /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
277         mask = ( ( datasize < sizeof ( mask ) ) ?
278                  ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL );
279
280         if ( val < 0 ) {
281                 fprintf ( stderr, "Add %s%#x+%#lx at %#zx %sflows field\n",
282                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
283                           offset, ( ( addend < 0 ) ? "under" : "over" ) );
284                 return -1;
285         }
286
287         if ( val & ~mask ) {
288                 fprintf ( stderr, "Add %s%#x+%#lx at %#zx overflows %zd-byte "
289                           "field (%d bytes too big)\n",
290                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
291                           offset, datasize,
292                           ( int )( ( val - mask - 1 ) * add->divisor ) );
293                 return -1;
294         }
295
296         switch ( datasize ) {
297         case 1:
298                 *( ( uint8_t * ) target ) = val;
299                 break;
300         case 2:
301                 *( ( uint16_t * ) target ) = val;
302                 break;
303         case 4:
304                 *( ( uint32_t * ) target ) = val;
305                 break;
306         }
307
308         if ( DEBUG ) {
309                 fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
310                           "%#lx\n", offset, ( offset + datasize ),
311                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
312                           len, add->divisor, val );
313         }
314
315         return 0;
316 }
317
318 static int process_zinfo_addb ( struct input_file *input,
319                                 struct output_file *output,
320                                 union zinfo_record *zinfo ) {
321         return process_zinfo_add ( input, output, output->len,
322                                    &zinfo->add, 0, 1 );
323 }
324
325 static int process_zinfo_addw ( struct input_file *input,
326                                 struct output_file *output,
327                                 union zinfo_record *zinfo ) {
328         return process_zinfo_add ( input, output, output->len,
329                                    &zinfo->add, 0, 2 );
330 }
331
332 static int process_zinfo_addl ( struct input_file *input,
333                                 struct output_file *output,
334                                 union zinfo_record *zinfo ) {
335         return process_zinfo_add ( input, output, output->len,
336                                    &zinfo->add, 0, 4 );
337 }
338
339 static int process_zinfo_adhb ( struct input_file *input,
340                                 struct output_file *output,
341                                 union zinfo_record *zinfo ) {
342         return process_zinfo_add ( input, output, output->hdr_len,
343                                    &zinfo->add, 0, 1 );
344 }
345
346 static int process_zinfo_adhw ( struct input_file *input,
347                                 struct output_file *output,
348                                 union zinfo_record *zinfo ) {
349         return process_zinfo_add ( input, output, output->hdr_len,
350                                    &zinfo->add, 0, 2 );
351 }
352
353 static int process_zinfo_adhl ( struct input_file *input,
354                                 struct output_file *output,
355                                 union zinfo_record *zinfo ) {
356         return process_zinfo_add ( input, output, output->hdr_len,
357                                    &zinfo->add, 0, 4 );
358 }
359
360 static int process_zinfo_adpb ( struct input_file *input,
361                                 struct output_file *output,
362                                 union zinfo_record *zinfo ) {
363         return process_zinfo_add ( input, output,
364                                    ( output->len - output->hdr_len ),
365                                    &zinfo->add, 0, 1 );
366 }
367
368 static int process_zinfo_adpw ( struct input_file *input,
369                                 struct output_file *output,
370                                 union zinfo_record *zinfo ) {
371         return process_zinfo_add ( input, output,
372                                    ( output->len - output->hdr_len ),
373                                    &zinfo->add, 0, 2 );
374 }
375
376 static int process_zinfo_adpl ( struct input_file *input,
377                                 struct output_file *output,
378                                 union zinfo_record *zinfo ) {
379         return process_zinfo_add ( input, output,
380                                    ( output->len - output->hdr_len ),
381                                    &zinfo->add, 0, 4 );
382 }
383
384 static int process_zinfo_appb ( struct input_file *input,
385                                 struct output_file *output,
386                                 union zinfo_record *zinfo ) {
387         return process_zinfo_add ( input, output,
388                                    ( output->len - output->hdr_len ),
389                                    &zinfo->add, output->hdr_len, 1 );
390 }
391
392 static int process_zinfo_appw ( struct input_file *input,
393                                 struct output_file *output,
394                                 union zinfo_record *zinfo ) {
395         return process_zinfo_add ( input, output,
396                                    ( output->len - output->hdr_len ),
397                                    &zinfo->add, output->hdr_len, 2 );
398 }
399
400 static int process_zinfo_appl ( struct input_file *input,
401                                 struct output_file *output,
402                                 union zinfo_record *zinfo ) {
403         return process_zinfo_add ( input, output,
404                                    ( output->len - output->hdr_len ),
405                                    &zinfo->add, output->hdr_len, 4 );
406 }
407
408 struct zinfo_processor {
409         char *type;
410         int ( * process ) ( struct input_file *input,
411                             struct output_file *output,
412                             union zinfo_record *zinfo );
413 };
414
415 static struct zinfo_processor zinfo_processors[] = {
416         { "COPY", process_zinfo_copy },
417         { "PACK", process_zinfo_pack },
418         { "PAYL", process_zinfo_payl },
419         { "ADDB", process_zinfo_addb },
420         { "ADDW", process_zinfo_addw },
421         { "ADDL", process_zinfo_addl },
422         { "ADHB", process_zinfo_adhb },
423         { "ADHW", process_zinfo_adhw },
424         { "ADHL", process_zinfo_adhl },
425         { "ADPB", process_zinfo_adpb },
426         { "ADPW", process_zinfo_adpw },
427         { "ADPL", process_zinfo_adpl },
428         { "APPB", process_zinfo_appb },
429         { "APPW", process_zinfo_appw },
430         { "APPL", process_zinfo_appl },
431 };
432
433 static int process_zinfo ( struct input_file *input,
434                            struct output_file *output,
435                            union zinfo_record *zinfo ) {
436         struct zinfo_common *common = &zinfo->common;
437         struct zinfo_processor *processor;
438         char type[ sizeof ( common->type ) + 1 ] = "";
439         unsigned int i;
440
441         strncat ( type, common->type, sizeof ( type ) - 1 );
442         for ( i = 0 ; i < ( sizeof ( zinfo_processors ) /
443                             sizeof ( zinfo_processors[0] ) ) ; i++ ) {
444                 processor = &zinfo_processors[i];
445                 if ( strcmp ( processor->type, type ) == 0 )
446                         return processor->process ( input, output, zinfo );
447         }
448
449         fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] );
450         return -1;
451 }
452
453 static int write_output_file ( struct output_file *output ) {
454         if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
455                 fprintf ( stderr, "Could not write %zd bytes of output: %s\n",
456                           output->len, strerror ( errno ) );
457                 return -1;
458         }
459         return 0;
460 }
461
462 int main ( int argc, char **argv ) {
463         struct input_file input;
464         struct output_file output;
465         struct zinfo_file zinfo;
466         unsigned int i;
467
468         if ( argc != 3 ) {
469                 fprintf ( stderr, "Syntax: %s file.bin file.zinfo "
470                           "> file.zbin\n", argv[0] );
471                 exit ( 1 );
472         }
473
474         if ( read_input_file ( argv[1], &input ) < 0 )
475                 exit ( 1 );
476         if ( read_zinfo_file ( argv[2], &zinfo ) < 0 )
477                 exit ( 1 );
478         if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 )
479                 exit ( 1 );
480
481         for ( i = 0 ; i < zinfo.num_entries ; i++ ) {
482                 if ( process_zinfo ( &input, &output,
483                                      &zinfo.zinfo[i] ) < 0 )
484                         exit ( 1 );
485         }
486
487         if ( write_output_file ( &output ) < 0 )
488                 exit ( 1 );
489
490         return 0;
491 }