7 FILE *infile, *outfile;
41 struct zinfo_subtract {
49 struct zinfo_common common;
50 struct zinfo_copy copy;
51 struct zinfo_pack pack;
52 struct zinfo_subtract subtract;
56 union zinfo_record *zinfo;
57 unsigned int num_entries;
60 static unsigned long align ( unsigned long value, unsigned long align ) {
61 return ( ( value + align - 1 ) & ~( align - 1 ) );
64 static int read_file ( const char *filename, void **buf, size_t *len ) {
68 file = fopen ( filename, "r" );
70 fprintf ( stderr, "Could not open %s: %s\n", filename,
75 if ( fstat ( fileno ( file ), &stat ) < 0 ) {
76 fprintf ( stderr, "Could not stat %s: %s\n", filename,
82 *buf = malloc ( *len );
84 fprintf ( stderr, "Could not malloc() %d bytes for %s: %s\n",
85 *len, filename, strerror ( errno ) );
89 if ( fread ( *buf, 1, *len, file ) != *len ) {
90 fprintf ( stderr, "Could not read %d bytes from %s: %s\n",
91 *len, filename, strerror ( errno ) );
104 static int read_input_file ( const char *filename,
105 struct input_file *input ) {
106 return read_file ( filename, &input->buf, &input->len );
109 static int read_zinfo_file ( const char *filename,
110 struct zinfo_file *zinfo ) {
114 if ( read_file ( filename, &buf, &len ) < 0 )
117 if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) {
118 fprintf ( stderr, ".zinfo file %s has invalid length %d\n",
124 zinfo->num_entries = ( len / sizeof ( *(zinfo->zinfo) ) );
128 static int alloc_output_file ( size_t max_len, struct output_file *output ) {
130 output->max_len = ( max_len );
131 output->buf = malloc ( max_len );
132 if ( ! output->buf ) {
133 fprintf ( stderr, "Could not allocate %d bytes for output\n",
137 memset ( output->buf, 0xff, sizeof ( output->buf ) );
141 static int process_zinfo_copy ( struct input_file *input,
142 struct output_file *output,
143 union zinfo_record *zinfo ) {
144 struct zinfo_copy *copy = &zinfo->copy;
145 size_t offset = copy->offset;
146 size_t len = copy->len;
148 if ( ( offset + len ) > input->len ) {
149 fprintf ( stderr, "Input buffer overrun on copy\n" );
153 output->len = align ( output->len, copy->align );
154 if ( ( output->len + len ) > output->max_len ) {
155 fprintf ( stderr, "Output buffer overrun on copy\n" );
160 fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
161 output->len, ( output->len + len ) );
164 memcpy ( ( output->buf + output->len ),
165 ( input->buf + offset ), len );
170 static int process_zinfo_pack ( struct input_file *input,
171 struct output_file *output,
172 union zinfo_record *zinfo ) {
173 struct zinfo_pack *pack = &zinfo->pack;
174 size_t offset = pack->offset;
175 size_t len = pack->len;
176 unsigned long packed_len;
178 if ( ( offset + len ) > input->len ) {
179 fprintf ( stderr, "Input buffer overrun on pack\n" );
183 output->len = align ( output->len, pack->align );
184 if ( output->len > output->max_len ) {
185 fprintf ( stderr, "Output buffer overrun on pack\n" );
189 if ( ucl_nrv2b_99_compress ( ( input->buf + offset ), len,
190 ( output->buf + output->len ),
191 &packed_len, 0 ) != UCL_E_OK ) {
192 fprintf ( stderr, "Compression failure\n" );
197 fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
198 output->len, ( output->len + packed_len ) );
201 output->len += packed_len;
202 if ( output->len > output->max_len ) {
203 fprintf ( stderr, "Output buffer overrun on pack\n" );
210 static int process_zinfo_subtract ( struct input_file *input,
211 struct output_file *output,
212 struct zinfo_subtract *subtract,
214 size_t offset = subtract->offset;
216 signed long raw_delta;
221 if ( ( offset + datasize ) > output->len ) {
222 fprintf ( stderr, "Subtract at %#zx outside output buffer\n",
227 target = ( output->buf + offset );
228 raw_delta = ( align ( output->len, subtract->divisor ) -
229 align ( input->len, subtract->divisor ) );
230 delta = ( raw_delta / ( ( signed long ) subtract->divisor ) );
232 switch ( datasize ) {
234 uint8_t *byte = target;
240 uint16_t *word = target;
246 uint32_t *dword = target;
252 fprintf ( stderr, "Unsupported subtract datasize %d\n",
258 fprintf ( stderr, "SUBx [%#zx,%#zx) (%#lx+(%#lx/%#x)-(%#lx/%#x)) = %#lx\n",
259 offset, ( offset + datasize ), old, output->len, subtract->divisor,
260 input->len, subtract->divisor, new );
266 static int process_zinfo_subb ( struct input_file *input,
267 struct output_file *output,
268 union zinfo_record *zinfo ) {
269 return process_zinfo_subtract ( input, output, &zinfo->subtract, 1 );
272 static int process_zinfo_subw ( struct input_file *input,
273 struct output_file *output,
274 union zinfo_record *zinfo ) {
275 return process_zinfo_subtract ( input, output, &zinfo->subtract, 2 );
278 static int process_zinfo_subl ( struct input_file *input,
279 struct output_file *output,
280 union zinfo_record *zinfo ) {
281 return process_zinfo_subtract ( input, output, &zinfo->subtract, 4 );
284 struct zinfo_processor {
286 int ( * process ) ( struct input_file *input,
287 struct output_file *output,
288 union zinfo_record *zinfo );
291 static struct zinfo_processor zinfo_processors[] = {
292 { "COPY", process_zinfo_copy },
293 { "PACK", process_zinfo_pack },
294 { "SUBB", process_zinfo_subb },
295 { "SUBW", process_zinfo_subw },
296 { "SUBL", process_zinfo_subl },
299 static int process_zinfo ( struct input_file *input,
300 struct output_file *output,
301 union zinfo_record *zinfo ) {
302 struct zinfo_common *common = &zinfo->common;
303 struct zinfo_processor *processor;
304 char type[ sizeof ( common->type ) + 1 ] = "";
307 strncat ( type, common->type, sizeof ( type ) - 1 );
308 for ( i = 0 ; i < ( sizeof ( zinfo_processors ) /
309 sizeof ( zinfo_processors[0] ) ) ; i++ ) {
310 processor = &zinfo_processors[i];
311 if ( strcmp ( processor->type, type ) == 0 )
312 return processor->process ( input, output, zinfo );
315 fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] );
319 static int write_output_file ( struct output_file *output ) {
320 if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
321 fprintf ( stderr, "Could not write %d bytes of output: %s\n",
322 output->len, strerror ( errno ) );
328 int main ( int argc, char **argv ) {
329 struct input_file input;
330 struct output_file output;
331 struct zinfo_file zinfo;
335 fprintf ( stderr, "Syntax: %s file.bin file.zinfo "
336 "> file.zbin\n", argv[0] );
340 if ( read_input_file ( argv[1], &input ) < 0 )
342 if ( read_zinfo_file ( argv[2], &zinfo ) < 0 )
344 if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 )
347 for ( i = 0 ; i < zinfo.num_entries ; i++ ) {
348 if ( process_zinfo ( &input, &output,
349 &zinfo.zinfo[i] ) < 0 )
353 if ( write_output_file ( &output ) < 0 )