2001-01-01 Philip Blundell <philb@gnu.org>
[binutils.git] / bfd / srec.c
blob56022392421542a6b7a5b8116bac2bb4f3789e1b
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>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 SUBSECTION
24 S-Record handling
26 DESCRIPTION
28 Ordinary S-Records cannot hold anything but addresses and
29 data, so that's all that we implement.
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".
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.
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.
44 An s record looks like:
46 EXAMPLE
47 S<type><length><address><data><checksum>
49 DESCRIPTION
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
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.
74 SUBSECTION
75 Symbol S-Record handling
77 DESCRIPTION
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.
82 The format of this is:
83 ($$ <modulename>
84 (<space> <symbol> <address>)*)
87 so a short symbol table could look like:
89 EXAMPLE
90 $$ flash.x
91 $$ flash.c
92 _port6 $0
93 _delay $4
94 _start $14
95 _etext $8036
96 _edata $8036
97 _end $8036
100 DESCRIPTION
101 We allow symbols to be anywhere in the data stream - the module names
102 are always ignored.
106 #include "bfd.h"
107 #include "sysdep.h"
108 #include "libbfd.h"
109 #include "libiberty.h"
110 #include <ctype.h>
112 static void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
113 static void srec_print_symbol
114 PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
115 static void srec_init PARAMS ((void));
116 static boolean srec_mkobject PARAMS ((bfd *));
117 static int srec_get_byte PARAMS ((bfd *, boolean *));
118 static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
119 static boolean srec_scan PARAMS ((bfd *));
120 static const bfd_target *srec_object_p PARAMS ((bfd *));
121 static const bfd_target *symbolsrec_object_p PARAMS ((bfd *));
122 static boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *));
124 static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma,
125 const bfd_byte *,
126 const bfd_byte *));
127 static boolean srec_write_header PARAMS ((bfd *));
128 static boolean srec_write_symbols PARAMS ((bfd *));
129 static boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma));
130 static boolean srec_get_section_contents
131 PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
132 static boolean srec_set_arch_mach
133 PARAMS ((bfd *, enum bfd_architecture, unsigned long));
134 static boolean srec_set_section_contents
135 PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
136 static boolean internal_srec_write_object_contents PARAMS ((bfd *, int));
137 static boolean srec_write_object_contents PARAMS ((bfd *));
138 static boolean symbolsrec_write_object_contents PARAMS ((bfd *));
139 static int srec_sizeof_headers PARAMS ((bfd *, boolean));
140 static asymbol *srec_make_empty_symbol PARAMS ((bfd *));
141 static long srec_get_symtab_upper_bound PARAMS ((bfd *));
142 static long srec_get_symtab PARAMS ((bfd *, asymbol **));
144 /* Macros for converting between hex and binary. */
146 static CONST char digs[] = "0123456789ABCDEF";
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)
156 /* Initialize by filling in the hex conversion array. */
158 static void
159 srec_init ()
161 static boolean inited = false;
163 if (inited == false)
165 inited = true;
166 hex_init ();
170 /* The maximum number of bytes on a line is FF. */
171 #define MAXCHUNK 0xff
173 /* Default size for a CHUNK. */
174 #define DEFAULT_CHUNK 16
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. */
179 unsigned int Chunk = DEFAULT_CHUNK;
181 /* The type of srec output (free or forced to S3).
182 This variable can be modified by objcopy's --srec-forceS3
183 parameter. */
184 boolean S3Forced = 0;
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. */
189 struct srec_data_list_struct
191 struct srec_data_list_struct *next;
192 bfd_byte *data;
193 bfd_vma where;
194 bfd_size_type size;
197 typedef struct srec_data_list_struct srec_data_list_type;
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). */
203 struct srec_symbol
205 struct srec_symbol *next;
206 const char *name;
207 bfd_vma val;
210 /* The S-record tdata information. */
212 typedef struct srec_data_struct
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;
221 tdata_type;
223 static boolean srec_write_section PARAMS ((bfd *, tdata_type *,
224 srec_data_list_type *));
225 static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *));
227 /* Set up the S-record tdata information. */
229 static boolean
230 srec_mkobject (abfd)
231 bfd *abfd;
233 srec_init ();
235 if (abfd->tdata.srec_data == NULL)
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;
249 return true;
252 /* Read a byte from an S record file. Set *ERRORPTR if an error
253 occurred. Return EOF on error or end of file. */
255 static int
256 srec_get_byte (abfd, errorptr)
257 bfd *abfd;
258 boolean *errorptr;
260 bfd_byte c;
262 if (bfd_read (&c, 1, 1, abfd) != 1)
264 if (bfd_get_error () != bfd_error_file_truncated)
265 *errorptr = true;
266 return EOF;
269 return (int) (c & 0xff);
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. */
276 static void
277 srec_bad_byte (abfd, lineno, c, error)
278 bfd *abfd;
279 unsigned int lineno;
280 int c;
281 boolean error;
283 if (c == EOF)
285 if (! error)
286 bfd_set_error (bfd_error_file_truncated);
288 else
290 char buf[10];
292 if (! isprint (c))
293 sprintf (buf, "\\%03o", (unsigned int) c);
294 else
296 buf[0] = c;
297 buf[1] = '\0';
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);
306 /* Add a new symbol found in an S-record file. */
308 static boolean
309 srec_new_symbol (abfd, name, val)
310 bfd *abfd;
311 const char *name;
312 bfd_vma val;
314 struct srec_symbol *n;
316 n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol));
317 if (n == NULL)
318 return false;
320 n->name = name;
321 n->val = val;
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;
330 ++abfd->symcount;
332 return true;
335 /* Read the S record file and turn it into sections. We create a new
336 section for each contiguous set of bytes. */
338 static boolean
339 srec_scan (abfd)
340 bfd *abfd;
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;
350 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
351 goto error_return;
353 while ((c = srec_get_byte (abfd, &error)) != EOF)
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;
360 switch (c)
362 default:
363 srec_bad_byte (abfd, lineno, c, error);
364 goto error_return;
366 case '\n':
367 ++lineno;
368 break;
370 case '\r':
371 break;
373 case '$':
374 /* Starting a module name, which we ignore. */
375 while ((c = srec_get_byte (abfd, &error)) != '\n'
376 && c != EOF)
378 if (c == EOF)
380 srec_bad_byte (abfd, lineno, c, error);
381 goto error_return;
384 ++lineno;
386 break;
388 case ' ':
391 unsigned int alc;
392 char *p, *symname;
393 bfd_vma symval;
395 /* Starting a symbol definition. */
396 while ((c = srec_get_byte (abfd, &error)) != EOF
397 && (c == ' ' || c == '\t'))
400 if (c == '\n' || c == '\r')
401 break;
403 if (c == EOF)
405 srec_bad_byte (abfd, lineno, c, error);
406 goto error_return;
409 alc = 10;
410 symbuf = (char *) bfd_malloc (alc + 1);
411 if (symbuf == NULL)
412 goto error_return;
414 p = symbuf;
416 *p++ = c;
417 while ((c = srec_get_byte (abfd, &error)) != EOF
418 && ! isspace (c))
420 if ((unsigned int) (p - symbuf) >= alc)
422 char *n;
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;
432 *p++ = c;
435 if (c == EOF)
437 srec_bad_byte (abfd, lineno, c, error);
438 goto error_return;
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;
449 while ((c = srec_get_byte (abfd, &error)) != EOF
450 && (c == ' ' || c == '\t'))
452 if (c == EOF)
454 srec_bad_byte (abfd, lineno, c, error);
455 goto error_return;
458 /* Skip a dollar sign before the hex value. */
459 if (c == '$')
461 c = srec_get_byte (abfd, &error);
462 if (c == EOF)
464 srec_bad_byte (abfd, lineno, c, error);
465 goto error_return;
469 symval = 0;
470 while (ISHEX (c))
472 symval <<= 4;
473 symval += NIBBLE (c);
474 c = srec_get_byte (abfd, &error);
477 if (! srec_new_symbol (abfd, symname, symval))
478 goto error_return;
480 while (c == ' ' || c == '\t')
483 if (c == '\n')
484 ++lineno;
485 else if (c != '\r')
487 srec_bad_byte (abfd, lineno, c, error);
488 goto error_return;
491 break;
493 case 'S':
495 file_ptr pos;
496 char hdr[3];
497 unsigned int bytes;
498 bfd_vma address;
499 bfd_byte *data;
501 /* Starting an S-record. */
503 pos = bfd_tell (abfd) - 1;
505 if (bfd_read (hdr, 1, 3, abfd) != 3)
506 goto error_return;
508 if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
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;
518 bytes = HEX (hdr + 1);
519 if (bytes * 2 > bufsize)
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;
529 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
530 goto error_return;
532 /* Ignore the checksum byte. */
533 --bytes;
535 address = 0;
536 data = buf;
537 switch (hdr[0])
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;
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;
563 if (sec != NULL
564 && sec->vma + sec->_raw_size == address)
566 /* This data goes at the end of the section we are
567 currently building. */
568 sec->_raw_size += bytes;
570 else
572 char secbuf[20];
573 char *secname;
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;
588 break;
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;
604 /* This is a termination record. */
605 abfd->start_address = address;
607 if (buf != NULL)
608 free (buf);
610 return true;
613 break;
617 if (error)
618 goto error_return;
620 if (buf != NULL)
621 free (buf);
623 return true;
625 error_return:
626 if (symbuf != NULL)
627 free (symbuf);
628 if (buf != NULL)
629 free (buf);
630 return false;
633 /* Check whether an existing file is an S-record file. */
635 static const bfd_target *
636 srec_object_p (abfd)
637 bfd *abfd;
639 bfd_byte b[4];
641 srec_init ();
643 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
644 || bfd_read (b, 1, 4, abfd) != 4)
645 return NULL;
647 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
649 bfd_set_error (bfd_error_wrong_format);
650 return NULL;
653 if (! srec_mkobject (abfd)
654 || ! srec_scan (abfd))
655 return NULL;
657 if (abfd->symcount > 0)
658 abfd->flags |= HAS_SYMS;
660 return abfd->xvec;
663 /* Check whether an existing file is an S-record file with symbols. */
665 static const bfd_target *
666 symbolsrec_object_p (abfd)
667 bfd *abfd;
669 char b[2];
671 srec_init ();
673 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
674 || bfd_read (b, 1, 2, abfd) != 2)
675 return NULL;
677 if (b[0] != '$' || b[1] != '$')
679 bfd_set_error (bfd_error_wrong_format);
680 return NULL;
683 if (! srec_mkobject (abfd)
684 || ! srec_scan (abfd))
685 return NULL;
687 if (abfd->symcount > 0)
688 abfd->flags |= HAS_SYMS;
690 return abfd->xvec;
693 /* Read in the contents of a section in an S-record file. */
695 static boolean
696 srec_read_section (abfd, section, contents)
697 bfd *abfd;
698 asection *section;
699 bfd_byte *contents;
701 int c;
702 bfd_size_type sofar = 0;
703 boolean error = false;
704 bfd_byte *buf = NULL;
705 size_t bufsize = 0;
707 if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
708 goto error_return;
710 while ((c = srec_get_byte (abfd, &error)) != EOF)
712 bfd_byte hdr[3];
713 unsigned int bytes;
714 bfd_vma address;
715 bfd_byte *data;
717 if (c == '\r' || c == '\n')
718 continue;
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');
724 if (bfd_read (hdr, 1, 3, abfd) != 3)
725 goto error_return;
727 BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
729 bytes = HEX (hdr + 1);
731 if (bytes * 2 > bufsize)
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;
741 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
742 goto error_return;
744 address = 0;
745 data = buf;
746 switch (hdr[0])
748 default:
749 BFD_ASSERT (sofar == section->_raw_size);
750 if (buf != NULL)
751 free (buf);
752 return true;
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;
771 if (address != section->vma + sofar)
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;
780 /* Don't consider checksum. */
781 --bytes;
783 while (bytes-- != 0)
785 contents[sofar] = HEX (data);
786 data += 2;
787 ++sofar;
790 break;
794 if (error)
795 goto error_return;
797 BFD_ASSERT (sofar == section->_raw_size);
799 if (buf != NULL)
800 free (buf);
802 return true;
804 error_return:
805 if (buf != NULL)
806 free (buf);
807 return false;
810 /* Get the contents of a section in an S-record file. */
812 static boolean
813 srec_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;
820 if (section->used_by_bfd == NULL)
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;
827 if (! srec_read_section (abfd, section, section->used_by_bfd))
828 return false;
831 memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
832 (size_t) count);
834 return true;
837 /* Set the architecture. We accept an unknown architecture here. */
839 static boolean
840 srec_set_arch_mach (abfd, arch, mach)
841 bfd *abfd;
842 enum bfd_architecture arch;
843 unsigned long mach;
845 if (arch == bfd_arch_unknown)
847 abfd->arch_info = &bfd_default_arch_struct;
848 return true;
850 return bfd_default_set_arch_mach (abfd, arch, mach);
853 /* We have to save up all the Srecords for a splurge before output. */
855 static boolean
856 srec_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;
863 tdata_type *tdata = abfd->tdata.srec_data;
864 register srec_data_list_type *entry;
866 entry = ((srec_data_list_type *)
867 bfd_alloc (abfd, sizeof (srec_data_list_type)));
868 if (entry == NULL)
869 return false;
871 if (bytes_to_do
872 && (section->flags & SEC_ALLOC)
873 && (section->flags & SEC_LOAD))
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);
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;
892 entry->data = data;
893 entry->where = section->lma + offset;
894 entry->size = bytes_to_do;
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)
901 tdata->tail->next = entry;
902 entry->next = NULL;
903 tdata->tail = entry;
905 else
907 register srec_data_list_type **look;
909 for (look = &tdata->head;
910 *look != NULL && (*look)->where < entry->where;
911 look = &(*look)->next)
913 entry->next = *look;
914 *look = entry;
915 if (entry->next == NULL)
916 tdata->tail = entry;
919 return true;
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. */
926 static boolean
927 srec_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;
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;
941 *dst++ = 'S';
942 *dst++ = '0' + type;
944 length = dst;
945 dst += 2; /* Leave room for dst. */
947 switch (type)
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;
967 for (src = data; src < end; src++)
969 TOHEX (dst, *src, check_sum);
970 dst += 2;
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;
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;
988 static boolean
989 srec_write_header (abfd)
990 bfd *abfd;
992 bfd_byte buffer[MAXCHUNK];
993 bfd_byte *dst = buffer;
994 unsigned int i;
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];
1000 return srec_write_record (abfd, 0, 0, buffer, dst);
1003 static boolean
1004 srec_write_section (abfd, tdata, list)
1005 bfd *abfd;
1006 tdata_type *tdata;
1007 srec_data_list_type *list;
1009 unsigned int octets_written = 0;
1010 bfd_byte *location = list->data;
1012 while (octets_written < list->size)
1014 bfd_vma address;
1015 unsigned int octets_this_chunk = list->size - octets_written;
1017 if (octets_this_chunk > Chunk)
1018 octets_this_chunk = Chunk;
1020 address = list->where + octets_written / bfd_octets_per_byte (abfd);
1022 if (! srec_write_record (abfd,
1023 tdata->type,
1024 address,
1025 location,
1026 location + octets_this_chunk))
1027 return false;
1029 octets_written += octets_this_chunk;
1030 location += octets_this_chunk;
1033 return true;
1036 static boolean
1037 srec_write_terminator (abfd, tdata)
1038 bfd *abfd;
1039 tdata_type *tdata;
1041 bfd_byte buffer[2];
1043 return srec_write_record (abfd, 10 - tdata->type,
1044 abfd->start_address, buffer, buffer);
1047 static boolean
1048 srec_write_symbols (abfd)
1049 bfd *abfd;
1051 char buffer[MAXCHUNK];
1052 /* Dump out the symbols of a bfd. */
1053 int i;
1054 int count = bfd_get_symcount (abfd);
1056 if (count)
1058 size_t len;
1059 asymbol **table = bfd_get_outsymbols (abfd);
1060 sprintf (buffer, "$$ %s\r\n", abfd->filename);
1062 len = strlen (buffer);
1063 if (bfd_write (buffer, len, 1, abfd) != len)
1064 return false;
1066 for (i = 0; i < count; i++)
1068 asymbol *s = table[i];
1069 if (! bfd_is_local_label (abfd, s)
1070 && (s->flags & BSF_DEBUGGING) == 0)
1072 /* Just dump out non debug symbols. */
1073 bfd_size_type l;
1074 char buf2[40], *p;
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;
1088 sprintf (buffer, "$$ \r\n");
1089 len = strlen (buffer);
1090 if (bfd_write (buffer, len, 1, abfd) != len)
1091 return false;
1094 return true;
1097 static boolean
1098 internal_srec_write_object_contents (abfd, symbols)
1099 bfd *abfd;
1100 int symbols;
1102 tdata_type *tdata = abfd->tdata.srec_data;
1103 srec_data_list_type *list;
1105 if (symbols)
1107 if (! srec_write_symbols (abfd))
1108 return false;
1111 if (! srec_write_header (abfd))
1112 return false;
1114 /* Now wander though all the sections provided and output them. */
1115 list = tdata->head;
1117 while (list != (srec_data_list_type *) NULL)
1119 if (! srec_write_section (abfd, tdata, list))
1120 return false;
1121 list = list->next;
1123 return srec_write_terminator (abfd, tdata);
1126 static boolean
1127 srec_write_object_contents (abfd)
1128 bfd *abfd;
1130 return internal_srec_write_object_contents (abfd, 0);
1133 static boolean
1134 symbolsrec_write_object_contents (abfd)
1135 bfd *abfd;
1137 return internal_srec_write_object_contents (abfd, 1);
1140 static int
1141 srec_sizeof_headers (abfd, exec)
1142 bfd *abfd ATTRIBUTE_UNUSED;
1143 boolean exec ATTRIBUTE_UNUSED;
1145 return 0;
1148 static asymbol *
1149 srec_make_empty_symbol (abfd)
1150 bfd *abfd;
1152 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
1153 if (new)
1154 new->the_bfd = abfd;
1155 return new;
1158 /* Return the amount of memory needed to read the symbol table. */
1160 static long
1161 srec_get_symtab_upper_bound (abfd)
1162 bfd *abfd;
1164 return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
1167 /* Return the symbol table. */
1169 static long
1170 srec_get_symtab (abfd, alocation)
1171 bfd *abfd;
1172 asymbol **alocation;
1174 unsigned int symcount = bfd_get_symcount (abfd);
1175 asymbol *csymbols;
1176 unsigned int i;
1178 csymbols = abfd->tdata.srec_data->csymbols;
1179 if (csymbols == NULL)
1181 asymbol *c;
1182 struct srec_symbol *s;
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;
1189 for (s = abfd->tdata.srec_data->symbols, c = csymbols;
1190 s != NULL;
1191 s = s->next, ++c)
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;
1202 for (i = 0; i < symcount; i++)
1203 *alocation++ = csymbols++;
1204 *alocation = NULL;
1206 return symcount;
1209 static void
1210 srec_get_symbol_info (ignore_abfd, symbol, ret)
1211 bfd *ignore_abfd ATTRIBUTE_UNUSED;
1212 asymbol *symbol;
1213 symbol_info *ret;
1215 bfd_symbol_info (symbol, ret);
1218 static void
1219 srec_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;
1225 FILE *file = (FILE *) afile;
1226 switch (how)
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);
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
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
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
1257 #define srec_get_section_contents_in_window \
1258 _bfd_generic_get_section_contents_in_window
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
1269 const bfd_target srec_vec =
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 */
1291 _bfd_dummy_target,
1292 srec_object_p, /* bfd_check_format */
1293 _bfd_dummy_target,
1294 _bfd_dummy_target,
1297 bfd_false,
1298 srec_mkobject,
1299 _bfd_generic_mkarchive,
1300 bfd_false,
1302 { /* bfd_write_contents */
1303 bfd_false,
1304 srec_write_object_contents,
1305 _bfd_write_archive_contents,
1306 bfd_false,
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),
1319 NULL,
1321 (PTR) 0
1324 const bfd_target symbolsrec_vec =
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 */
1346 _bfd_dummy_target,
1347 symbolsrec_object_p, /* bfd_check_format */
1348 _bfd_dummy_target,
1349 _bfd_dummy_target,
1352 bfd_false,
1353 srec_mkobject,
1354 _bfd_generic_mkarchive,
1355 bfd_false,
1357 { /* bfd_write_contents */
1358 bfd_false,
1359 symbolsrec_write_object_contents,
1360 _bfd_write_archive_contents,
1361 bfd_false,
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),
1374 NULL,
1376 (PTR) 0