Annotation of qemu/roms/ipxe/src/util/zbin.c, revision 1.1.1.1

1.1       root        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, sizeof ( output->buf ) );
                    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:                                struct output_file *output,
                    223:                                union zinfo_record *zinfo ) {
                    224:        struct zinfo_payload *payload = &zinfo->payload;
                    225: 
                    226:        output->len = align ( output->len, payload->align );
                    227:        output->hdr_len = output->len;
                    228: 
                    229:        if ( DEBUG ) {
                    230:                fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len );
                    231:        }
                    232: }
                    233: 
                    234: static int process_zinfo_add ( struct input_file *input,
                    235:                               struct output_file *output,
                    236:                               size_t len,
                    237:                               struct zinfo_add *add,
                    238:                               size_t datasize ) {
                    239:        size_t offset = add->offset;
                    240:        void *target;
                    241:        signed long addend;
                    242:        unsigned long size;
                    243:        signed long val;
                    244:        unsigned long mask;
                    245: 
                    246:        if ( ( offset + datasize ) > output->len ) {
                    247:                fprintf ( stderr, "Add at %#zx outside output buffer\n",
                    248:                          offset );
                    249:                return -1;
                    250:        }
                    251: 
                    252:        target = ( output->buf + offset );
                    253:        size = ( align ( len, add->divisor ) / add->divisor );
                    254: 
                    255:        switch ( datasize ) {
                    256:        case 1:
                    257:                addend = *( ( int8_t * ) target );
                    258:                break;
                    259:        case 2:
                    260:                addend = *( ( int16_t * ) target );
                    261:                break;
                    262:        case 4:
                    263:                addend = *( ( int32_t * ) target );
                    264:                break;
                    265:        default:
                    266:                fprintf ( stderr, "Unsupported add datasize %zd\n",
                    267:                          datasize );
                    268:                return -1;
                    269:        }
                    270: 
                    271:        val = size + addend;
                    272: 
                    273:        /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
                    274:        mask = ( ( datasize < sizeof ( mask ) ) ?
                    275:                 ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL );
                    276: 
                    277:        if ( val < 0 ) {
                    278:                fprintf ( stderr, "Add %s%#x+%#lx at %#zx %sflows field\n",
                    279:                          ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
                    280:                          offset, ( ( addend < 0 ) ? "under" : "over" ) );
                    281:                return -1;
                    282:        }
                    283: 
                    284:        if ( val & ~mask ) {
                    285:                fprintf ( stderr, "Add %s%#x+%#lx at %#zx overflows %zd-byte "
                    286:                          "field (%d bytes too big)\n",
                    287:                          ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
                    288:                          offset, datasize,
                    289:                          ( int )( ( val - mask - 1 ) * add->divisor ) );
                    290:                return -1;
                    291:        }
                    292: 
                    293:        switch ( datasize ) {
                    294:        case 1:
                    295:                *( ( uint8_t * ) target ) = val;
                    296:                break;
                    297:        case 2:
                    298:                *( ( uint16_t * ) target ) = val;
                    299:                break;
                    300:        case 4:
                    301:                *( ( uint32_t * ) target ) = val;
                    302:                break;
                    303:        }
                    304: 
                    305:        if ( DEBUG ) {
                    306:                fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
                    307:                          "%#lx\n", offset, ( offset + datasize ),
                    308:                          ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
                    309:                          len, add->divisor, val );
                    310:        }
                    311: 
                    312:        return 0;
                    313: }
                    314: 
                    315: static int process_zinfo_addb ( struct input_file *input,
                    316:                                struct output_file *output,
                    317:                                union zinfo_record *zinfo ) {
                    318:        return process_zinfo_add ( input, output, output->len,
                    319:                                   &zinfo->add, 1 );
                    320: }
                    321: 
                    322: static int process_zinfo_addw ( struct input_file *input,
                    323:                                struct output_file *output,
                    324:                                union zinfo_record *zinfo ) {
                    325:        return process_zinfo_add ( input, output, output->len,
                    326:                                   &zinfo->add, 2 );
                    327: }
                    328: 
                    329: static int process_zinfo_addl ( struct input_file *input,
                    330:                                struct output_file *output,
                    331:                                union zinfo_record *zinfo ) {
                    332:        return process_zinfo_add ( input, output, output->len,
                    333:                                   &zinfo->add, 4 );
                    334: }
                    335: 
                    336: static int process_zinfo_adhb ( struct input_file *input,
                    337:                                struct output_file *output,
                    338:                                union zinfo_record *zinfo ) {
                    339:        return process_zinfo_add ( input, output, output->hdr_len,
                    340:                                   &zinfo->add, 1 );
                    341: }
                    342: 
                    343: static int process_zinfo_adhw ( struct input_file *input,
                    344:                                struct output_file *output,
                    345:                                union zinfo_record *zinfo ) {
                    346:        return process_zinfo_add ( input, output, output->hdr_len,
                    347:                                   &zinfo->add, 2 );
                    348: }
                    349: 
                    350: static int process_zinfo_adhl ( struct input_file *input,
                    351:                                struct output_file *output,
                    352:                                union zinfo_record *zinfo ) {
                    353:        return process_zinfo_add ( input, output, output->hdr_len,
                    354:                                   &zinfo->add, 4 );
                    355: }
                    356: 
                    357: struct zinfo_processor {
                    358:        char *type;
                    359:        int ( * process ) ( struct input_file *input,
                    360:                            struct output_file *output,
                    361:                            union zinfo_record *zinfo );
                    362: };
                    363: 
                    364: static struct zinfo_processor zinfo_processors[] = {
                    365:        { "COPY", process_zinfo_copy },
                    366:        { "PACK", process_zinfo_pack },
                    367:        { "PAYL", process_zinfo_payl },
                    368:        { "ADDB", process_zinfo_addb },
                    369:        { "ADDW", process_zinfo_addw },
                    370:        { "ADDL", process_zinfo_addl },
                    371:        { "ADHB", process_zinfo_adhb },
                    372:        { "ADHW", process_zinfo_adhw },
                    373:        { "ADHL", process_zinfo_adhl },
                    374: };
                    375: 
                    376: static int process_zinfo ( struct input_file *input,
                    377:                           struct output_file *output,
                    378:                           union zinfo_record *zinfo ) {
                    379:        struct zinfo_common *common = &zinfo->common;
                    380:        struct zinfo_processor *processor;
                    381:        char type[ sizeof ( common->type ) + 1 ] = "";
                    382:        unsigned int i;
                    383: 
                    384:        strncat ( type, common->type, sizeof ( type ) - 1 );
                    385:        for ( i = 0 ; i < ( sizeof ( zinfo_processors ) /
                    386:                            sizeof ( zinfo_processors[0] ) ) ; i++ ) {
                    387:                processor = &zinfo_processors[i];
                    388:                if ( strcmp ( processor->type, type ) == 0 )
                    389:                        return processor->process ( input, output, zinfo );
                    390:        }
                    391: 
                    392:        fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] );
                    393:        return -1;
                    394: }
                    395: 
                    396: static int write_output_file ( struct output_file *output ) {
                    397:        if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
                    398:                fprintf ( stderr, "Could not write %zd bytes of output: %s\n",
                    399:                          output->len, strerror ( errno ) );
                    400:                return -1;
                    401:        }
                    402:        return 0;
                    403: }
                    404: 
                    405: int main ( int argc, char **argv ) {
                    406:        struct input_file input;
                    407:        struct output_file output;
                    408:        struct zinfo_file zinfo;
                    409:        unsigned int i;
                    410: 
                    411:        if ( argc != 3 ) {
                    412:                fprintf ( stderr, "Syntax: %s file.bin file.zinfo "
                    413:                          "> file.zbin\n", argv[0] );
                    414:                exit ( 1 );
                    415:        }
                    416: 
                    417:        if ( read_input_file ( argv[1], &input ) < 0 )
                    418:                exit ( 1 );
                    419:        if ( read_zinfo_file ( argv[2], &zinfo ) < 0 )
                    420:                exit ( 1 );
                    421:        if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 )
                    422:                exit ( 1 );
                    423: 
                    424:        for ( i = 0 ; i < zinfo.num_entries ; i++ ) {
                    425:                if ( process_zinfo ( &input, &output,
                    426:                                     &zinfo.zinfo[i] ) < 0 )
                    427:                        exit ( 1 );
                    428:        }
                    429: 
                    430:        if ( write_output_file ( &output ) < 0 )
                    431:                exit ( 1 );
                    432: 
                    433:        return 0;
                    434: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.