7 FILE *infile
, *outfile
;
42 struct zinfo_payload
{
57 struct zinfo_common common
;
58 struct zinfo_copy copy
;
59 struct zinfo_pack pack
;
60 struct zinfo_payload payload
;
65 union zinfo_record
*zinfo
;
66 unsigned int num_entries
;
69 static unsigned long align ( unsigned long value
, unsigned long align
) {
70 return ( ( value
+ align
- 1 ) & ~( align
- 1 ) );
73 static int read_file ( const char *filename
, void **buf
, size_t *len
) {
77 file
= fopen ( filename
, "r" );
79 fprintf ( stderr
, "Could not open %s: %s\n", filename
,
84 if ( fstat ( fileno ( file
), &stat
) < 0 ) {
85 fprintf ( stderr
, "Could not stat %s: %s\n", filename
,
91 *buf
= malloc ( *len
);
93 fprintf ( stderr
, "Could not malloc() %zd bytes for %s: %s\n",
94 *len
, filename
, strerror ( errno
) );
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
) );
113 static int read_input_file ( const char *filename
,
114 struct input_file
*input
) {
115 return read_file ( filename
, &input
->buf
, &input
->len
);
118 static int read_zinfo_file ( const char *filename
,
119 struct zinfo_file
*zinfo
) {
123 if ( read_file ( filename
, &buf
, &len
) < 0 )
126 if ( ( len
% sizeof ( *(zinfo
->zinfo
) ) ) != 0 ) {
127 fprintf ( stderr
, ".zinfo file %s has invalid length %zd\n",
133 zinfo
->num_entries
= ( len
/ sizeof ( *(zinfo
->zinfo
) ) );
137 static int alloc_output_file ( size_t max_len
, struct output_file
*output
) {
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",
146 memset ( output
->buf
, 0xff, sizeof ( output
->buf
) );
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
;
157 if ( ( offset
+ len
) > input
->len
) {
158 fprintf ( stderr
, "Input buffer overrun on copy\n" );
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" );
169 fprintf ( stderr
, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n",
170 offset
, ( offset
+ len
), output
->len
,
171 ( output
->len
+ len
) );
174 memcpy ( ( output
->buf
+ output
->len
),
175 ( input
->buf
+ offset
), len
);
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
;
188 if ( ( offset
+ len
) > input
->len
) {
189 fprintf ( stderr
, "Input buffer overrun on pack\n" );
193 output
->len
= align ( output
->len
, pack
->align
);
194 if ( output
->len
> output
->max_len
) {
195 fprintf ( stderr
, "Output buffer overrun on pack\n" );
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" );
207 fprintf ( stderr
, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
208 offset
, ( offset
+ len
), output
->len
,
209 ( size_t )( output
->len
+ packed_len
) );
212 output
->len
+= packed_len
;
213 if ( output
->len
> output
->max_len
) {
214 fprintf ( stderr
, "Output buffer overrun on pack\n" );
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
;
226 output
->len
= align ( output
->len
, payload
->align
);
227 output
->hdr_len
= output
->len
;
230 fprintf ( stderr
, "PAYL at %#zx\n", output
->hdr_len
);
234 static int process_zinfo_add ( struct input_file
*input
,
235 struct output_file
*output
,
237 struct zinfo_add
*add
,
239 size_t offset
= add
->offset
;
246 if ( ( offset
+ datasize
) > output
->len
) {
247 fprintf ( stderr
, "Add at %#zx outside output buffer\n",
252 target
= ( output
->buf
+ offset
);
253 size
= ( align ( len
, add
->divisor
) / add
->divisor
);
255 switch ( datasize
) {
257 addend
= *( ( int8_t * ) target
);
260 addend
= *( ( int16_t * ) target
);
263 addend
= *( ( int32_t * ) target
);
266 fprintf ( stderr
, "Unsupported add datasize %zd\n",
273 /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
274 mask
= ( ( datasize
< sizeof ( mask
) ) ?
275 ( ( 1UL << ( 8 * datasize
) ) - 1 ) : ~0UL );
278 fprintf ( stderr
, "Add %s%#x+%#lx at %#zx %sflows field\n",
279 ( ( addend
< 0 ) ? "-" : "" ), abs ( addend
), size
,
280 offset
, ( ( addend
< 0 ) ? "under" : "over" ) );
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
,
289 ( int )( ( val
- mask
- 1 ) * add
->divisor
) );
293 switch ( datasize
) {
295 *( ( uint8_t * ) target
) = val
;
298 *( ( uint16_t * ) target
) = val
;
301 *( ( uint32_t * ) target
) = val
;
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
);
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
,
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
,
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
,
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
,
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
,
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
,
357 struct zinfo_processor
{
359 int ( * process
) ( struct input_file
*input
,
360 struct output_file
*output
,
361 union zinfo_record
*zinfo
);
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
},
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 ] = "";
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
);
392 fprintf ( stderr
, "Unknown zinfo record type \"%s\"\n", &type
[0] );
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
) );
405 int main ( int argc
, char **argv
) {
406 struct input_file input
;
407 struct output_file output
;
408 struct zinfo_file zinfo
;
412 fprintf ( stderr
, "Syntax: %s file.bin file.zinfo "
413 "> file.zbin\n", argv
[0] );
417 if ( read_input_file ( argv
[1], &input
) < 0 )
419 if ( read_zinfo_file ( argv
[2], &zinfo
) < 0 )
421 if ( alloc_output_file ( ( input
.len
* 4 ), &output
) < 0 )
424 for ( i
= 0 ; i
< zinfo
.num_entries
; i
++ ) {
425 if ( process_zinfo ( &input
, &output
,
426 &zinfo
.zinfo
[i
] ) < 0 )
430 if ( write_output_file ( &output
) < 0 )