srec.c revision 77298
1/* BFD back-end for s-record objects. 2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 3 Free Software Foundation, Inc. 4 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. 5 6This file is part of BFD, the Binary File Descriptor library. 7 8This program is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with this program; if not, write to the Free Software 20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21 22/* 23SUBSECTION 24 S-Record handling 25 26DESCRIPTION 27 28 Ordinary S-Records cannot hold anything but addresses and 29 data, so that's all that we implement. 30 31 The only interesting thing is that S-Records may come out of 32 order and there is no header, so an initial scan is required 33 to discover the minimum and maximum addresses used to create 34 the vma and size of the only section we create. We 35 arbitrarily call this section ".text". 36 37 When bfd_get_section_contents is called the file is read 38 again, and this time the data is placed into a bfd_alloc'd 39 area. 40 41 Any number of sections may be created for output, we save them 42 up and output them when it's time to close the bfd. 43 44 An s record looks like: 45 46EXAMPLE 47 S<type><length><address><data><checksum> 48 49DESCRIPTION 50 Where 51 o length 52 is the number of bytes following upto the checksum. Note that 53 this is not the number of chars following, since it takes two 54 chars to represent a byte. 55 o type 56 is one of: 57 0) header record 58 1) two byte address data record 59 2) three byte address data record 60 3) four byte address data record 61 7) four byte address termination record 62 8) three byte address termination record 63 9) two byte address termination record 64 65 o address 66 is the start address of the data following, or in the case of 67 a termination record, the start address of the image 68 o data 69 is the data. 70 o checksum 71 is the sum of all the raw byte data in the record, from the length 72 upwards, modulo 256 and subtracted from 255. 73 74SUBSECTION 75 Symbol S-Record handling 76 77DESCRIPTION 78 Some ICE equipment understands an addition to the standard 79 S-Record format; symbols and their addresses can be sent 80 before the data. 81 82 The format of this is: 83 ($$ <modulename> 84 (<space> <symbol> <address>)*) 85 $$ 86 87 so a short symbol table could look like: 88 89EXAMPLE 90 $$ flash.x 91 $$ flash.c 92 _port6 $0 93 _delay $4 94 _start $14 95 _etext $8036 96 _edata $8036 97 _end $8036 98 $$ 99 100DESCRIPTION 101 We allow symbols to be anywhere in the data stream - the module names 102 are always ignored. 103 104*/ 105 106#include "bfd.h" 107#include "sysdep.h" 108#include "libbfd.h" 109#include "libiberty.h" 110#include <ctype.h> 111 112static void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); 113static void srec_print_symbol 114 PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); 115static void srec_init PARAMS ((void)); 116static boolean srec_mkobject PARAMS ((bfd *)); 117static int srec_get_byte PARAMS ((bfd *, boolean *)); 118static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean)); 119static boolean srec_scan PARAMS ((bfd *)); 120static const bfd_target *srec_object_p PARAMS ((bfd *)); 121static const bfd_target *symbolsrec_object_p PARAMS ((bfd *)); 122static boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *)); 123 124static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma, 125 const bfd_byte *, 126 const bfd_byte *)); 127static boolean srec_write_header PARAMS ((bfd *)); 128static boolean srec_write_symbols PARAMS ((bfd *)); 129static boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma)); 130static boolean srec_get_section_contents 131 PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); 132static boolean srec_set_arch_mach 133 PARAMS ((bfd *, enum bfd_architecture, unsigned long)); 134static boolean srec_set_section_contents 135 PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); 136static boolean internal_srec_write_object_contents PARAMS ((bfd *, int)); 137static boolean srec_write_object_contents PARAMS ((bfd *)); 138static boolean symbolsrec_write_object_contents PARAMS ((bfd *)); 139static int srec_sizeof_headers PARAMS ((bfd *, boolean)); 140static asymbol *srec_make_empty_symbol PARAMS ((bfd *)); 141static long srec_get_symtab_upper_bound PARAMS ((bfd *)); 142static long srec_get_symtab PARAMS ((bfd *, asymbol **)); 143 144/* Macros for converting between hex and binary. */ 145 146static CONST char digs[] = "0123456789ABCDEF"; 147 148#define NIBBLE(x) hex_value(x) 149#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1])) 150#define TOHEX(d, x, ch) \ 151 d[1] = digs[(x) & 0xf]; \ 152 d[0] = digs[((x)>>4)&0xf]; \ 153 ch += ((x) & 0xff); 154#define ISHEX(x) hex_p(x) 155 156/* Initialize by filling in the hex conversion array. */ 157 158static void 159srec_init () 160{ 161 static boolean inited = false; 162 163 if (inited == false) 164 { 165 inited = true; 166 hex_init (); 167 } 168} 169 170/* The maximum number of bytes on a line is FF. */ 171#define MAXCHUNK 0xff 172 173/* Default size for a CHUNK. */ 174#define DEFAULT_CHUNK 16 175 176/* The number of bytes we actually fit onto a line on output. 177 This variable can be modified by objcopy's --srec-len parameter. 178 For a 0x75 byte record you should set --srec-len=0x70. */ 179unsigned int Chunk = DEFAULT_CHUNK; 180 181/* The type of srec output (free or forced to S3). 182 This variable can be modified by objcopy's --srec-forceS3 183 parameter. */ 184boolean S3Forced = 0; 185 186/* When writing an S-record file, the S-records can not be output as 187 they are seen. This structure is used to hold them in memory. */ 188 189struct srec_data_list_struct 190{ 191 struct srec_data_list_struct *next; 192 bfd_byte *data; 193 bfd_vma where; 194 bfd_size_type size; 195}; 196 197typedef struct srec_data_list_struct srec_data_list_type; 198 199/* When scanning the S-record file, a linked list of srec_symbol 200 structures is built to represent the symbol table (if there is 201 one). */ 202 203struct srec_symbol 204{ 205 struct srec_symbol *next; 206 const char *name; 207 bfd_vma val; 208}; 209 210/* The S-record tdata information. */ 211 212typedef struct srec_data_struct 213 { 214 srec_data_list_type *head; 215 srec_data_list_type *tail; 216 unsigned int type; 217 struct srec_symbol *symbols; 218 struct srec_symbol *symtail; 219 asymbol *csymbols; 220 } 221tdata_type; 222 223static boolean srec_write_section PARAMS ((bfd *, tdata_type *, 224 srec_data_list_type *)); 225static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *)); 226 227/* Set up the S-record tdata information. */ 228 229static boolean 230srec_mkobject (abfd) 231 bfd *abfd; 232{ 233 srec_init (); 234 235 if (abfd->tdata.srec_data == NULL) 236 { 237 tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); 238 if (tdata == NULL) 239 return false; 240 abfd->tdata.srec_data = tdata; 241 tdata->type = 1; 242 tdata->head = NULL; 243 tdata->tail = NULL; 244 tdata->symbols = NULL; 245 tdata->symtail = NULL; 246 tdata->csymbols = NULL; 247 } 248 249 return true; 250} 251 252/* Read a byte from an S record file. Set *ERRORPTR if an error 253 occurred. Return EOF on error or end of file. */ 254 255static int 256srec_get_byte (abfd, errorptr) 257 bfd *abfd; 258 boolean *errorptr; 259{ 260 bfd_byte c; 261 262 if (bfd_read (&c, 1, 1, abfd) != 1) 263 { 264 if (bfd_get_error () != bfd_error_file_truncated) 265 *errorptr = true; 266 return EOF; 267 } 268 269 return (int) (c & 0xff); 270} 271 272/* Report a problem in an S record file. FIXME: This probably should 273 not call fprintf, but we really do need some mechanism for printing 274 error messages. */ 275 276static void 277srec_bad_byte (abfd, lineno, c, error) 278 bfd *abfd; 279 unsigned int lineno; 280 int c; 281 boolean error; 282{ 283 if (c == EOF) 284 { 285 if (! error) 286 bfd_set_error (bfd_error_file_truncated); 287 } 288 else 289 { 290 char buf[10]; 291 292 if (! isprint (c)) 293 sprintf (buf, "\\%03o", (unsigned int) c); 294 else 295 { 296 buf[0] = c; 297 buf[1] = '\0'; 298 } 299 (*_bfd_error_handler) 300 (_("%s:%d: Unexpected character `%s' in S-record file\n"), 301 bfd_get_filename (abfd), lineno, buf); 302 bfd_set_error (bfd_error_bad_value); 303 } 304} 305 306/* Add a new symbol found in an S-record file. */ 307 308static boolean 309srec_new_symbol (abfd, name, val) 310 bfd *abfd; 311 const char *name; 312 bfd_vma val; 313{ 314 struct srec_symbol *n; 315 316 n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol)); 317 if (n == NULL) 318 return false; 319 320 n->name = name; 321 n->val = val; 322 323 if (abfd->tdata.srec_data->symbols == NULL) 324 abfd->tdata.srec_data->symbols = n; 325 else 326 abfd->tdata.srec_data->symtail->next = n; 327 abfd->tdata.srec_data->symtail = n; 328 n->next = NULL; 329 330 ++abfd->symcount; 331 332 return true; 333} 334 335/* Read the S record file and turn it into sections. We create a new 336 section for each contiguous set of bytes. */ 337 338static boolean 339srec_scan (abfd) 340 bfd *abfd; 341{ 342 int c; 343 unsigned int lineno = 1; 344 boolean error = false; 345 bfd_byte *buf = NULL; 346 size_t bufsize = 0; 347 asection *sec = NULL; 348 char *symbuf = NULL; 349 350 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 351 goto error_return; 352 353 while ((c = srec_get_byte (abfd, &error)) != EOF) 354 { 355 /* We only build sections from contiguous S-records, so if this 356 is not an S-record, then stop building a section. */ 357 if (c != 'S' && c != '\r' && c != '\n') 358 sec = NULL; 359 360 switch (c) 361 { 362 default: 363 srec_bad_byte (abfd, lineno, c, error); 364 goto error_return; 365 366 case '\n': 367 ++lineno; 368 break; 369 370 case '\r': 371 break; 372 373 case '$': 374 /* Starting a module name, which we ignore. */ 375 while ((c = srec_get_byte (abfd, &error)) != '\n' 376 && c != EOF) 377 ; 378 if (c == EOF) 379 { 380 srec_bad_byte (abfd, lineno, c, error); 381 goto error_return; 382 } 383 384 ++lineno; 385 386 break; 387 388 case ' ': 389 do 390 { 391 unsigned int alc; 392 char *p, *symname; 393 bfd_vma symval; 394 395 /* Starting a symbol definition. */ 396 while ((c = srec_get_byte (abfd, &error)) != EOF 397 && (c == ' ' || c == '\t')) 398 ; 399 400 if (c == '\n' || c == '\r') 401 break; 402 403 if (c == EOF) 404 { 405 srec_bad_byte (abfd, lineno, c, error); 406 goto error_return; 407 } 408 409 alc = 10; 410 symbuf = (char *) bfd_malloc (alc + 1); 411 if (symbuf == NULL) 412 goto error_return; 413 414 p = symbuf; 415 416 *p++ = c; 417 while ((c = srec_get_byte (abfd, &error)) != EOF 418 && ! isspace (c)) 419 { 420 if ((unsigned int) (p - symbuf) >= alc) 421 { 422 char *n; 423 424 alc *= 2; 425 n = (char *) bfd_realloc (symbuf, alc + 1); 426 if (n == NULL) 427 goto error_return; 428 p = n + (p - symbuf); 429 symbuf = n; 430 } 431 432 *p++ = c; 433 } 434 435 if (c == EOF) 436 { 437 srec_bad_byte (abfd, lineno, c, error); 438 goto error_return; 439 } 440 441 *p++ = '\0'; 442 symname = bfd_alloc (abfd, p - symbuf); 443 if (symname == NULL) 444 goto error_return; 445 strcpy (symname, symbuf); 446 free (symbuf); 447 symbuf = NULL; 448 449 while ((c = srec_get_byte (abfd, &error)) != EOF 450 && (c == ' ' || c == '\t')) 451 ; 452 if (c == EOF) 453 { 454 srec_bad_byte (abfd, lineno, c, error); 455 goto error_return; 456 } 457 458 /* Skip a dollar sign before the hex value. */ 459 if (c == '$') 460 { 461 c = srec_get_byte (abfd, &error); 462 if (c == EOF) 463 { 464 srec_bad_byte (abfd, lineno, c, error); 465 goto error_return; 466 } 467 } 468 469 symval = 0; 470 while (ISHEX (c)) 471 { 472 symval <<= 4; 473 symval += NIBBLE (c); 474 c = srec_get_byte (abfd, &error); 475 } 476 477 if (! srec_new_symbol (abfd, symname, symval)) 478 goto error_return; 479 } 480 while (c == ' ' || c == '\t') 481 ; 482 483 if (c == '\n') 484 ++lineno; 485 else if (c != '\r') 486 { 487 srec_bad_byte (abfd, lineno, c, error); 488 goto error_return; 489 } 490 491 break; 492 493 case 'S': 494 { 495 file_ptr pos; 496 char hdr[3]; 497 unsigned int bytes; 498 bfd_vma address; 499 bfd_byte *data; 500 501 /* Starting an S-record. */ 502 503 pos = bfd_tell (abfd) - 1; 504 505 if (bfd_read (hdr, 1, 3, abfd) != 3) 506 goto error_return; 507 508 if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2])) 509 { 510 if (! ISHEX (hdr[1])) 511 c = hdr[1]; 512 else 513 c = hdr[2]; 514 srec_bad_byte (abfd, lineno, c, error); 515 goto error_return; 516 } 517 518 bytes = HEX (hdr + 1); 519 if (bytes * 2 > bufsize) 520 { 521 if (buf != NULL) 522 free (buf); 523 buf = (bfd_byte *) bfd_malloc (bytes * 2); 524 if (buf == NULL) 525 goto error_return; 526 bufsize = bytes * 2; 527 } 528 529 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2) 530 goto error_return; 531 532 /* Ignore the checksum byte. */ 533 --bytes; 534 535 address = 0; 536 data = buf; 537 switch (hdr[0]) 538 { 539 case '0': 540 case '5': 541 /* Prologue--ignore the file name, but stop building a 542 section at this point. */ 543 sec = NULL; 544 break; 545 546 case '3': 547 address = HEX (data); 548 data += 2; 549 --bytes; 550 /* Fall through. */ 551 case '2': 552 address = (address << 8) | HEX (data); 553 data += 2; 554 --bytes; 555 /* Fall through. */ 556 case '1': 557 address = (address << 8) | HEX (data); 558 data += 2; 559 address = (address << 8) | HEX (data); 560 data += 2; 561 bytes -= 2; 562 563 if (sec != NULL 564 && sec->vma + sec->_raw_size == address) 565 { 566 /* This data goes at the end of the section we are 567 currently building. */ 568 sec->_raw_size += bytes; 569 } 570 else 571 { 572 char secbuf[20]; 573 char *secname; 574 575 sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); 576 secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1); 577 strcpy (secname, secbuf); 578 sec = bfd_make_section (abfd, secname); 579 if (sec == NULL) 580 goto error_return; 581 sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; 582 sec->vma = address; 583 sec->lma = address; 584 sec->_raw_size = bytes; 585 sec->filepos = pos; 586 } 587 588 break; 589 590 case '7': 591 address = HEX (data); 592 data += 2; 593 /* Fall through. */ 594 case '8': 595 address = (address << 8) | HEX (data); 596 data += 2; 597 /* Fall through. */ 598 case '9': 599 address = (address << 8) | HEX (data); 600 data += 2; 601 address = (address << 8) | HEX (data); 602 data += 2; 603 604 /* This is a termination record. */ 605 abfd->start_address = address; 606 607 if (buf != NULL) 608 free (buf); 609 610 return true; 611 } 612 } 613 break; 614 } 615 } 616 617 if (error) 618 goto error_return; 619 620 if (buf != NULL) 621 free (buf); 622 623 return true; 624 625 error_return: 626 if (symbuf != NULL) 627 free (symbuf); 628 if (buf != NULL) 629 free (buf); 630 return false; 631} 632 633/* Check whether an existing file is an S-record file. */ 634 635static const bfd_target * 636srec_object_p (abfd) 637 bfd *abfd; 638{ 639 bfd_byte b[4]; 640 641 srec_init (); 642 643 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 644 || bfd_read (b, 1, 4, abfd) != 4) 645 return NULL; 646 647 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) 648 { 649 bfd_set_error (bfd_error_wrong_format); 650 return NULL; 651 } 652 653 if (! srec_mkobject (abfd) 654 || ! srec_scan (abfd)) 655 return NULL; 656 657 if (abfd->symcount > 0) 658 abfd->flags |= HAS_SYMS; 659 660 return abfd->xvec; 661} 662 663/* Check whether an existing file is an S-record file with symbols. */ 664 665static const bfd_target * 666symbolsrec_object_p (abfd) 667 bfd *abfd; 668{ 669 char b[2]; 670 671 srec_init (); 672 673 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 674 || bfd_read (b, 1, 2, abfd) != 2) 675 return NULL; 676 677 if (b[0] != '$' || b[1] != '$') 678 { 679 bfd_set_error (bfd_error_wrong_format); 680 return NULL; 681 } 682 683 if (! srec_mkobject (abfd) 684 || ! srec_scan (abfd)) 685 return NULL; 686 687 if (abfd->symcount > 0) 688 abfd->flags |= HAS_SYMS; 689 690 return abfd->xvec; 691} 692 693/* Read in the contents of a section in an S-record file. */ 694 695static boolean 696srec_read_section (abfd, section, contents) 697 bfd *abfd; 698 asection *section; 699 bfd_byte *contents; 700{ 701 int c; 702 bfd_size_type sofar = 0; 703 boolean error = false; 704 bfd_byte *buf = NULL; 705 size_t bufsize = 0; 706 707 if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0) 708 goto error_return; 709 710 while ((c = srec_get_byte (abfd, &error)) != EOF) 711 { 712 bfd_byte hdr[3]; 713 unsigned int bytes; 714 bfd_vma address; 715 bfd_byte *data; 716 717 if (c == '\r' || c == '\n') 718 continue; 719 720 /* This is called after srec_scan has already been called, so we 721 ought to know the exact format. */ 722 BFD_ASSERT (c == 'S'); 723 724 if (bfd_read (hdr, 1, 3, abfd) != 3) 725 goto error_return; 726 727 BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2])); 728 729 bytes = HEX (hdr + 1); 730 731 if (bytes * 2 > bufsize) 732 { 733 if (buf != NULL) 734 free (buf); 735 buf = (bfd_byte *) bfd_malloc (bytes * 2); 736 if (buf == NULL) 737 goto error_return; 738 bufsize = bytes * 2; 739 } 740 741 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2) 742 goto error_return; 743 744 address = 0; 745 data = buf; 746 switch (hdr[0]) 747 { 748 default: 749 BFD_ASSERT (sofar == section->_raw_size); 750 if (buf != NULL) 751 free (buf); 752 return true; 753 754 case '3': 755 address = HEX (data); 756 data += 2; 757 --bytes; 758 /* Fall through. */ 759 case '2': 760 address = (address << 8) | HEX (data); 761 data += 2; 762 --bytes; 763 /* Fall through. */ 764 case '1': 765 address = (address << 8) | HEX (data); 766 data += 2; 767 address = (address << 8) | HEX (data); 768 data += 2; 769 bytes -= 2; 770 771 if (address != section->vma + sofar) 772 { 773 /* We've come to the end of this section. */ 774 BFD_ASSERT (sofar == section->_raw_size); 775 if (buf != NULL) 776 free (buf); 777 return true; 778 } 779 780 /* Don't consider checksum. */ 781 --bytes; 782 783 while (bytes-- != 0) 784 { 785 contents[sofar] = HEX (data); 786 data += 2; 787 ++sofar; 788 } 789 790 break; 791 } 792 } 793 794 if (error) 795 goto error_return; 796 797 BFD_ASSERT (sofar == section->_raw_size); 798 799 if (buf != NULL) 800 free (buf); 801 802 return true; 803 804 error_return: 805 if (buf != NULL) 806 free (buf); 807 return false; 808} 809 810/* Get the contents of a section in an S-record file. */ 811 812static boolean 813srec_get_section_contents (abfd, section, location, offset, count) 814 bfd *abfd; 815 asection *section; 816 PTR location; 817 file_ptr offset; 818 bfd_size_type count; 819{ 820 if (section->used_by_bfd == NULL) 821 { 822 section->used_by_bfd = bfd_alloc (abfd, section->_raw_size); 823 if (section->used_by_bfd == NULL 824 && section->_raw_size != 0) 825 return false; 826 827 if (! srec_read_section (abfd, section, section->used_by_bfd)) 828 return false; 829 } 830 831 memcpy (location, (bfd_byte *) section->used_by_bfd + offset, 832 (size_t) count); 833 834 return true; 835} 836 837/* Set the architecture. We accept an unknown architecture here. */ 838 839static boolean 840srec_set_arch_mach (abfd, arch, mach) 841 bfd *abfd; 842 enum bfd_architecture arch; 843 unsigned long mach; 844{ 845 if (arch == bfd_arch_unknown) 846 { 847 abfd->arch_info = &bfd_default_arch_struct; 848 return true; 849 } 850 return bfd_default_set_arch_mach (abfd, arch, mach); 851} 852 853/* We have to save up all the Srecords for a splurge before output. */ 854 855static boolean 856srec_set_section_contents (abfd, section, location, offset, bytes_to_do) 857 bfd *abfd; 858 sec_ptr section; 859 PTR location; 860 file_ptr offset; 861 bfd_size_type bytes_to_do; 862{ 863 tdata_type *tdata = abfd->tdata.srec_data; 864 register srec_data_list_type *entry; 865 866 entry = ((srec_data_list_type *) 867 bfd_alloc (abfd, sizeof (srec_data_list_type))); 868 if (entry == NULL) 869 return false; 870 871 if (bytes_to_do 872 && (section->flags & SEC_ALLOC) 873 && (section->flags & SEC_LOAD)) 874 { 875 bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); 876 if (data == NULL) 877 return false; 878 memcpy ((PTR) data, location, (size_t) bytes_to_do); 879 880 /* Ff S3Forced is true then always select S3 records, 881 regardless of the siez of the addresses. */ 882 if (S3Forced) 883 tdata->type = 3; 884 else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff) 885 ; /* The default, S1, is OK. */ 886 else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff 887 && tdata->type <= 2) 888 tdata->type = 2; 889 else 890 tdata->type = 3; 891 892 entry->data = data; 893 entry->where = section->lma + offset; 894 entry->size = bytes_to_do; 895 896 /* Sort the records by address. Optimize for the common case of 897 adding a record to the end of the list. */ 898 if (tdata->tail != NULL 899 && entry->where >= tdata->tail->where) 900 { 901 tdata->tail->next = entry; 902 entry->next = NULL; 903 tdata->tail = entry; 904 } 905 else 906 { 907 register srec_data_list_type **look; 908 909 for (look = &tdata->head; 910 *look != NULL && (*look)->where < entry->where; 911 look = &(*look)->next) 912 ; 913 entry->next = *look; 914 *look = entry; 915 if (entry->next == NULL) 916 tdata->tail = entry; 917 } 918 } 919 return true; 920} 921 922/* Write a record of type, of the supplied number of bytes. The 923 supplied bytes and length don't have a checksum. That's worked out 924 here. */ 925 926static boolean 927srec_write_record (abfd, type, address, data, end) 928 bfd *abfd; 929 int type; 930 bfd_vma address; 931 const bfd_byte *data; 932 const bfd_byte *end; 933{ 934 char buffer[MAXCHUNK]; 935 unsigned int check_sum = 0; 936 CONST bfd_byte *src = data; 937 char *dst = buffer; 938 char *length; 939 bfd_size_type wrlen; 940 941 *dst++ = 'S'; 942 *dst++ = '0' + type; 943 944 length = dst; 945 dst += 2; /* Leave room for dst. */ 946 947 switch (type) 948 { 949 case 3: 950 case 7: 951 TOHEX (dst, (address >> 24), check_sum); 952 dst += 2; 953 case 8: 954 case 2: 955 TOHEX (dst, (address >> 16), check_sum); 956 dst += 2; 957 case 9: 958 case 1: 959 case 0: 960 TOHEX (dst, (address >> 8), check_sum); 961 dst += 2; 962 TOHEX (dst, (address), check_sum); 963 dst += 2; 964 break; 965 966 } 967 for (src = data; src < end; src++) 968 { 969 TOHEX (dst, *src, check_sum); 970 dst += 2; 971 } 972 973 /* Fill in the length. */ 974 TOHEX (length, (dst - length) / 2, check_sum); 975 check_sum &= 0xff; 976 check_sum = 255 - check_sum; 977 TOHEX (dst, check_sum, check_sum); 978 dst += 2; 979 980 *dst++ = '\r'; 981 *dst++ = '\n'; 982 wrlen = dst - buffer; 983 if (bfd_write ((PTR) buffer, 1, wrlen, abfd) != wrlen) 984 return false; 985 return true; 986} 987 988static boolean 989srec_write_header (abfd) 990 bfd *abfd; 991{ 992 bfd_byte buffer[MAXCHUNK]; 993 bfd_byte *dst = buffer; 994 unsigned int i; 995 996 /* I'll put an arbitary 40 char limit on header size. */ 997 for (i = 0; i < 40 && abfd->filename[i]; i++) 998 *dst++ = abfd->filename[i]; 999 1000 return srec_write_record (abfd, 0, 0, buffer, dst); 1001} 1002 1003static boolean 1004srec_write_section (abfd, tdata, list) 1005 bfd *abfd; 1006 tdata_type *tdata; 1007 srec_data_list_type *list; 1008{ 1009 unsigned int octets_written = 0; 1010 bfd_byte *location = list->data; 1011 1012 while (octets_written < list->size) 1013 { 1014 bfd_vma address; 1015 unsigned int octets_this_chunk = list->size - octets_written; 1016 1017 if (octets_this_chunk > Chunk) 1018 octets_this_chunk = Chunk; 1019 1020 address = list->where + octets_written / bfd_octets_per_byte (abfd); 1021 1022 if (! srec_write_record (abfd, 1023 tdata->type, 1024 address, 1025 location, 1026 location + octets_this_chunk)) 1027 return false; 1028 1029 octets_written += octets_this_chunk; 1030 location += octets_this_chunk; 1031 } 1032 1033 return true; 1034} 1035 1036static boolean 1037srec_write_terminator (abfd, tdata) 1038 bfd *abfd; 1039 tdata_type *tdata; 1040{ 1041 bfd_byte buffer[2]; 1042 1043 return srec_write_record (abfd, 10 - tdata->type, 1044 abfd->start_address, buffer, buffer); 1045} 1046 1047static boolean 1048srec_write_symbols (abfd) 1049 bfd *abfd; 1050{ 1051 char buffer[MAXCHUNK]; 1052 /* Dump out the symbols of a bfd. */ 1053 int i; 1054 int count = bfd_get_symcount (abfd); 1055 1056 if (count) 1057 { 1058 size_t len; 1059 asymbol **table = bfd_get_outsymbols (abfd); 1060 sprintf (buffer, "$$ %s\r\n", abfd->filename); 1061 1062 len = strlen (buffer); 1063 if (bfd_write (buffer, len, 1, abfd) != len) 1064 return false; 1065 1066 for (i = 0; i < count; i++) 1067 { 1068 asymbol *s = table[i]; 1069 if (! bfd_is_local_label (abfd, s) 1070 && (s->flags & BSF_DEBUGGING) == 0) 1071 { 1072 /* Just dump out non debug symbols. */ 1073 bfd_size_type l; 1074 char buf2[40], *p; 1075 1076 sprintf_vma (buf2, 1077 s->value + s->section->output_section->lma 1078 + s->section->output_offset); 1079 p = buf2; 1080 while (p[0] == '0' && p[1] != 0) 1081 p++; 1082 sprintf (buffer, " %s $%s\r\n", s->name, p); 1083 l = strlen (buffer); 1084 if (bfd_write (buffer, l, 1, abfd) != l) 1085 return false; 1086 } 1087 } 1088 sprintf (buffer, "$$ \r\n"); 1089 len = strlen (buffer); 1090 if (bfd_write (buffer, len, 1, abfd) != len) 1091 return false; 1092 } 1093 1094 return true; 1095} 1096 1097static boolean 1098internal_srec_write_object_contents (abfd, symbols) 1099 bfd *abfd; 1100 int symbols; 1101{ 1102 tdata_type *tdata = abfd->tdata.srec_data; 1103 srec_data_list_type *list; 1104 1105 if (symbols) 1106 { 1107 if (! srec_write_symbols (abfd)) 1108 return false; 1109 } 1110 1111 if (! srec_write_header (abfd)) 1112 return false; 1113 1114 /* Now wander though all the sections provided and output them. */ 1115 list = tdata->head; 1116 1117 while (list != (srec_data_list_type *) NULL) 1118 { 1119 if (! srec_write_section (abfd, tdata, list)) 1120 return false; 1121 list = list->next; 1122 } 1123 return srec_write_terminator (abfd, tdata); 1124} 1125 1126static boolean 1127srec_write_object_contents (abfd) 1128 bfd *abfd; 1129{ 1130 return internal_srec_write_object_contents (abfd, 0); 1131} 1132 1133static boolean 1134symbolsrec_write_object_contents (abfd) 1135 bfd *abfd; 1136{ 1137 return internal_srec_write_object_contents (abfd, 1); 1138} 1139 1140static int 1141srec_sizeof_headers (abfd, exec) 1142 bfd *abfd ATTRIBUTE_UNUSED; 1143 boolean exec ATTRIBUTE_UNUSED; 1144{ 1145 return 0; 1146} 1147 1148static asymbol * 1149srec_make_empty_symbol (abfd) 1150 bfd *abfd; 1151{ 1152 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); 1153 if (new) 1154 new->the_bfd = abfd; 1155 return new; 1156} 1157 1158/* Return the amount of memory needed to read the symbol table. */ 1159 1160static long 1161srec_get_symtab_upper_bound (abfd) 1162 bfd *abfd; 1163{ 1164 return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); 1165} 1166 1167/* Return the symbol table. */ 1168 1169static long 1170srec_get_symtab (abfd, alocation) 1171 bfd *abfd; 1172 asymbol **alocation; 1173{ 1174 unsigned int symcount = bfd_get_symcount (abfd); 1175 asymbol *csymbols; 1176 unsigned int i; 1177 1178 csymbols = abfd->tdata.srec_data->csymbols; 1179 if (csymbols == NULL) 1180 { 1181 asymbol *c; 1182 struct srec_symbol *s; 1183 1184 csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); 1185 if (csymbols == NULL && symcount != 0) 1186 return false; 1187 abfd->tdata.srec_data->csymbols = csymbols; 1188 1189 for (s = abfd->tdata.srec_data->symbols, c = csymbols; 1190 s != NULL; 1191 s = s->next, ++c) 1192 { 1193 c->the_bfd = abfd; 1194 c->name = s->name; 1195 c->value = s->val; 1196 c->flags = BSF_GLOBAL; 1197 c->section = bfd_abs_section_ptr; 1198 c->udata.p = NULL; 1199 } 1200 } 1201 1202 for (i = 0; i < symcount; i++) 1203 *alocation++ = csymbols++; 1204 *alocation = NULL; 1205 1206 return symcount; 1207} 1208 1209static void 1210srec_get_symbol_info (ignore_abfd, symbol, ret) 1211 bfd *ignore_abfd ATTRIBUTE_UNUSED; 1212 asymbol *symbol; 1213 symbol_info *ret; 1214{ 1215 bfd_symbol_info (symbol, ret); 1216} 1217 1218static void 1219srec_print_symbol (ignore_abfd, afile, symbol, how) 1220 bfd *ignore_abfd ATTRIBUTE_UNUSED; 1221 PTR afile; 1222 asymbol *symbol; 1223 bfd_print_symbol_type how; 1224{ 1225 FILE *file = (FILE *) afile; 1226 switch (how) 1227 { 1228 case bfd_print_symbol_name: 1229 fprintf (file, "%s", symbol->name); 1230 break; 1231 default: 1232 bfd_print_symbol_vandf ((PTR) file, symbol); 1233 fprintf (file, " %-5s %s", 1234 symbol->section->name, 1235 symbol->name); 1236 1237 } 1238} 1239 1240#define srec_close_and_cleanup _bfd_generic_close_and_cleanup 1241#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 1242#define srec_new_section_hook _bfd_generic_new_section_hook 1243 1244#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name 1245#define srec_get_lineno _bfd_nosymbols_get_lineno 1246#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line 1247#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 1248#define srec_read_minisymbols _bfd_generic_read_minisymbols 1249#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 1250 1251#define srec_get_reloc_upper_bound \ 1252 ((long (*) PARAMS ((bfd *, asection *))) bfd_0l) 1253#define srec_canonicalize_reloc \ 1254 ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l) 1255#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 1256 1257#define srec_get_section_contents_in_window \ 1258 _bfd_generic_get_section_contents_in_window 1259 1260#define srec_bfd_get_relocated_section_contents \ 1261 bfd_generic_get_relocated_section_contents 1262#define srec_bfd_relax_section bfd_generic_relax_section 1263#define srec_bfd_gc_sections bfd_generic_gc_sections 1264#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 1265#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols 1266#define srec_bfd_final_link _bfd_generic_final_link 1267#define srec_bfd_link_split_section _bfd_generic_link_split_section 1268 1269const bfd_target srec_vec = 1270{ 1271 "srec", /* name */ 1272 bfd_target_srec_flavour, 1273 BFD_ENDIAN_UNKNOWN, /* target byte order */ 1274 BFD_ENDIAN_UNKNOWN, /* target headers byte order */ 1275 (HAS_RELOC | EXEC_P | /* object flags */ 1276 HAS_LINENO | HAS_DEBUG | 1277 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1278 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 1279 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 1280 0, /* leading underscore */ 1281 ' ', /* ar_pad_char */ 1282 16, /* ar_max_namelen */ 1283 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1284 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1285 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ 1286 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1287 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1288 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ 1289 1290 { 1291 _bfd_dummy_target, 1292 srec_object_p, /* bfd_check_format */ 1293 _bfd_dummy_target, 1294 _bfd_dummy_target, 1295 }, 1296 { 1297 bfd_false, 1298 srec_mkobject, 1299 _bfd_generic_mkarchive, 1300 bfd_false, 1301 }, 1302 { /* bfd_write_contents */ 1303 bfd_false, 1304 srec_write_object_contents, 1305 _bfd_write_archive_contents, 1306 bfd_false, 1307 }, 1308 1309 BFD_JUMP_TABLE_GENERIC (srec), 1310 BFD_JUMP_TABLE_COPY (_bfd_generic), 1311 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1312 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), 1313 BFD_JUMP_TABLE_SYMBOLS (srec), 1314 BFD_JUMP_TABLE_RELOCS (srec), 1315 BFD_JUMP_TABLE_WRITE (srec), 1316 BFD_JUMP_TABLE_LINK (srec), 1317 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1318 1319 NULL, 1320 1321 (PTR) 0 1322}; 1323 1324const bfd_target symbolsrec_vec = 1325{ 1326 "symbolsrec", /* name */ 1327 bfd_target_srec_flavour, 1328 BFD_ENDIAN_UNKNOWN, /* target byte order */ 1329 BFD_ENDIAN_UNKNOWN, /* target headers byte order */ 1330 (HAS_RELOC | EXEC_P | /* object flags */ 1331 HAS_LINENO | HAS_DEBUG | 1332 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1333 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 1334 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 1335 0, /* leading underscore */ 1336 ' ', /* ar_pad_char */ 1337 16, /* ar_max_namelen */ 1338 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1339 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1340 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ 1341 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1342 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1343 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ 1344 1345 { 1346 _bfd_dummy_target, 1347 symbolsrec_object_p, /* bfd_check_format */ 1348 _bfd_dummy_target, 1349 _bfd_dummy_target, 1350 }, 1351 { 1352 bfd_false, 1353 srec_mkobject, 1354 _bfd_generic_mkarchive, 1355 bfd_false, 1356 }, 1357 { /* bfd_write_contents */ 1358 bfd_false, 1359 symbolsrec_write_object_contents, 1360 _bfd_write_archive_contents, 1361 bfd_false, 1362 }, 1363 1364 BFD_JUMP_TABLE_GENERIC (srec), 1365 BFD_JUMP_TABLE_COPY (_bfd_generic), 1366 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1367 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), 1368 BFD_JUMP_TABLE_SYMBOLS (srec), 1369 BFD_JUMP_TABLE_RELOCS (srec), 1370 BFD_JUMP_TABLE_WRITE (srec), 1371 BFD_JUMP_TABLE_LINK (srec), 1372 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1373 1374 NULL, 1375 1376 (PTR) 0 1377}; 1378