1 /* BFD back-end for s-record objects.
2 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
3 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
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 static boolean srec_write_record
PARAMS ((bfd
*, int, bfd_vma
,
111 const unsigned char *,
112 const unsigned char *));
113 static boolean srec_write_header
PARAMS ((bfd
*));
114 static boolean srec_write_symbols
PARAMS ((bfd
*));
116 /* Macros for converting between hex and binary. */
118 static CONST
char digs
[] = "0123456789ABCDEF";
120 /* Table that gets filled in with numbers corresponding to hex chars. */
122 static char hex_value
[256];
125 #define NIBBLE(x) hex_value[(unsigned char)(x)]
126 #define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
127 #define TOHEX(d, x, ch) \
128 d[1] = digs[(x) & 0xf]; \
129 d[0] = digs[((x)>>4)&0xf]; \
131 #define ISHEX(x) (hex_value[(unsigned char)(x)] != NOT_HEX)
133 /* Initialize by filling in the hex conversion array. */
139 static boolean inited
= false;
145 for (i
= 0; i
< sizeof (hex_value
); i
++)
147 hex_value
[i
] = NOT_HEX
;
149 for (i
= 0; i
< 10; i
++)
151 hex_value
[i
+ '0'] = i
;
153 for (i
= 0; i
< 6; i
++)
155 hex_value
[i
+ 'a'] = i
+ 10;
156 hex_value
[i
+ 'A'] = i
+ 10;
162 /* The maximum number of bytes on a line is FF */
163 #define MAXCHUNK 0xff
164 /* The number of bytes we fit onto a line on output */
167 /* We cannot output our srecords as we see them, we have to glue them
168 together, this is done in this structure : */
170 struct srec_data_list_struct
175 struct srec_data_list_struct
*next
;
179 typedef struct srec_data_list_struct srec_data_list_type
;
182 typedef struct srec_data_struct
184 srec_data_list_type
*head
;
187 int done_symbol_read
;
197 static boolean srec_write_section
PARAMS ((bfd
*, tdata_type
*,
198 srec_data_list_type
*));
199 static boolean srec_write_terminator
PARAMS ((bfd
*, tdata_type
*));
202 called once per input S-Record, used to work out vma and size of data.
205 static bfd_vma low
, high
;
209 size_symbols (abfd
, buf
, len
, val
)
216 abfd
->tdata
.srec_data
->string_size
+= len
+ 1;
220 fillup_symbols (abfd
, buf
, len
, val
)
226 if (!abfd
->tdata
.srec_data
->done_symbol_read
)
229 if (abfd
->tdata
.srec_data
->symbols
== 0)
231 abfd
->tdata
.srec_data
->symbols
= (asymbol
*) bfd_alloc (abfd
, abfd
->symcount
* sizeof (asymbol
));
232 abfd
->tdata
.srec_data
->strings
= (char *) bfd_alloc (abfd
, abfd
->tdata
.srec_data
->string_size
);
233 if (!abfd
->tdata
.srec_data
->symbols
|| !abfd
->tdata
.srec_data
->strings
)
235 bfd_set_error (bfd_error_no_memory
);
236 abort (); /* FIXME */
238 abfd
->tdata
.srec_data
->symbol_idx
= 0;
239 abfd
->tdata
.srec_data
->string_idx
= 0;
242 p
= abfd
->tdata
.srec_data
->symbols
+ abfd
->tdata
.srec_data
->symbol_idx
++;
244 p
->name
= abfd
->tdata
.srec_data
->strings
+ abfd
->tdata
.srec_data
->string_idx
;
245 memcpy ((char *) (p
->name
), buf
, len
+ 1);
246 abfd
->tdata
.srec_data
->string_idx
+= len
+ 1;
248 p
->flags
= BSF_EXPORT
| BSF_GLOBAL
;
249 p
->section
= bfd_abs_section_ptr
;
255 size_srec (abfd
, section
, address
, raw
, length
)
264 if (address
+ length
> high
)
265 high
= address
+ length
- 1;
270 called once per input S-Record, copies data from input into bfd_alloc'd area
275 fillup (abfd
, section
, address
, raw
, length
)
284 (bfd_byte
*) (section
->used_by_bfd
) + address
- section
->vma
;
285 /* length -1 because we don't read in the checksum */
286 for (i
= 0; i
< length
- 1; i
++)
294 /* Pass over an S-Record file, calling one of the above functions on each
301 return (x
== ' ' || x
== '\t' || x
== '\n' || x
== '\r');
304 skipwhite (src
, abfd
)
309 while (white (*src
) && !eof
)
311 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
320 if (abfd
->tdata
.srec_data
== 0)
322 tdata_type
*tdata
= (tdata_type
*) bfd_alloc (abfd
, sizeof (tdata_type
));
325 bfd_set_error (bfd_error_no_memory
);
328 abfd
->tdata
.srec_data
= tdata
;
330 tdata
->head
= (srec_data_list_type
*) NULL
;
337 pass_over (abfd
, func
, symbolfunc
, section
)
340 void (*symbolfunc
) ();
343 unsigned int bytes_on_line
;
346 srec_mkobject (abfd
);
347 /* To the front of the file */
348 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
352 char buffer
[MAXCHUNK
];
357 /* Find first 'S' or $ */
358 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
367 /* Inside a symbol definition - just ignore the module name */
368 while (*src
!= '\n' && !eof
)
370 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
375 /* spaces - maybe just before a symbol */
376 while (*src
!= '\n' && *src
!= '\r' && white (*src
))
378 eof
= skipwhite (src
, abfd
);
383 char symbol
[MAXCHUNK
];
385 /* get the symbol part */
386 while (!eof
&& !white (*src
) && slen
< MAXCHUNK
)
388 symbol
[slen
++] = *src
;
389 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
392 eof
= skipwhite (src
, abfd
);
393 /* skip the $ for the hex value */
396 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
399 /* Scan off the hex number */
400 while (isxdigit (*src
))
405 else if (isupper (*src
))
407 val
+= *src
- 'A' + 10;
411 val
+= *src
- 'a' + 10;
413 eof
= (boolean
) (bfd_read (src
, 1, 1, abfd
) != 1);
415 symbolfunc (abfd
, symbol
, slen
, val
);
422 /* Fetch the type and the length */
423 if (bfd_read (src
, 1, 3, abfd
) != 3)
424 abort (); /* FIXME */
428 if (!ISHEX (src
[0]) || !ISHEX (src
[1]))
431 bytes_on_line
= HEX (src
);
433 if (bytes_on_line
> MAXCHUNK
/ 2)
437 if (bfd_read (src
, 1, bytes_on_line
* 2, abfd
) != bytes_on_line
* 2)
438 abort (); /* FIXME */
444 /* Prologue - ignore */
452 address
= HEX (src
) | (address
<< 8);
456 address
= HEX (src
) | (address
<< 8);
458 address
= HEX (src
) | (address
<< 8);
461 func (abfd
, section
, address
, src
, bytes_on_line
);
469 address
= HEX (src
) | (address
<< 8);
473 address
= HEX (src
) | (address
<< 8);
475 address
= HEX (src
) | (address
<< 8);
478 abfd
->start_address
= address
;
489 static const bfd_target
*
494 /* We create one section called .text for all the contents,
495 and allocate enough room for the entire file. */
497 section
= bfd_make_section (abfd
, ".text");
498 section
->_raw_size
= 0;
499 section
->vma
= 0xffffffff;
502 pass_over (abfd
, size_srec
, size_symbols
, section
);
503 section
->_raw_size
= high
- low
;
505 section
->flags
= SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
;
508 abfd
->flags
|= HAS_SYMS
;
512 static const bfd_target
*
520 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0
521 || bfd_read (b
, 1, 4, abfd
) != 4)
524 if (b
[0] != 'S' || !ISHEX (b
[1]) || !ISHEX (b
[2]) || !ISHEX (b
[3]))
525 return (const bfd_target
*) NULL
;
527 /* We create one section called .text for all the contents,
528 and allocate enough room for the entire file. */
530 return object_p (abfd
);
534 static const bfd_target
*
535 symbolsrec_object_p (abfd
)
542 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0
543 || bfd_read (b
, 1, 4, abfd
) != 4)
546 if (b
[0] != '$' || b
[1] != '$')
547 return (const bfd_target
*) NULL
;
549 return object_p (abfd
);
554 srec_get_section_contents (abfd
, section
, location
, offset
, count
)
561 if (section
->used_by_bfd
== (PTR
) NULL
)
563 section
->used_by_bfd
= (PTR
) bfd_alloc (abfd
, section
->_raw_size
);
564 if (!section
->used_by_bfd
)
566 bfd_set_error (bfd_error_no_memory
);
570 pass_over (abfd
, fillup
, fillup_symbols
, section
);
572 memcpy ((PTR
) location
,
573 (PTR
) ((char *) (section
->used_by_bfd
) + offset
),
581 srec_set_arch_mach (abfd
, arch
, machine
)
583 enum bfd_architecture arch
;
584 unsigned long machine
;
586 return bfd_default_set_arch_mach (abfd
, arch
, machine
);
590 /* we have to save up all the Srecords for a splurge before output,
594 srec_set_section_contents (abfd
, section
, location
, offset
, bytes_to_do
)
599 bfd_size_type bytes_to_do
;
601 tdata_type
*tdata
= abfd
->tdata
.srec_data
;
602 srec_data_list_type
*entry
= (srec_data_list_type
*)
603 bfd_alloc (abfd
, sizeof (srec_data_list_type
));
607 bfd_set_error (bfd_error_no_memory
);
611 if ((section
->flags
& SEC_ALLOC
)
612 && (section
->flags
& SEC_LOAD
))
614 unsigned char *data
= (unsigned char *) bfd_alloc (abfd
, bytes_to_do
);
617 bfd_set_error (bfd_error_no_memory
);
620 memcpy ((PTR
) data
, location
, bytes_to_do
);
622 if ((section
->lma
+ offset
+ bytes_to_do
) <= 0xffff)
626 else if ((section
->lma
+ offset
+ bytes_to_do
) <= 0xffffff
637 entry
->where
= section
->lma
+ offset
;
638 entry
->size
= bytes_to_do
;
639 entry
->next
= tdata
->head
;
645 /* Write a record of type, of the supplied number of bytes. The
646 supplied bytes and length don't have a checksum. That's worked out
650 srec_write_record (abfd
, type
, address
, data
, end
)
654 const unsigned char *data
;
655 const unsigned char *end
;
657 char buffer
[MAXCHUNK
];
659 unsigned int check_sum
= 0;
660 CONST
unsigned char *src
= data
;
669 dst
+= 2; /* leave room for dst*/
675 TOHEX (dst
, (address
>> 24), check_sum
);
679 TOHEX (dst
, (address
>> 16), check_sum
);
684 TOHEX (dst
, (address
>> 8), check_sum
);
686 TOHEX (dst
, (address
), check_sum
);
691 for (src
= data
; src
< end
; src
++)
693 TOHEX (dst
, *src
, check_sum
);
697 /* Fill in the length */
698 TOHEX (length
, (dst
- length
) / 2, check_sum
);
700 check_sum
= 255 - check_sum
;
701 TOHEX (dst
, check_sum
, check_sum
);
706 if (bfd_write ((PTR
) buffer
, 1, dst
- buffer
, abfd
) != dst
- buffer
)
714 srec_write_header (abfd
)
717 unsigned char buffer
[MAXCHUNK
];
718 unsigned char *dst
= buffer
;
721 /* I'll put an arbitary 40 char limit on header size */
722 for (i
= 0; i
< 40 && abfd
->filename
[i
]; i
++)
724 *dst
++ = abfd
->filename
[i
];
726 return srec_write_record (abfd
, 0, 0, buffer
, dst
);
730 srec_write_section (abfd
, tdata
, list
)
733 srec_data_list_type
*list
;
735 unsigned int bytes_written
= 0;
736 unsigned char *location
= list
->data
;
738 while (bytes_written
< list
->size
)
742 unsigned int bytes_this_chunk
= list
->size
- bytes_written
;
744 if (bytes_this_chunk
> CHUNK
)
746 bytes_this_chunk
= CHUNK
;
749 address
= list
->where
+ bytes_written
;
751 if (! srec_write_record (abfd
,
755 location
+ bytes_this_chunk
))
758 bytes_written
+= bytes_this_chunk
;
759 location
+= bytes_this_chunk
;
766 srec_write_terminator (abfd
, tdata
)
770 unsigned char buffer
[2];
772 return srec_write_record (abfd
, 10 - tdata
->type
,
773 abfd
->start_address
, buffer
, buffer
);
779 srec_write_symbols (abfd
)
782 char buffer
[MAXCHUNK
];
783 /* Dump out the symbols of a bfd */
785 int count
= bfd_get_symcount (abfd
);
790 asymbol
**table
= bfd_get_outsymbols (abfd
);
791 sprintf (buffer
, "$$ %s\r\n", abfd
->filename
);
793 len
= strlen (buffer
);
794 if (bfd_write (buffer
, len
, 1, abfd
) != len
)
797 for (i
= 0; i
< count
; i
++)
799 asymbol
*s
= table
[i
];
801 int len
= strlen (s
->name
);
803 /* If this symbol has a .[ocs] in it, it's probably a file name
804 and we'll output that as the module name */
806 if (len
> 3 && s
->name
[len
- 2] == '.')
809 sprintf (buffer
, "$$ %s\r\n", s
->name
);
811 if (bfd_write (buffer
, l
, 1, abfd
) != l
)
816 if (s
->flags
& (BSF_GLOBAL
| BSF_LOCAL
)
817 && (s
->flags
& BSF_DEBUGGING
) == 0
819 && s
->name
[0] != 't')
821 /* Just dump out non debug symbols */
827 s
->value
+ s
->section
->output_section
->lma
828 + s
->section
->output_offset
);
830 while (p
[0] == '0' && p
[1] != 0)
832 sprintf (buffer
, " %s $%s\r\n", s
->name
, p
);
834 if (bfd_write (buffer
, l
, 1, abfd
) != l
)
838 sprintf (buffer
, "$$ \r\n");
839 len
= strlen (buffer
);
840 if (bfd_write (buffer
, len
, 1, abfd
) != len
)
848 internal_srec_write_object_contents (abfd
, symbols
)
852 tdata_type
*tdata
= abfd
->tdata
.srec_data
;
853 srec_data_list_type
*list
;
857 if (! srec_write_symbols (abfd
))
861 if (! srec_write_header (abfd
))
864 /* Now wander though all the sections provided and output them */
867 while (list
!= (srec_data_list_type
*) NULL
)
869 if (! srec_write_section (abfd
, tdata
, list
))
873 return srec_write_terminator (abfd
, tdata
);
877 srec_write_object_contents (abfd
)
880 return internal_srec_write_object_contents (abfd
, 0);
884 symbolsrec_write_object_contents (abfd
)
887 return internal_srec_write_object_contents (abfd
, 1);
892 srec_sizeof_headers (abfd
, exec
)
900 srec_make_empty_symbol (abfd
)
903 asymbol
*new = (asymbol
*) bfd_zalloc (abfd
, sizeof (asymbol
));
910 srec_get_symtab_upper_bound (abfd
)
913 /* Read in all the info */
914 if (! srec_get_section_contents (abfd
, abfd
->sections
, 0, 0, 0))
916 return (bfd_get_symcount (abfd
) + 1) * (sizeof (asymbol
*));
920 srec_get_symtab (abfd
, alocation
)
924 int lim
= abfd
->symcount
;
926 for (i
= 0; i
< lim
; i
++)
928 alocation
[i
] = abfd
->tdata
.srec_data
->symbols
+ i
;
936 srec_get_symbol_info (ignore_abfd
, symbol
, ret
)
941 bfd_symbol_info (symbol
, ret
);
946 srec_print_symbol (ignore_abfd
, afile
, symbol
, how
)
950 bfd_print_symbol_type how
;
952 FILE *file
= (FILE *) afile
;
955 case bfd_print_symbol_name
:
956 fprintf (file
, "%s", symbol
->name
);
959 bfd_print_symbol_vandf ((PTR
) file
, symbol
);
960 fprintf (file
, " %-5s %s",
961 symbol
->section
->name
,
967 #define srec_close_and_cleanup _bfd_generic_close_and_cleanup
968 #define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
969 #define srec_new_section_hook _bfd_generic_new_section_hook
971 #define srec_bfd_is_local_label bfd_generic_is_local_label
972 #define srec_get_lineno _bfd_nosymbols_get_lineno
973 #define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
974 #define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
976 #define srec_bfd_get_relocated_section_contents \
977 bfd_generic_get_relocated_section_contents
978 #define srec_bfd_relax_section bfd_generic_relax_section
979 #define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
980 #define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
981 #define srec_bfd_final_link _bfd_generic_final_link
983 const bfd_target srec_vec
=
986 bfd_target_srec_flavour
,
987 true, /* target byte order */
988 true, /* target headers byte order */
989 (HAS_RELOC
| EXEC_P
| /* object flags */
990 HAS_LINENO
| HAS_DEBUG
|
991 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
992 (SEC_CODE
| SEC_DATA
| SEC_ROM
| SEC_HAS_CONTENTS
993 | SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
994 0, /* leading underscore */
995 ' ', /* ar_pad_char */
996 16, /* ar_max_namelen */
997 1, /* minimum alignment */
998 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
999 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1000 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
1001 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1002 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1003 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
1007 srec_object_p
, /* bfd_check_format */
1014 _bfd_generic_mkarchive
,
1017 { /* bfd_write_contents */
1019 srec_write_object_contents
,
1020 _bfd_write_archive_contents
,
1024 BFD_JUMP_TABLE_GENERIC (srec
),
1025 BFD_JUMP_TABLE_COPY (_bfd_generic
),
1026 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
1027 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive
),
1028 BFD_JUMP_TABLE_SYMBOLS (srec
),
1029 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs
),
1030 BFD_JUMP_TABLE_WRITE (srec
),
1031 BFD_JUMP_TABLE_LINK (srec
),
1032 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
1039 const bfd_target symbolsrec_vec
=
1041 "symbolsrec", /* name */
1042 bfd_target_srec_flavour
,
1043 true, /* target byte order */
1044 true, /* target headers byte order */
1045 (HAS_RELOC
| EXEC_P
| /* object flags */
1046 HAS_LINENO
| HAS_DEBUG
|
1047 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
1048 (SEC_CODE
| SEC_DATA
| SEC_ROM
| SEC_HAS_CONTENTS
1049 | SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
1050 0, /* leading underscore */
1051 ' ', /* ar_pad_char */
1052 16, /* ar_max_namelen */
1053 1, /* minimum alignment */
1054 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1055 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1056 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
1057 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1058 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1059 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
1063 symbolsrec_object_p
, /* bfd_check_format */
1070 _bfd_generic_mkarchive
,
1073 { /* bfd_write_contents */
1075 symbolsrec_write_object_contents
,
1076 _bfd_write_archive_contents
,
1080 BFD_JUMP_TABLE_GENERIC (srec
),
1081 BFD_JUMP_TABLE_COPY (_bfd_generic
),
1082 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
1083 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive
),
1084 BFD_JUMP_TABLE_SYMBOLS (srec
),
1085 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs
),
1086 BFD_JUMP_TABLE_WRITE (srec
),
1087 BFD_JUMP_TABLE_LINK (srec
),
1088 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),