|
|
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.