7 FILE *infile
, *outfile
;
39 struct zinfo_subtract
{
47 struct zinfo_common common
;
48 struct zinfo_copy copy
;
49 struct zinfo_pack pack
;
50 struct zinfo_subtract subtract
;
54 union zinfo_record
*zinfo
;
55 unsigned int num_entries
;
58 static int read_file ( const char *filename
, void **buf
, size_t *len
) {
62 file
= fopen ( filename
, "r" );
64 fprintf ( stderr
, "Could not open %s: %s\n", filename
,
69 if ( fstat ( fileno ( file
), &stat
) < 0 ) {
70 fprintf ( stderr
, "Could not stat %s: %s\n", filename
,
76 *buf
= malloc ( *len
);
78 fprintf ( stderr
, "Could not malloc() %d bytes for %s: %s\n",
79 *len
, filename
, strerror ( errno
) );
83 if ( fread ( *buf
, 1, *len
, file
) != *len
) {
84 fprintf ( stderr
, "Could not read %d bytes from %s: %s\n",
85 *len
, filename
, strerror ( errno
) );
97 static int read_input_file ( const char *filename
,
98 struct input_file
*input
) {
99 return read_file ( filename
, &input
->buf
, &input
->len
);
102 static int read_zinfo_file ( const char *filename
,
103 struct zinfo_file
*zinfo
) {
107 if ( read_file ( filename
, &buf
, &len
) < 0 )
110 if ( ( len
% sizeof ( *(zinfo
->zinfo
) ) ) != 0 ) {
111 fprintf ( stderr
, ".zinfo file %s has invalid length %d\n",
117 zinfo
->num_entries
= ( len
/ sizeof ( *(zinfo
->zinfo
) ) );
121 static int alloc_output_file ( size_t max_len
, struct output_file
*output
) {
123 output
->max_len
= ( max_len
);
124 output
->buf
= malloc ( max_len
);
125 if ( ! output
->buf
) {
126 fprintf ( stderr
, "Could not allocate %d bytes for output\n",
130 memset ( output
->buf
, 0xff, sizeof ( output
->buf
) );
134 static int process_zinfo_copy ( struct input_file
*input
,
135 struct output_file
*output
,
136 union zinfo_record
*zinfo
) {
137 struct zinfo_copy
*copy
= &zinfo
->copy
;
138 size_t offset
= copy
->offset
;
139 size_t len
= copy
->len
;
140 unsigned int align
= copy
->align
;
142 if ( ( offset
+ len
) > input
->len
) {
143 fprintf ( stderr
, "Input buffer overrun on copy\n" );
147 output
->len
= ( ( output
->len
+ align
- 1 ) & ~( align
- 1 ) );
148 if ( ( output
->len
+ len
) > output
->max_len
) {
149 fprintf ( stderr
, "Output buffer overrun on copy\n" );
153 memcpy ( ( output
->buf
+ output
->len
),
154 ( input
->buf
+ offset
), len
);
159 static int process_zinfo_pack ( struct input_file
*input
,
160 struct output_file
*output
,
161 union zinfo_record
*zinfo
) {
162 struct zinfo_pack
*pack
= &zinfo
->pack
;
163 size_t offset
= pack
->offset
;
164 size_t len
= pack
->len
;
165 unsigned int align
= pack
->align
;
166 unsigned long packed_len
;
168 if ( ( offset
+ len
) > input
->len
) {
169 fprintf ( stderr
, "Input buffer overrun on pack\n" );
173 output
->len
= ( ( output
->len
+ align
- 1 ) & ~( align
- 1 ) );
174 if ( output
->len
> output
->max_len
) {
175 fprintf ( stderr
, "Output buffer overrun on pack\n" );
179 if ( ucl_nrv2b_99_compress ( ( input
->buf
+ offset
), len
,
180 ( output
->buf
+ output
->len
),
181 &packed_len
, 0 ) != UCL_E_OK
) {
182 fprintf ( stderr
, "Compression failure\n" );
186 output
->len
+= packed_len
;
187 if ( output
->len
> output
->max_len
) {
188 fprintf ( stderr
, "Output buffer overrun on pack\n" );
195 static int process_zinfo_subtract ( struct input_file
*input
,
196 struct output_file
*output
,
197 struct zinfo_subtract
*subtract
,
199 size_t offset
= subtract
->offset
;
203 if ( ( offset
+ datasize
) > output
->len
) {
204 fprintf ( stderr
, "Subtract at %#zx outside output buffer\n",
209 target
= ( output
->buf
+ offset
);
210 delta
= ( ( output
->len
/ subtract
->divisor
) -
211 ( input
->len
/ subtract
->divisor
) );
213 switch ( datasize
) {
215 uint8_t *byte
= target
;
219 uint16_t *word
= target
;
223 uint32_t *dword
= target
;
227 fprintf ( stderr
, "Unsupported subtract datasize %d\n",
234 static int process_zinfo_subb ( struct input_file
*input
,
235 struct output_file
*output
,
236 union zinfo_record
*zinfo
) {
237 return process_zinfo_subtract ( input
, output
, &zinfo
->subtract
, 1 );
240 static int process_zinfo_subw ( struct input_file
*input
,
241 struct output_file
*output
,
242 union zinfo_record
*zinfo
) {
243 return process_zinfo_subtract ( input
, output
, &zinfo
->subtract
, 2 );
246 static int process_zinfo_subl ( struct input_file
*input
,
247 struct output_file
*output
,
248 union zinfo_record
*zinfo
) {
249 return process_zinfo_subtract ( input
, output
, &zinfo
->subtract
, 4 );
252 struct zinfo_processor
{
254 int ( * process
) ( struct input_file
*input
,
255 struct output_file
*output
,
256 union zinfo_record
*zinfo
);
259 static struct zinfo_processor zinfo_processors
[] = {
260 { "COPY", process_zinfo_copy
},
261 { "PACK", process_zinfo_pack
},
262 { "SUBB", process_zinfo_subb
},
263 { "SUBW", process_zinfo_subw
},
264 { "SUBL", process_zinfo_subl
},
267 static int process_zinfo ( struct input_file
*input
,
268 struct output_file
*output
,
269 union zinfo_record
*zinfo
) {
270 struct zinfo_common
*common
= &zinfo
->common
;
271 struct zinfo_processor
*processor
;
272 char type
[ sizeof ( common
->type
) + 1 ] = "";
275 strncat ( type
, common
->type
, sizeof ( type
) - 1 );
276 for ( i
= 0 ; i
< ( sizeof ( zinfo_processors
) /
277 sizeof ( zinfo_processors
[0] ) ) ; i
++ ) {
278 processor
= &zinfo_processors
[i
];
279 if ( strcmp ( processor
->type
, type
) == 0 )
280 return processor
->process ( input
, output
, zinfo
);
283 fprintf ( stderr
, "Unknown zinfo record type \"%s\"\n", &type
[0] );
287 static int write_output_file ( struct output_file
*output
) {
288 if ( fwrite ( output
->buf
, 1, output
->len
, stdout
) != output
->len
) {
289 fprintf ( stderr
, "Could not write %d bytes of output: %s\n",
290 output
->len
, strerror ( errno
) );
296 int main ( int argc
, char **argv
) {
297 struct input_file input
;
298 struct output_file output
;
299 struct zinfo_file zinfo
;
303 fprintf ( stderr
, "Syntax: %s file.bin file.zinfo "
304 "> file.zbin\n", argv
[0] );
308 if ( read_input_file ( argv
[1], &input
) < 0 )
310 if ( read_zinfo_file ( argv
[2], &zinfo
) < 0 )
312 if ( alloc_output_file ( ( input
.len
* 4 ), &output
) < 0 )
315 for ( i
= 0 ; i
< zinfo
.num_entries
; i
++ ) {
316 if ( process_zinfo ( &input
, &output
,
317 &zinfo
.zinfo
[i
] ) < 0 )
321 if ( write_output_file ( &output
) < 0 )