1 /* BFD back-end for s-record objects.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27 Ordinary S-Records cannot hold anything but addresses and
28 data, so that's all that we implement.
30 The only interesting thing is that S-Records may come out of
31 order and there is no header, so an initial scan is required
32 to discover the minimum and maximum addresses used to create
33 the vma and size of the only section we create. We
34 arbitrarily call this section ".text".
36 When bfd_get_section_contents is called the file is read
37 again, and this time the data is placed into a bfd_alloc'd
40 Any number of sections may be created for output, we save them
41 up and output them when it's time to close the bfd.
43 An s record looks like:
46 S<type><length><address><data><checksum>
51 is the number of bytes following upto the checksum. Note that
52 this is not the number of chars following, since it takes two
53 chars to represent a byte.
57 1) two byte address data record
58 2) three byte address data record
59 3) four byte address data record
60 7) four byte address termination record
61 8) three byte address termination record
62 9) two byte address termination record
65 is the start address of the data following, or in the case of
66 a termination record, the start address of the image
70 is the sum of all the raw byte data in the record, from the length
71 upwards, modulo 256 and subtracted from 255.
75 Symbol S-Record handling
78 Some ICE equipment understands an addition to the standard
79 S-Record format; symbols and their addresses can be sent
82 The format of this is:
84 (<space> <symbol> <address>)*)
87 so a short symbol table could look like:
101 We allow symbols to be anywhere in the data stream - the module names
110 /* Macros for converting between hex and binary */
112 static CONST char digs[] = "0123456789ABCDEF";
114 static char hex_value[1 + (unsigned char)~0];
117 #define NIBBLE(x) hex_value[(unsigned char)(x)]
118 #define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
119 #define TOHEX(d, x, ch) \
120 d[1] = digs[(x) & 0xf]; \
121 d[0] = digs[((x)>>4)&0xf]; \
123 #define ISHEX(x) (hex_value[(unsigned char)(x)] != NOT_HEX)
128 DEFUN_VOID(srec_init)
131 static boolean inited = false;
138 for (i = 0; i < sizeof (hex_value); i++)
140 hex_value[i] = NOT_HEX;
143 for (i = 0; i < 10; i++)
145 hex_value[i + '0'] = i;
148 for (i = 0; i < 6; i++)
150 hex_value[i + 'a'] = i+10;
151 hex_value[i + 'A'] = i+10;
157 /* The maximum number of bytes on a line is FF */
158 #define MAXCHUNK 0xff
159 /* The number of bytes we fit onto a line on output */
162 /* We cannot output our srecords as we see them, we have to glue them
163 together, this is done in this structure : */
165 struct srec_data_list_struct
170 struct srec_data_list_struct *next;
174 typedef struct srec_data_list_struct srec_data_list_type;
177 typedef struct srec_data_struct
179 srec_data_list_type *head;
182 int done_symbol_read;
193 called once per input S-Record, used to work out vma and size of data.
196 static bfd_vma low,high;
199 size_symbols(abfd, buf, len, val)
206 abfd->tdata.srec_data->string_size += len + 1;
210 fillup_symbols(abfd, buf, len, val)
216 if (!abfd->tdata.srec_data->done_symbol_read)
219 if (abfd->tdata.srec_data->symbols == 0)
221 abfd->tdata.srec_data->symbols = (asymbol *)bfd_alloc(abfd, abfd->symcount * sizeof(asymbol));
222 abfd->tdata.srec_data->strings = (char*)bfd_alloc(abfd, abfd->tdata.srec_data->string_size);
223 abfd->tdata.srec_data->symbol_idx = 0;
224 abfd->tdata.srec_data->string_idx = 0;
227 p = abfd->tdata.srec_data->symbols + abfd->tdata.srec_data->symbol_idx++;
229 p->name = abfd->tdata.srec_data->strings + abfd->tdata.srec_data->string_idx;
230 memcpy((char *)(p->name), buf, len+1);
231 abfd->tdata.srec_data->string_idx += len + 1;
233 p->flags = BSF_EXPORT | BSF_GLOBAL;
234 p->section = &bfd_abs_section;
239 DEFUN(size_srec,(abfd, section, address, raw, length),
241 asection *section AND
248 if (address + length > high)
249 high = address + length -1;
254 called once per input S-Record, copies data from input into bfd_alloc'd area
258 DEFUN(fillup,(abfd, section, address, raw, length),
260 asection *section AND
267 (bfd_byte *)(section->used_by_bfd) + address - section->vma;
268 /* length -1 because we don't read in the checksum */
269 for (i = 0; i < length -1 ; i++) {
276 /* Pass over an S-Record file, calling one of the above functions on each
282 return (x== ' ' || x == '\t' || x == '\n' || x == '\r');
290 while (white(*src) && !eof)
292 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
298 DEFUN(srec_mkobject, (abfd),
301 if (abfd->tdata.srec_data == 0)
303 tdata_type *tdata = (tdata_type *)bfd_alloc(abfd, sizeof(tdata_type));
304 abfd->tdata.srec_data = tdata;
306 tdata->head = (srec_data_list_type *)NULL;
313 DEFUN(pass_over,(abfd, func, symbolfunc, section),
316 void (*symbolfunc)() AND
319 unsigned int bytes_on_line;
323 /* To the front of the file */
324 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
327 char buffer[MAXCHUNK];
332 /* Find first 'S' or $ */
333 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
337 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
342 /* Inside a symbol definition - just ignore the module name */
343 while (*src != '\n' && !eof)
345 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
350 /* spaces - maybe just before a symbol */
351 while (*src != '\n' && white(*src)) {
352 eof = skipwhite(src, abfd);
357 char symbol[MAXCHUNK];
359 /* get the symbol part */
360 while (!eof && !white(*src) && slen < MAXCHUNK)
362 symbol[slen++] = *src;
363 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
366 eof = skipwhite(src, abfd);
367 /* skip the $ for the hex value */
370 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
373 /* Scan off the hex number */
374 while (isxdigit(*src ))
379 else if (isupper(*src)) {
380 val += *src - 'A' + 10;
383 val += *src - 'a' + 10;
385 eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
387 symbolfunc(abfd, symbol, slen, val);
394 /* Fetch the type and the length */
395 bfd_read(src, 1, 3, abfd);
399 if (!ISHEX (src[0]) || !ISHEX (src[1]))
402 bytes_on_line = HEX(src);
404 if (bytes_on_line > MAXCHUNK/2)
408 bfd_read(src, 1 , bytes_on_line * 2, abfd);
413 /* Prologue - ignore */
421 address = HEX(src) | (address<<8) ;
425 address = HEX(src) | (address<<8) ;
427 address = HEX(src) | (address<<8) ;
430 func(abfd,section, address, src, bytes_on_line);
445 /* We create one section called .text for all the contents,
446 and allocate enough room for the entire file. */
448 section = bfd_make_section(abfd, ".text");
449 section->_raw_size = 0;
450 section->vma = 0xffffffff;
453 pass_over(abfd, size_srec, size_symbols, section);
454 section->_raw_size = high - low;
456 section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
459 abfd->flags |= HAS_SYMS;
464 DEFUN(srec_object_p, (abfd),
471 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
472 bfd_read(b, 1, 4, abfd);
474 if (b[0] != 'S' || !ISHEX(b[1]) || !ISHEX(b[2]) || !ISHEX(b[3]))
475 return (bfd_target*) NULL;
477 /* We create one section called .text for all the contents,
478 and allocate enough room for the entire file. */
480 return object_p(abfd);
485 DEFUN(symbolsrec_object_p, (abfd),
492 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
493 bfd_read(b, 1, 4, abfd);
495 if (b[0] != '$' || b[1] != '$')
496 return (bfd_target*) NULL;
498 return object_p(abfd);
503 DEFUN(srec_get_section_contents,(abfd, section, location, offset, count),
505 asection *section AND
510 if (section->used_by_bfd == (PTR)NULL)
512 section->used_by_bfd = (PTR)bfd_alloc (abfd, section->_raw_size);
514 pass_over(abfd, fillup, fillup_symbols, section);
516 (void) memcpy((PTR)location,
517 (PTR)((char *)(section->used_by_bfd) + offset),
525 DEFUN(srec_set_arch_mach,(abfd, arch, machine),
527 enum bfd_architecture arch AND
528 unsigned long machine)
530 return bfd_default_set_arch_mach(abfd, arch, machine);
534 /* we have to save up all the Srecords for a splurge before output,
538 DEFUN(srec_set_section_contents,(abfd, section, location, offset, bytes_to_do),
543 bfd_size_type bytes_to_do)
545 tdata_type *tdata = abfd->tdata.srec_data;
546 srec_data_list_type *entry = (srec_data_list_type *)
547 bfd_alloc(abfd, sizeof(srec_data_list_type));
549 if ((section->flags & SEC_ALLOC)
550 && (section->flags & SEC_LOAD))
552 unsigned char *data = (unsigned char *) bfd_alloc(abfd, bytes_to_do);
553 memcpy(data, location, bytes_to_do);
555 if ((section->lma + offset + bytes_to_do) <= 0xffff)
559 else if ((section->lma + offset + bytes_to_do) <= 0xffffff
570 entry->where = section->lma + offset;
571 entry->size = bytes_to_do;
572 entry->next = tdata->head;
578 /* Write a record of type, of the supplied number of bytes. The
579 supplied bytes and length don't have a checksum. That's worked out
583 void DEFUN(srec_write_record,(abfd, type, address, data, end),
587 CONST unsigned char *data AND
588 CONST unsigned char *end)
591 char buffer[MAXCHUNK];
593 unsigned int check_sum = 0;
594 unsigned CONST char *src = data;
603 dst+=2; /* leave room for dst*/
609 TOHEX(dst, (address >> 24), check_sum);
613 TOHEX(dst, (address >> 16), check_sum);
618 TOHEX(dst, (address >> 8), check_sum);
620 TOHEX(dst, (address), check_sum);
625 for (src = data; src < end; src++)
627 TOHEX(dst, *src, check_sum);
631 /* Fill in the length */
632 TOHEX(length, (dst - length)/2, check_sum);
634 check_sum = 255 - check_sum;
635 TOHEX(dst, check_sum, check_sum);
640 bfd_write((PTR)buffer, 1, dst - buffer , abfd);
646 DEFUN(srec_write_header,(abfd),
649 unsigned char buffer[MAXCHUNK];
650 unsigned char *dst = buffer;
653 /* I'll put an arbitary 40 char limit on header size */
654 for (i = 0; i < 40 && abfd->filename[i]; i++)
656 *dst++ = abfd->filename[i];
658 srec_write_record(abfd,0, 0, buffer, dst);
662 DEFUN(srec_write_section,(abfd, tdata, list),
664 tdata_type *tdata AND
665 srec_data_list_type *list)
667 unsigned int bytes_written = 0;
668 unsigned char *location = list->data;
670 while (bytes_written < list->size)
674 unsigned int bytes_this_chunk = list->size - bytes_written;
676 if (bytes_this_chunk > CHUNK)
678 bytes_this_chunk = CHUNK;
681 address = list->where + bytes_written;
683 srec_write_record(abfd,
687 location + bytes_this_chunk);
689 bytes_written += bytes_this_chunk;
690 location += bytes_this_chunk;
696 DEFUN(srec_write_terminator,(abfd, tdata),
700 unsigned char buffer[2];
702 srec_write_record(abfd, 10 - tdata->type,
703 abfd->start_address, buffer, buffer);
709 srec_write_symbols(abfd)
712 char buffer[MAXCHUNK];
713 /* Dump out the symbols of a bfd */
715 int len = bfd_get_symcount(abfd);
719 asymbol **table = bfd_get_outsymbols(abfd);
720 sprintf(buffer, "$$ %s\r\n", abfd->filename);
722 bfd_write(buffer, strlen(buffer), 1, abfd);
724 for (i = 0; i < len; i++)
726 asymbol *s = table[i];
728 int len = strlen(s->name);
730 /* If this symbol has a .[ocs] in it, it's probably a file name
731 and we'll output that as the module name */
733 if (len > 3 && s->name[len-2] == '.')
736 sprintf(buffer, "$$ %s\n\r", s->name);
738 bfd_write(buffer, l, 1, abfd);
742 if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
743 && (s->flags & BSF_DEBUGGING) == 0
745 && s->name[0] != 't')
747 /* Just dump out non debug symbols */
752 sprintf (buffer," %s $", s->name);
753 sprintf_vma (buf2, s->value + s->section->lma);
755 while (p[0] == '0' && p[1] != 0)
758 strcat (buffer, "\n\r");
760 bfd_write(buffer, l, 1,abfd);
763 sprintf(buffer, "$$ \r\n");
764 bfd_write(buffer, strlen(buffer), 1, abfd);
769 internal_srec_write_object_contents(abfd, symbols)
774 tdata_type *tdata = abfd->tdata.srec_data;
775 srec_data_list_type *list;
781 srec_write_symbols(abfd);
783 srec_write_header(abfd);
785 /* Now wander though all the sections provided and output them */
788 while (list != (srec_data_list_type*)NULL)
790 srec_write_section(abfd, tdata, list);
793 srec_write_terminator(abfd, tdata);
798 srec_write_object_contents(abfd)
801 return internal_srec_write_object_contents(abfd, 0);
805 symbolsrec_write_object_contents(abfd)
808 return internal_srec_write_object_contents(abfd, 1);
812 DEFUN(srec_sizeof_headers,(abfd, exec),
820 DEFUN(srec_make_empty_symbol, (abfd),
823 asymbol *new= (asymbol *)bfd_zalloc (abfd, sizeof (asymbol));
829 srec_get_symtab_upper_bound(abfd)
832 /* Read in all the info */
833 srec_get_section_contents(abfd,abfd->sections,0,0,0);
834 return (bfd_get_symcount(abfd) + 1) * (sizeof(asymbol *));
838 DEFUN(srec_get_symtab, (abfd, alocation),
842 int lim = abfd->symcount;
844 for (i = 0; i < lim; i++) {
845 alocation[i] = abfd->tdata.srec_data->symbols + i;
852 DEFUN(srec_get_symbol_info,(ignore_abfd, symbol, ret),
857 bfd_symbol_info (symbol, ret);
861 DEFUN(srec_print_symbol,(ignore_abfd, afile, symbol, how),
865 bfd_print_symbol_type how)
867 FILE *file = (FILE *)afile;
870 case bfd_print_symbol_name:
871 fprintf (file, "%s", symbol->name);
874 bfd_print_symbol_vandf ((PTR) file, symbol);
875 fprintf (file, " %-5s %s",
876 symbol->section->name,
883 #define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
885 #define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
886 #define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
890 #define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
891 #define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
892 #define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0
895 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
896 #define srec_core_file_failing_signal (int (*)())bfd_0
897 #define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
898 #define srec_slurp_armap bfd_true
899 #define srec_slurp_extended_name_table bfd_true
900 #define srec_truncate_arname (void (*)())bfd_nullvoidptr
901 #define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
902 #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
903 #define srec_close_and_cleanup bfd_generic_close_and_cleanup
904 #define srec_bfd_debug_info_start bfd_void
905 #define srec_bfd_debug_info_end bfd_void
906 #define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void
907 #define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
908 #define srec_bfd_relax_section bfd_generic_relax_section
909 #define srec_bfd_seclet_link bfd_generic_seclet_link
910 #define srec_bfd_reloc_type_lookup \
911 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
912 #define srec_bfd_make_debug_symbol \
913 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
915 bfd_target srec_vec =
918 bfd_target_srec_flavour,
919 true, /* target byte order */
920 true, /* target headers byte order */
921 (HAS_RELOC | EXEC_P | /* object flags */
922 HAS_LINENO | HAS_DEBUG |
923 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
924 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
925 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
926 0, /* leading underscore */
927 ' ', /* ar_pad_char */
928 16, /* ar_max_namelen */
929 1, /* minimum alignment */
930 _do_getb64, _do_getb_signed_64, _do_putb64,
931 _do_getb32, _do_getb_signed_32, _do_putb32,
932 _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
933 _do_getb64, _do_getb_signed_64, _do_putb64,
934 _do_getb32, _do_getb_signed_32, _do_putb32,
935 _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
939 srec_object_p, /* bfd_check_format */
940 (struct bfd_target *(*)()) bfd_nullvoidptr,
941 (struct bfd_target *(*)()) bfd_nullvoidptr,
946 _bfd_generic_mkarchive,
949 { /* bfd_write_contents */
951 srec_write_object_contents,
952 _bfd_write_archive_contents,
960 bfd_target symbolsrec_vec =
962 "symbolsrec", /* name */
963 bfd_target_srec_flavour,
964 true, /* target byte order */
965 true, /* target headers byte order */
966 (HAS_RELOC | EXEC_P | /* object flags */
967 HAS_LINENO | HAS_DEBUG |
968 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
969 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
970 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
971 0, /* leading underscore */
972 ' ', /* ar_pad_char */
973 16, /* ar_max_namelen */
974 1, /* minimum alignment */
975 _do_getb64, _do_getb_signed_64, _do_putb64,
976 _do_getb32, _do_getb_signed_32, _do_putb32,
977 _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
978 _do_getb64, _do_getb_signed_64, _do_putb64,
979 _do_getb32, _do_getb_signed_32, _do_putb32,
980 _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
984 symbolsrec_object_p, /* bfd_check_format */
985 (struct bfd_target *(*)()) bfd_nullvoidptr,
986 (struct bfd_target *(*)()) bfd_nullvoidptr,
991 _bfd_generic_mkarchive,
994 { /* bfd_write_contents */
996 symbolsrec_write_object_contents,
997 _bfd_write_archive_contents,