|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.