Changeset 81666 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Nov 5, 2019 11:07:52 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134426
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/ipxe/src/util/zbin.c
r63497 r81666 11 11 12 12 struct input_file { 13 14 13 void *buf; 14 size_t len; 15 15 }; 16 16 17 17 struct output_file { 18 19 20 21 18 void *buf; 19 size_t len; 20 size_t hdr_len; 21 size_t max_len; 22 22 }; 23 23 24 24 struct zinfo_common { 25 26 25 char type[4]; 26 char pad[12]; 27 27 }; 28 28 29 29 struct zinfo_copy { 30 31 32 33 30 char type[4]; 31 uint32_t offset; 32 uint32_t len; 33 uint32_t align; 34 34 }; 35 35 36 36 struct zinfo_pack { 37 38 39 40 37 char type[4]; 38 uint32_t offset; 39 uint32_t len; 40 uint32_t align; 41 41 }; 42 42 43 43 struct zinfo_payload { 44 45 46 47 44 char type[4]; 45 uint32_t pad1; 46 uint32_t pad2; 47 uint32_t align; 48 48 }; 49 49 50 50 struct zinfo_add { 51 52 53 54 51 char type[4]; 52 uint32_t offset; 53 uint32_t divisor; 54 uint32_t pad; 55 55 }; 56 56 57 57 union zinfo_record { 58 59 60 61 62 58 struct zinfo_common common; 59 struct zinfo_copy copy; 60 struct zinfo_pack pack; 61 struct zinfo_payload payload; 62 struct zinfo_add add; 63 63 }; 64 64 65 65 struct zinfo_file { 66 67 66 union zinfo_record *zinfo; 67 unsigned int num_entries; 68 68 }; 69 69 70 70 static unsigned long align ( unsigned long value, unsigned long algn ) { 71 71 return ( ( value + algn - 1 ) & ~( algn - 1 ) ); 72 72 } 73 73 74 74 static int read_file ( const char *filename, void **buf, size_t *len ) { 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 75 FILE *file; 76 struct stat sstat; 77 78 file = fopen ( filename, "r" ); 79 if ( ! file ) { 80 fprintf ( stderr, "Could not open %s: %s\n", filename, 81 strerror ( errno ) ); 82 goto err; 83 } 84 85 if ( fstat ( fileno ( file ), &sstat ) < 0 ) { 86 fprintf ( stderr, "Could not stat %s: %s\n", filename, 87 strerror ( errno ) ); 88 goto err; 89 } 90 91 *len = sstat.st_size; 92 *buf = malloc ( *len ); 93 if ( ! *buf ) { 94 fprintf ( stderr, "Could not malloc() %zd bytes for %s: %s\n", 95 *len, filename, strerror ( errno ) ); 96 goto err; 97 } 98 99 if ( fread ( *buf, 1, *len, file ) != *len ) { 100 fprintf ( stderr, "Could not read %zd bytes from %s: %s\n", 101 *len, filename, strerror ( errno ) ); 102 goto err; 103 } 104 105 fclose ( file ); 106 return 0; 107 107 108 108 err: 109 110 111 109 if ( file ) 110 fclose ( file ); 111 return -1; 112 112 } 113 113 114 114 static int read_input_file ( const char *filename, 115 116 115 struct input_file *input ) { 116 return read_file ( filename, &input->buf, &input->len ); 117 117 } 118 118 119 119 static int read_zinfo_file ( const char *filename, 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 120 struct zinfo_file *zinfo ) { 121 void *buf; 122 size_t len; 123 124 if ( read_file ( filename, &buf, &len ) < 0 ) 125 return -1; 126 127 if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) { 128 fprintf ( stderr, ".zinfo file %s has invalid length %zd\n", 129 filename, len ); 130 return -1; 131 } 132 133 zinfo->zinfo = buf; 134 zinfo->num_entries = ( len / sizeof ( *(zinfo->zinfo) ) ); 135 return 0; 136 136 } 137 137 138 138 static int alloc_output_file ( size_t max_len, struct output_file *output ) { 139 140 141 142 143 144 145 146 139 output->len = 0; 140 output->max_len = ( max_len ); 141 output->buf = malloc ( max_len ); 142 if ( ! output->buf ) { 143 fprintf ( stderr, "Could not allocate %zd bytes for output\n", 144 max_len ); 145 return -1; 146 } 147 147 #ifndef VBOX 148 148 memset ( output->buf, 0xff, sizeof ( output->buf ) ); 149 149 #else 150 150 memset ( output->buf, 0xff, max_len ); 151 151 #endif 152 152 return 0; 153 153 } 154 154 155 155 static int process_zinfo_copy ( struct input_file *input, 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 156 struct output_file *output, 157 union zinfo_record *zinfo ) { 158 struct zinfo_copy *copy = &zinfo->copy; 159 size_t offset = copy->offset; 160 size_t len = copy->len; 161 162 if ( ( offset + len ) > input->len ) { 163 fprintf ( stderr, "Input buffer overrun on copy\n" ); 164 return -1; 165 } 166 167 output->len = align ( output->len, copy->align ); 168 if ( ( output->len + len ) > output->max_len ) { 169 fprintf ( stderr, "Output buffer overrun on copy\n" ); 170 return -1; 171 } 172 173 if ( DEBUG ) { 174 fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n", 175 offset, ( offset + len ), output->len, 176 ( output->len + len ) ); 177 } 178 179 memcpy ( (void*)((char*) output->buf + output->len ), 180 (void*)((char*) input->buf + offset ), len ); 181 output->len += len; 182 return 0; 183 183 } 184 184 185 185 static int process_zinfo_pack ( struct input_file *input, 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 186 struct output_file *output, 187 union zinfo_record *zinfo ) { 188 struct zinfo_pack *pack = &zinfo->pack; 189 size_t offset = pack->offset; 190 size_t len = pack->len; 191 unsigned long packed_len; 192 193 if ( ( offset + len ) > input->len ) { 194 fprintf ( stderr, "Input buffer overrun on pack\n" ); 195 return -1; 196 } 197 198 output->len = align ( output->len, pack->align ); 199 if ( output->len > output->max_len ) { 200 fprintf ( stderr, "Output buffer overrun on pack\n" ); 201 return -1; 202 } 203 204 if ( ucl_nrv2b_99_compress ( (void*)((char*) input->buf + offset ), len, 205 (void*)((char*) output->buf + output->len ), 206 &packed_len, 0 ) != UCL_E_OK ) { 207 fprintf ( stderr, "Compression failure\n" ); 208 return -1; 209 } 210 211 if ( DEBUG ) { 212 fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n", 213 offset, ( offset + len ), output->len, 214 ( size_t )( output->len + packed_len ) ); 215 } 216 217 output->len += packed_len; 218 if ( output->len > output->max_len ) { 219 fprintf ( stderr, "Output buffer overrun on pack\n" ); 220 return -1; 221 } 222 223 return 0; 224 224 } 225 225 226 226 static int process_zinfo_payl ( struct input_file *input 227 228 229 230 231 232 233 234 235 236 237 238 227 __attribute__ (( unused )), 228 struct output_file *output, 229 union zinfo_record *zinfo ) { 230 struct zinfo_payload *payload = &zinfo->payload; 231 232 output->len = align ( output->len, payload->align ); 233 output->hdr_len = output->len; 234 235 if ( DEBUG ) { 236 fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len ); 237 } 238 return 0; 239 239 } 240 240 241 241 static int process_zinfo_add ( struct input_file *input 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 ( ( addend < 0 ) ? "-" : "" ),abs ( addend ), size,288 289 290 291 292 293 294 295 ( ( addend < 0 ) ? "-" : "" ),abs ( addend ), size,296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 ( ( addend < 0 ) ? "-" : "" ),abs ( addend ),317 318 319 320 242 __attribute__ (( unused )), 243 struct output_file *output, 244 size_t len, 245 struct zinfo_add *add, 246 size_t datasize ) { 247 size_t offset = add->offset; 248 void *target; 249 signed long addend; 250 unsigned long size; 251 signed long val; 252 unsigned long mask; 253 254 if ( ( offset + datasize ) > output->len ) { 255 fprintf ( stderr, "Add at %#zx outside output buffer\n", 256 offset ); 257 return -1; 258 } 259 260 target = (void*)((char*) output->buf + offset ); 261 size = ( align ( len, add->divisor ) / add->divisor ); 262 263 switch ( datasize ) { 264 case 1: 265 addend = *( ( int8_t * ) target ); 266 break; 267 case 2: 268 addend = *( ( int16_t * ) target ); 269 break; 270 case 4: 271 addend = *( ( int32_t * ) target ); 272 break; 273 default: 274 fprintf ( stderr, "Unsupported add datasize %zd\n", 275 datasize ); 276 return -1; 277 } 278 279 val = size + addend; 280 281 /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */ 282 mask = ( ( datasize < sizeof ( mask ) ) ? 283 ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL ); 284 285 if ( val < 0 ) { 286 fprintf ( stderr, "Add %s%#x+%#lx at %#zx %sflows field\n", 287 ( ( addend < 0 ) ? "-" : "" ), labs ( addend ), size, 288 offset, ( ( addend < 0 ) ? "under" : "over" ) ); 289 return -1; 290 } 291 292 if ( val & ~mask ) { 293 fprintf ( stderr, "Add %s%#x+%#lx at %#zx overflows %zd-byte " 294 "field (%d bytes too big)\n", 295 ( ( addend < 0 ) ? "-" : "" ), labs ( addend ), size, 296 offset, datasize, 297 ( int )( ( val - mask - 1 ) * add->divisor ) ); 298 return -1; 299 } 300 301 switch ( datasize ) { 302 case 1: 303 *( ( uint8_t * ) target ) = val; 304 break; 305 case 2: 306 *( ( uint16_t * ) target ) = val; 307 break; 308 case 4: 309 *( ( uint32_t * ) target ) = val; 310 break; 311 } 312 313 if ( DEBUG ) { 314 fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = " 315 "%#lx\n", offset, ( offset + datasize ), 316 ( ( addend < 0 ) ? "-" : "" ), labs ( addend ), 317 len, add->divisor, val ); 318 } 319 320 return 0; 321 321 } 322 322 323 323 static int process_zinfo_addb ( struct input_file *input, 324 325 326 327 324 struct output_file *output, 325 union zinfo_record *zinfo ) { 326 return process_zinfo_add ( input, output, output->len, 327 &zinfo->add, 1 ); 328 328 } 329 329 330 330 static int process_zinfo_addw ( struct input_file *input, 331 332 333 334 331 struct output_file *output, 332 union zinfo_record *zinfo ) { 333 return process_zinfo_add ( input, output, output->len, 334 &zinfo->add, 2 ); 335 335 } 336 336 337 337 static int process_zinfo_addl ( struct input_file *input, 338 339 340 341 338 struct output_file *output, 339 union zinfo_record *zinfo ) { 340 return process_zinfo_add ( input, output, output->len, 341 &zinfo->add, 4 ); 342 342 } 343 343 344 344 static int process_zinfo_adhb ( struct input_file *input, 345 346 347 348 345 struct output_file *output, 346 union zinfo_record *zinfo ) { 347 return process_zinfo_add ( input, output, output->hdr_len, 348 &zinfo->add, 1 ); 349 349 } 350 350 351 351 static int process_zinfo_adhw ( struct input_file *input, 352 353 354 355 352 struct output_file *output, 353 union zinfo_record *zinfo ) { 354 return process_zinfo_add ( input, output, output->hdr_len, 355 &zinfo->add, 2 ); 356 356 } 357 357 358 358 static int process_zinfo_adhl ( struct input_file *input, 359 360 361 362 359 struct output_file *output, 360 union zinfo_record *zinfo ) { 361 return process_zinfo_add ( input, output, output->hdr_len, 362 &zinfo->add, 4 ); 363 363 } 364 364 365 365 struct zinfo_processor { 366 367 368 369 366 char *type; 367 int ( * process ) ( struct input_file *input, 368 struct output_file *output, 369 union zinfo_record *zinfo ); 370 370 }; 371 371 372 372 static struct zinfo_processor zinfo_processors[] = { 373 374 375 376 377 378 379 380 381 373 { "COPY", process_zinfo_copy }, 374 { "PACK", process_zinfo_pack }, 375 { "PAYL", process_zinfo_payl }, 376 { "ADDB", process_zinfo_addb }, 377 { "ADDW", process_zinfo_addw }, 378 { "ADDL", process_zinfo_addl }, 379 { "ADHB", process_zinfo_adhb }, 380 { "ADHW", process_zinfo_adhw }, 381 { "ADHL", process_zinfo_adhl }, 382 382 }; 383 383 384 384 static int process_zinfo ( struct input_file *input, 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 385 struct output_file *output, 386 union zinfo_record *zinfo ) { 387 struct zinfo_common *common = &zinfo->common; 388 struct zinfo_processor *processor; 389 char type[ sizeof ( common->type ) + 1 ] = ""; 390 unsigned int i; 391 392 strncat ( type, common->type, sizeof ( type ) - 1 ); 393 for ( i = 0 ; i < ( sizeof ( zinfo_processors ) / 394 sizeof ( zinfo_processors[0] ) ) ; i++ ) { 395 processor = &zinfo_processors[i]; 396 if ( strcmp ( processor->type, type ) == 0 ) 397 return processor->process ( input, output, zinfo ); 398 } 399 400 fprintf ( stderr, "Unknown zinfo record type \"%s\"\n", &type[0] ); 401 return -1; 402 402 } 403 403 404 404 static int write_output_file ( struct output_file *output ) { 405 406 407 408 409 410 405 if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) { 406 fprintf ( stderr, "Could not write %zd bytes of output: %s\n", 407 output->len, strerror ( errno ) ); 408 return -1; 409 } 410 return 0; 411 411 } 412 412 413 413 int main ( int argc, char **argv ) { 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 } 414 struct input_file input; 415 struct output_file output; 416 struct zinfo_file zinfo; 417 unsigned int i; 418 419 if ( argc != 3 ) { 420 fprintf ( stderr, "Syntax: %s file.bin file.zinfo " 421 "> file.zbin\n", argv[0] ); 422 exit ( 1 ); 423 } 424 425 if ( read_input_file ( argv[1], &input ) < 0 ) 426 exit ( 1 ); 427 if ( read_zinfo_file ( argv[2], &zinfo ) < 0 ) 428 exit ( 1 ); 429 if ( alloc_output_file ( ( input.len * 4 ), &output ) < 0 ) 430 exit ( 1 ); 431 432 for ( i = 0 ; i < zinfo.num_entries ; i++ ) { 433 if ( process_zinfo ( &input, &output, 434 &zinfo.zinfo[i] ) < 0 ) 435 exit ( 1 ); 436 } 437 438 if ( write_output_file ( &output ) < 0 ) 439 exit ( 1 ); 440 441 return 0; 442 }
Note:
See TracChangeset
for help on using the changeset viewer.