These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / util / zbin.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <sys/stat.h>
7 #include <lzma.h>
8
9 #define DEBUG 0
10
11 /* LZMA filter choices.  Must match those used by unlzma.S */
12 #define LZMA_LC 2
13 #define LZMA_LP 0
14 #define LZMA_PB 0
15
16 /* LZMA preset choice.  This is a policy decision */
17 #define LZMA_PRESET ( LZMA_PRESET_DEFAULT | LZMA_PRESET_EXTREME )
18
19 struct input_file {
20         void *buf;
21         size_t len;
22 };
23
24 struct output_file {
25         void *buf;
26         size_t len;
27         size_t hdr_len;
28         size_t max_len;
29 };
30
31 struct zinfo_common {
32         char type[4];
33         char pad[12];
34 };
35
36 struct zinfo_copy {
37         char type[4];
38         uint32_t offset;
39         uint32_t len;
40         uint32_t align;
41 };
42
43 struct zinfo_pack {
44         char type[4];
45         uint32_t offset;
46         uint32_t len;
47         uint32_t align;
48 };
49
50 struct zinfo_payload {
51         char type[4];
52         uint32_t pad1;
53         uint32_t pad2;
54         uint32_t align;
55 };
56
57 struct zinfo_add {
58         char type[4];
59         uint32_t offset;
60         uint32_t divisor;
61         uint32_t pad;
62 };
63
64 union zinfo_record {
65         struct zinfo_common common;
66         struct zinfo_copy copy;
67         struct zinfo_pack pack;
68         struct zinfo_payload payload;
69         struct zinfo_add add;
70 };
71
72 struct zinfo_file {
73         union zinfo_record *zinfo;
74         unsigned int num_entries;
75 };
76
77 static unsigned long align ( unsigned long value, unsigned long align ) {
78         return ( ( value + align - 1 ) & ~( align - 1 ) );
79 }
80
81 static int read_file ( const char *filename, void **buf, size_t *len ) {
82         FILE *file;
83         struct stat stat;
84
85         file = fopen ( filename, "r" );
86         if ( ! file ) {
87                 fprintf ( stderr, "Could not open %s: %s\n", filename,
88                           strerror ( errno ) );
89                 goto err;
90         }
91
92         if ( fstat ( fileno ( file ), &stat ) < 0 ) {
93                 fprintf ( stderr, "Could not stat %s: %s\n", filename,
94                           strerror ( errno ) );
95                 goto err;
96         }
97
98         *len = stat.st_size;
99         *buf = malloc ( *len );
100         if ( ! *buf ) {
101                 fprintf ( stderr, "Could not malloc() %zd bytes for %s: %s\n",
102                           *len, filename, strerror ( errno ) );
103                 goto err;
104         }
105
106         if ( fread ( *buf, 1, *len, file ) != *len ) {
107                 fprintf ( stderr, "Could not read %zd bytes from %s: %s\n",
108                           *len, filename, strerror ( errno ) );
109                 goto err;
110         }
111
112         fclose ( file );
113         return 0;
114
115  err:
116         if ( file )
117                 fclose ( file );
118         return -1;
119 }
120
121 static int read_input_file ( const char *filename,
122                              struct input_file *input ) {
123         return read_file ( filename, &input->buf, &input->len );
124 }
125
126 static int read_zinfo_file ( const char *filename,
127                              struct zinfo_file *zinfo ) {
128         void *buf;
129         size_t len;
130
131         if ( read_file ( filename, &buf, &len ) < 0 )
132                 return -1;
133
134         if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) {
135                 fprintf ( stderr, ".zinfo file %s has invalid length %zd\n",
136                           filename, len );
137                 return -1;
138         }
139
140         zinfo->zinfo = buf;
141         zinfo->num_entries = ( len / sizeof ( *(zinfo->zinfo) ) );
142         return 0;
143 }
144
145 static int alloc_output_file ( size_t max_len, struct output_file *output ) {
146         output->len = 0;
147         output->max_len = ( max_len );
148         output->buf = malloc ( max_len );
149         if ( ! output->buf ) {
150                 fprintf ( stderr, "Could not allocate %zd bytes for output\n",
151                           max_len );
152                 return -1;
153         }
154         memset ( output->buf, 0xff, max_len );
155         return 0;
156 }
157
158 static int process_zinfo_copy ( struct input_file *input,
159                                 struct output_file *output,
160                                 union zinfo_record *zinfo ) {
161         struct zinfo_copy *copy = &zinfo->copy;
162         size_t offset = copy->offset;
163         size_t len = copy->len;
164
165         if ( ( offset + len ) > input->len ) {
166                 fprintf ( stderr, "Input buffer overrun on copy\n" );
167                 return -1;
168         }
169
170         output->len = align ( output->len, copy->align );
171         if ( ( output->len + len ) > output->max_len ) {
172                 fprintf ( stderr, "Output buffer overrun on copy\n" );
173                 return -1;
174         }
175
176         if ( DEBUG ) {
177                 fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n",
178                           offset, ( offset + len ), output->len,
179                           ( output->len + len ) );
180         }
181
182         memcpy ( ( output->buf + output->len ),
183                  ( input->buf + offset ), len );
184         output->len += len;
185         return 0;
186 }
187
188 #define OPCODE_CALL 0xe8
189 #define OPCODE_JMP 0xe9
190
191 static void bcj_filter ( void *data, size_t len ) {
192         struct {
193                 uint8_t opcode;
194                 int32_t target;
195         } __attribute__ (( packed )) *jump;
196         ssize_t limit = ( len - sizeof ( *jump ) );
197         ssize_t offset;
198
199         /* liblzma does include an x86 BCJ filter, but it's hideously
200          * convoluted and undocumented.  This BCJ filter is
201          * substantially simpler and achieves the same compression (at
202          * the cost of requiring the decompressor to know the size of
203          * the decompressed data, which we already have in iPXE).
204          */
205         for ( offset = 0 ; offset <= limit ; offset++ ) {
206                 jump = ( data + offset );
207
208                 /* Skip instructions that are not followed by a rel32 address */
209                 if ( ( jump->opcode != OPCODE_CALL ) &&
210                      ( jump->opcode != OPCODE_JMP ) )
211                         continue;
212
213                 /* Convert rel32 address to an absolute address.  To
214                  * avoid false positives (which damage the compression
215                  * ratio), we should check that the jump target is
216                  * within the range [0,limit).
217                  *
218                  * Some output values would then end up being mapped
219                  * from two distinct input values, making the
220                  * transformation irreversible.  To solve this, we
221                  * transform such values back into the part of the
222                  * range which would otherwise correspond to no input
223                  * values.
224                  */
225                 if ( ( jump->target >= -offset ) &&
226                      ( jump->target < ( limit - offset ) ) ) {
227                         /* Convert relative addresses in the range
228                          * [-offset,limit-offset) to absolute
229                          * addresses in the range [0,limit).
230                          */
231                         jump->target += offset;
232                 } else if ( ( jump->target >= ( limit - offset ) ) &&
233                             ( jump->target < limit ) ) {
234                         /* Convert positive numbers in the range
235                          * [limit-offset,limit) to negative numbers in
236                          * the range [-offset,0).
237                          */
238                         jump->target -= limit;
239                 }
240                 offset += sizeof ( jump->target );
241         };
242 }
243
244 static int process_zinfo_pack ( struct input_file *input,
245                                 struct output_file *output,
246                                 union zinfo_record *zinfo ) {
247         struct zinfo_pack *pack = &zinfo->pack;
248         size_t offset = pack->offset;
249         size_t len = pack->len;
250         size_t packed_len = 0;
251         size_t remaining = ( output->max_len - output->len );
252         lzma_options_lzma options;
253         const lzma_filter filters[] = {
254                 { .id = LZMA_FILTER_LZMA1, .options = &options },
255                 { .id = LZMA_VLI_UNKNOWN }
256         };
257
258         if ( ( offset + len ) > input->len ) {
259                 fprintf ( stderr, "Input buffer overrun on pack\n" );
260                 return -1;
261         }
262
263         output->len = align ( output->len, pack->align );
264         if ( output->len > output->max_len ) {
265                 fprintf ( stderr, "Output buffer overrun on pack\n" );
266                 return -1;
267         }
268
269         bcj_filter ( ( input->buf + offset ), len );
270
271         lzma_lzma_preset ( &options, LZMA_PRESET );
272         options.lc = LZMA_LC;
273         options.lp = LZMA_LP;
274         options.pb = LZMA_PB;
275         if ( lzma_raw_buffer_encode ( filters, NULL, ( input->buf + offset ),
276                                       len, ( output->buf + output->len ),
277                                       &packed_len, remaining ) != LZMA_OK ) {
278                 fprintf ( stderr, "Compression failure\n" );
279                 return -1;
280         }
281
282         if ( DEBUG ) {
283                 fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
284                           offset, ( offset + len ), output->len,
285                           ( output->len + packed_len ) );
286         }
287
288         output->len += packed_len;
289         if ( output->len > output->max_len ) {
290                 fprintf ( stderr, "Output buffer overrun on pack\n" );
291                 return -1;
292         }
293
294         return 0;
295 }
296
297 static int process_zinfo_payl ( struct input_file *input
298                                         __attribute__ (( unused )),
299                                 struct output_file *output,
300                                 union zinfo_record *zinfo ) {
301         struct zinfo_payload *payload = &zinfo->payload;
302
303         output->len = align ( output->len, payload->align );
304         output->hdr_len = output->len;
305
306         if ( DEBUG ) {
307                 fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len );
308         }
309         return 0;
310 }
311
312 static int process_zinfo_add ( struct input_file *input
313                                         __attribute__ (( unused )),
314                                struct output_file *output,
315                                size_t len,
316                                struct zinfo_add *add, size_t offset,
317                                size_t datasize ) {
318         void *target;
319         signed long addend;
320         unsigned long size;
321         signed long val;
322         unsigned long mask;
323
324         offset += add->offset;
325         if ( ( offset + datasize ) > output->len ) {
326                 fprintf ( stderr, "Add at %#zx outside output buffer\n",
327                           offset );
328                 return -1;
329         }
330
331         target = ( output->buf + offset );
332         size = ( align ( len, add->divisor ) / add->divisor );
333
334         switch ( datasize ) {
335         case 1:
336                 addend = *( ( int8_t * ) target );
337                 break;
338         case 2:
339                 addend = *( ( int16_t * ) target );
340                 break;
341         case 4:
342                 addend = *( ( int32_t * ) target );
343                 break;
344         default:
345                 fprintf ( stderr, "Unsupported add datasize %zd\n",
346                           datasize );
347                 return -1;
348         }
349
350         val = size + addend;
351
352         /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
353         mask = ( ( datasize < sizeof ( mask ) ) ?
354                  ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL );
355
356         if ( val < 0 ) {
357                 fprintf ( stderr, "Add %s%#x+%#lx at %#zx %sflows field\n",
358                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
359                           offset, ( ( addend < 0 ) ? "under" : "over" ) );
360                 return -1;
361         }
362
363         if ( val & ~mask ) {
364                 fprintf ( stderr, "Add %s%#x+%#lx at %#zx overflows %zd-byte "
365                           "field (%d bytes too big)\n",
366                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
367                           offset, datasize,
368                           ( int )( ( val - mask - 1 ) * add->divisor ) );
369                 return -1;
370         }
371
372         switch ( datasize ) {
373         case 1:
374                 *( ( uint8_t * ) target ) = val;
375                 break;
376         case 2:
377                 *( ( uint16_t * ) target ) = val;
378                 break;
379         case 4:
380                 *( ( uint32_t * ) target ) = val;
381                 break;
382         }
383
384         if ( DEBUG ) {
385                 fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
386                           "%#lx\n", offset, ( offset + datasize ),
387                           ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
388                           len, add->divisor, val );
389         }
390
391         return 0;
392 }
393
394 static int process_zinfo_addb ( struct input_file *input,
395                                 struct output_file *output,
396                                 union zinfo_record *zinfo ) {
397         return process_zinfo_add ( input, output, output->len,
398                                    &zinfo->add, 0, 1 );
399 }
400
401 static int process_zinfo_addw ( struct input_file *input,
402                                 struct output_file *output,
403                                 union zinfo_record *zinfo ) {
404         return process_zinfo_add ( input, output, output->len,
405                                    &zinfo->add, 0, 2 );
406 }
407
408 static int process_zinfo_addl ( struct input_file *input,
409                                 struct output_file *output,
410                                 union zinfo_record *zinfo ) {
411         return process_zinfo_add ( input, output, output->len,
412                                    &zinfo->add, 0, 4 );
413 }
414
415 static int process_zinfo_adhb ( struct input_file *input,
416                                 struct output_file *output,
417                                 union zinfo_record *zinfo ) {
418         return process_zinfo_add ( input, output, output->hdr_len,
419                                    &zinfo->add, 0, 1 );
420 }
421
422 static int process_zinfo_adhw ( struct input_file *input,
423                                 struct output_file *output,
424                                 union zinfo_record *zinfo ) {
425         return process_zinfo_add ( input, output, output->hdr_len,
426                                    &zinfo->add, 0, 2 );
427 }
428
429 static int process_zinfo_adhl ( struct input_file *input,
430                                 struct output_file *output,
431                                 union zinfo_record *zinfo ) {
432         return process_zinfo_add ( input, output, output->hdr_len,
433                                    &zinfo->add, 0, 4 );
434 }
435
436 static int process_zinfo_adpb ( struct input_file *input,
437                                 struct output_file *output,
438                                 union zinfo_record *zinfo ) {
439         return process_zinfo_add ( input, output,
440                                    ( output->len - output->hdr_len ),
441                                    &zinfo->add, 0, 1 );
442 }
443
444 static int process_zinfo_adpw ( struct input_file *input,
445                                 struct output_file *output,
446                                 union zinfo_record *zinfo ) {
447         return process_zinfo_add ( input, output,
448                                    ( output->len - output->hdr_len ),
449                                    &zinfo->add, 0, 2 );
450 }
451
452 static int process_zinfo_adpl ( struct input_file *input,
453                                 struct output_file *output,
454                                 union zinfo_record *zinfo ) {
455         return process_zinfo_add ( input, output,
456                                    ( output->len - output->hdr_len ),
457                                    &zinfo->add, 0, 4 );
458 }
459
460 static int process_zinfo_appb ( struct input_file *input,
461                                 struct output_file *output,
462                                 union zinfo_record *zinfo ) {
463         return process_zinfo_add ( input, output,
464                                    ( output->len - output->hdr_len ),
465                                    &zinfo->add, output->hdr_len, 1 );
466 }
467
468 static int process_zinfo_appw ( struct input_file *input,
469                                 struct output_file *output,
470                                 union zinfo_record *zinfo ) {
471         return process_zinfo_add ( input, output,
472                                    ( output->len - output->hdr_len ),
473                                    &zinfo->add, output->hdr_len, 2 );
474 }
475
476 static int process_zinfo_appl ( struct input_file *input,
477                                 struct output_file *output,
478                                 union zinfo_record *zinfo ) {
479         return process_zinfo_add ( input, output,
480                                    ( output->len - output->hdr_len ),
481                                    &zinfo->add, output->hdr_len, 4 );
482 }
483
484 struct zinfo_processor {
485         char *type;
486         int ( * process ) ( struct input_file *input,
487                             struct output_file *output,
488                             union zinfo_record *zinfo );
489 };
490
491 static struct zinfo_processor zinfo_processors[] = {
492         { "COPY", process_zinfo_copy },
493         { "PACK", process_zinfo_pack },
494         { "PAYL", process_zinfo_payl },
495         { "ADDB", process_zinfo_addb },
496         { "ADDW", process_zinfo_addw },
497         { "ADDL", process_zinfo_addl },
498         { "ADHB", process_zinfo_adhb },
499         { "ADHW", process_zinfo_adhw },
500         { "ADHL", process_zinfo_adhl },
501         { "ADPB", process_zinfo_adpb },
502         { "ADPW", process_zinfo_adpw },
503         { "ADPL", process_zinfo_adpl },
504         { "APPB", process_zinfo_appb },
505         { "APPW", process_zinfo_appw },
506         { "APPL", process_zinfo_appl },
507 };
508
509 static int process_zinfo ( struct input_file *input,
510                            struct output_file *output,
511                            union zinfo_record *zinfo ) {
512         struct zinfo_common *common = &zinfo->common;
513         struct zinfo_processor *processor;
514         char type[ sizeof ( common->type ) + 1 ] = "";
515         unsigned int i;
516
517         strncat ( type, common->type, sizeof ( type ) - 1 );
518         for ( i = 0 ; i < ( sizeof ( zinfo_processors ) /
519                             sizeof ( zinfo_processors[0] ) ) ; i++ ) {
520                 processor = &zinfo_processors[i];
521                 if ( strcmp ( processor->type, type ) == 0 )
522                         return processor->process ( input, output, zinfo );
523         }
524
525         fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] );
526         return -1;
527 }
528
529 static int write_output_file ( struct output_file *output ) {
530         if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
531                 fprintf ( stderr, "Could not write %zd bytes of output: %s\n",
532                           output->len, strerror ( errno ) );
533                 return -1;
534         }
535         return 0;
536 }
537
538 int main ( int argc, char **argv ) {
539         struct input_file input;
540         struct output_file output;
541         struct zinfo_file zinfo;
542         unsigned int i;
543
544         if ( argc != 3 ) {
545                 fprintf ( stderr, "Syntax: %s file.bin file.zinfo "
546                           "> file.zbin\n", argv[0] );
547                 exit ( 1 );
548         }
549
550         if ( read_input_file ( argv[1], &input ) < 0 )
551                 exit ( 1 );
552         if ( read_zinfo_file ( argv[2], &zinfo ) < 0 )
553                 exit ( 1 );
554         if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 )
555                 exit ( 1 );
556
557         for ( i = 0 ; i < zinfo.num_entries ; i++ ) {
558                 if ( process_zinfo ( &input, &output,
559                                      &zinfo.zinfo[i] ) < 0 )
560                         exit ( 1 );
561         }
562
563         if ( write_output_file ( &output ) < 0 )
564                 exit ( 1 );
565
566         return 0;
567 }