Annotation of qemu/roms/ipxe/src/util/zbin.c, revision 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.