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 ) );
98 static int read_input_file ( const char *filename,
99 struct input_file *input ) {
100 return read_file ( filename, &input->buf, &input->len );
103 static int read_zinfo_file ( const char *filename,
104 struct zinfo_file *zinfo ) {
108 if ( read_file ( filename, &buf, &len ) < 0 )
111 if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) {
112 fprintf ( stderr, ".zinfo file %s has invalid length %d\n",
118 zinfo->num_entries = ( len / sizeof ( *(zinfo->zinfo) ) );
122 static int alloc_output_file ( size_t max_len, struct output_file *output ) {
124 output->max_len = ( max_len );
125 output->buf = malloc ( max_len );
126 if ( ! output->buf ) {
127 fprintf ( stderr, "Could not allocate %d bytes for output\n",
131 memset ( output->buf, 0xff, sizeof ( output->buf ) );
135 static int process_zinfo_copy ( struct input_file *input,
136 struct output_file *output,
137 union zinfo_record *zinfo ) {
138 struct zinfo_copy *copy = &zinfo->copy;
139 size_t offset = copy->offset;
140 size_t len = copy->len;
141 unsigned int align = copy->align;
143 if ( ( offset + len ) > input->len ) {
144 fprintf ( stderr, "Input buffer overrun on copy\n" );
148 output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
149 if ( ( output->len + len ) > output->max_len ) {
150 fprintf ( stderr, "Output buffer overrun on copy\n" );
154 memcpy ( ( output->buf + output->len ),
155 ( input->buf + offset ), len );
160 static int process_zinfo_pack ( struct input_file *input,
161 struct output_file *output,
162 union zinfo_record *zinfo ) {
163 struct zinfo_pack *pack = &zinfo->pack;
164 size_t offset = pack->offset;
165 size_t len = pack->len;
166 unsigned int align = pack->align;
167 unsigned long packed_len;
169 if ( ( offset + len ) > input->len ) {
170 fprintf ( stderr, "Input buffer overrun on pack\n" );
174 output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
175 if ( output->len > output->max_len ) {
176 fprintf ( stderr, "Output buffer overrun on pack\n" );
180 if ( ucl_nrv2b_99_compress ( ( input->buf + offset ), len,
181 ( output->buf + output->len ),
182 &packed_len, 0 ) != UCL_E_OK ) {
183 fprintf ( stderr, "Compression failure\n" );
187 output->len += packed_len;
188 if ( output->len > output->max_len ) {
189 fprintf ( stderr, "Output buffer overrun on pack\n" );
196 static int process_zinfo_subtract ( struct input_file *input,
197 struct output_file *output,
198 struct zinfo_subtract *subtract,
200 size_t offset = subtract->offset;
204 if ( ( offset + datasize ) > output->len ) {
205 fprintf ( stderr, "Subtract at %#zx outside output buffer\n",
210 target = ( output->buf + offset );
211 delta = ( ( output->len / subtract->divisor ) -
212 ( input->len / subtract->divisor ) );
214 switch ( datasize ) {
216 uint8_t *byte = target;
220 uint16_t *word = target;
224 uint32_t *dword = target;
228 fprintf ( stderr, "Unsupported subtract datasize %d\n",
235 static int process_zinfo_subb ( struct input_file *input,
236 struct output_file *output,
237 union zinfo_record *zinfo ) {
238 return process_zinfo_subtract ( input, output, &zinfo->subtract, 1 );
241 static int process_zinfo_subw ( struct input_file *input,
242 struct output_file *output,
243 union zinfo_record *zinfo ) {
244 return process_zinfo_subtract ( input, output, &zinfo->subtract, 2 );
247 static int process_zinfo_subl ( struct input_file *input,
248 struct output_file *output,
249 union zinfo_record *zinfo ) {
250 return process_zinfo_subtract ( input, output, &zinfo->subtract, 4 );
253 struct zinfo_processor {
255 int ( * process ) ( struct input_file *input,
256 struct output_file *output,
257 union zinfo_record *zinfo );
260 static struct zinfo_processor zinfo_processors[] = {
261 { "COPY", process_zinfo_copy },
262 { "PACK", process_zinfo_pack },
263 { "SUBB", process_zinfo_subb },
264 { "SUBW", process_zinfo_subw },
265 { "SUBL", process_zinfo_subl },
268 static int process_zinfo ( struct input_file *input,
269 struct output_file *output,
270 union zinfo_record *zinfo ) {
271 struct zinfo_common *common = &zinfo->common;
272 struct zinfo_processor *processor;
273 char type[ sizeof ( common->type ) + 1 ] = "";
276 strncat ( type, common->type, sizeof ( type ) - 1 );
277 for ( i = 0 ; i < ( sizeof ( zinfo_processors ) /
278 sizeof ( zinfo_processors[0] ) ) ; i++ ) {
279 processor = &zinfo_processors[i];
280 if ( strcmp ( processor->type, type ) == 0 )
281 return processor->process ( input, output, zinfo );
284 fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] );
288 static int write_output_file ( struct output_file *output ) {
289 if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
290 fprintf ( stderr, "Could not write %d bytes of output: %s\n",
291 output->len, strerror ( errno ) );
297 int main ( int argc, char **argv ) {
298 struct input_file input;
299 struct output_file output;
300 struct zinfo_file zinfo;
304 fprintf ( stderr, "Syntax: %s file.bin file.zinfo "
305 "> file.zbin\n", argv[0] );
309 if ( read_input_file ( argv[1], &input ) < 0 )
311 if ( read_zinfo_file ( argv[2], &zinfo ) < 0 )
313 if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 )
316 for ( i = 0 ; i < zinfo.num_entries ; i++ ) {
317 if ( process_zinfo ( &input, &output,
318 &zinfo.zinfo[i] ) < 0 )
322 if ( write_output_file ( &output ) < 0 )