Mercurial > hg > index.cgi
comparison lwasm/output.c @ 425:9f0448022f1f
Fix address overflows in SREC and IHEX file formats
Thanks to hider <stego@satx.rr.com> for pointing out an overflow that caused
16 bit addresses to be output as 5 hex digits in cases where an address
counter wrapped. Simply mask the addresses down to 16 bits.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 03 Nov 2016 21:36:17 -0600 |
parents | 7f538053492c |
children | 58cafa61ab40 |
comparison
equal
deleted
inserted
replaced
424:3aad0ff3c3be | 425:9f0448022f1f |
---|---|
394 rc = fetch_output_byte(cl, &outbyte, &outaddr); | 394 rc = fetch_output_byte(cl, &outbyte, &outaddr); |
395 | 395 |
396 // if address jump or xxx0 address, start new line | 396 // if address jump or xxx0 address, start new line |
397 if ((rc == -1) || ((rc == 1) && (outaddr % RECLEN == 0))) | 397 if ((rc == -1) || ((rc == 1) && (outaddr % RECLEN == 0))) |
398 { | 398 { |
399 fprintf(of, "\r\n%04X:", (unsigned int)outaddr); | 399 fprintf(of, "\r\n%04X:", (unsigned int)(outaddr & 0xffff)); |
400 fprintf(of, "%02X", (unsigned char)outbyte); | 400 fprintf(of, "%02X", (unsigned char)outbyte); |
401 rc = -1; | 401 rc = -1; |
402 } | 402 } |
403 if (rc == 1) | 403 if (rc == 1) |
404 fprintf(of, ",%02X", (unsigned char)outbyte); | 404 fprintf(of, ",%02X", (unsigned char)outbyte); |
457 | 457 |
458 // flush any current S1 record before starting new one | 458 // flush any current S1 record before starting new one |
459 if (recdlen > 0) | 459 if (recdlen > 0) |
460 { | 460 { |
461 recsum = recdlen + 3; | 461 recsum = recdlen + 3; |
462 fprintf(of, "S1%02X%04X", recdlen + 3, recaddr); | 462 fprintf(of, "S1%02X%04X", recdlen + 3, recaddr & 0xffff); |
463 for (i = 0; i < recdlen; i++) | 463 for (i = 0; i < recdlen; i++) |
464 { | 464 { |
465 fprintf(of, "%02X", (unsigned char)recdata[i]); | 465 fprintf(of, "%02X", (unsigned char)recdata[i]); |
466 recsum += (unsigned char)recdata[i]; | 466 recsum += (unsigned char)recdata[i]; |
467 } | 467 } |
485 | 485 |
486 // done with all output lines, flush the final S1 record (if any) | 486 // done with all output lines, flush the final S1 record (if any) |
487 if (recdlen > 0) | 487 if (recdlen > 0) |
488 { | 488 { |
489 recsum = recdlen + 3; | 489 recsum = recdlen + 3; |
490 fprintf(of, "S1%02X%04X", recdlen + 3, recaddr); | 490 fprintf(of, "S1%02X%04X", recdlen + 3, recaddr & 0xffff); |
491 for (i = 0; i < recdlen; i++) | 491 for (i = 0; i < recdlen; i++) |
492 { | 492 { |
493 fprintf(of, "%02X", (unsigned char)recdata[i]); | 493 fprintf(of, "%02X", (unsigned char)recdata[i]); |
494 recsum += (unsigned char)recdata[i]; | 494 recsum += (unsigned char)recdata[i]; |
495 } | 495 } |
511 | 511 |
512 // emit S9 end-of-file record | 512 // emit S9 end-of-file record |
513 recsum = 3; | 513 recsum = 3; |
514 recsum += (as -> execaddr >> 8) & 0xFF; | 514 recsum += (as -> execaddr >> 8) & 0xFF; |
515 recsum += (as -> execaddr) & 0xFF; | 515 recsum += (as -> execaddr) & 0xFF; |
516 fprintf(of, "S903%04X", as -> execaddr); | 516 fprintf(of, "S903%04X", as -> execaddr & 0xffff); |
517 fprintf(of, "%02X\r\n", (unsigned char)(~recsum)); | 517 fprintf(of, "%02X\r\n", (unsigned char)(~recsum)); |
518 } | 518 } |
519 } | 519 } |
520 | 520 |
521 | 521 |
546 { | 546 { |
547 // flush any current ihex record before starting new one | 547 // flush any current ihex record before starting new one |
548 if (recdlen > 0) | 548 if (recdlen > 0) |
549 { | 549 { |
550 recsum = recdlen; | 550 recsum = recdlen; |
551 fprintf(of, ":%02X%04X00", recdlen, recaddr); | 551 fprintf(of, ":%02X%04X00", recdlen, recaddr & 0xffff); |
552 for (i = 0; i < recdlen; i++) | 552 for (i = 0; i < recdlen; i++) |
553 { | 553 { |
554 fprintf(of, "%02X", (unsigned char)recdata[i]); | 554 fprintf(of, "%02X", (unsigned char)recdata[i]); |
555 recsum += (unsigned char)recdata[i]; | 555 recsum += (unsigned char)recdata[i]; |
556 } | 556 } |
574 | 574 |
575 // done with all output lines, flush the final ihex record (if any) | 575 // done with all output lines, flush the final ihex record (if any) |
576 if (recdlen > 0) | 576 if (recdlen > 0) |
577 { | 577 { |
578 recsum = recdlen; | 578 recsum = recdlen; |
579 fprintf(of, ":%02X%04X00", recdlen, recaddr); | 579 fprintf(of, ":%02X%04X00", recdlen, recaddr & 0xffff); |
580 for (i = 0; i < recdlen; i++) | 580 for (i = 0; i < recdlen; i++) |
581 { | 581 { |
582 fprintf(of, "%02X", (unsigned char)recdata[i]); | 582 fprintf(of, "%02X", (unsigned char)recdata[i]); |
583 recsum += (unsigned char)recdata[i]; | 583 recsum += (unsigned char)recdata[i]; |
584 } | 584 } |