2000-12-19 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / srec.c
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
6 This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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. */
21
22 /*
23 SUBSECTION
24 S-Record handling
25
26 DESCRIPTION
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
46 EXAMPLE
47 S<type><length><address><data><checksum>
48
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
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
74 SUBSECTION
75 Symbol S-Record handling
76
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.
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
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
98 $$
99
100 DESCRIPTION
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
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 *));
123
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 **));
143
144 /* Macros for converting between hex and binary. */
145
146 static 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
158 static void
159 srec_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. */
179 unsigned 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. */
184 boolean 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
189 struct 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
197 typedef 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
203 struct 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
212 typedef 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 }
221 tdata_type;
222
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 *));
226
227 /* Set up the S-record tdata information. */
228
229 static boolean
230 srec_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
255 static int
256 srec_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
276 static void
277 srec_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
308 static boolean
309 srec_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
338 static boolean
339 srec_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
635 static const bfd_target *
636 srec_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
665 static const bfd_target *
666 symbolsrec_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
695 static boolean
696 srec_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
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;
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
839 static boolean
840 srec_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
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;
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
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;
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
988 static boolean
989 srec_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
1003 static boolean
1004 srec_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
1036 static boolean
1037 srec_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
1047 static boolean
1048 srec_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
1097 static boolean
1098 internal_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
1126 static boolean
1127 srec_write_object_contents (abfd)
1128 bfd *abfd;
1129 {
1130 return internal_srec_write_object_contents (abfd, 0);
1131 }
1132
1133 static boolean
1134 symbolsrec_write_object_contents (abfd)
1135 bfd *abfd;
1136 {
1137 return internal_srec_write_object_contents (abfd, 1);
1138 }
1139
1140 static int
1141 srec_sizeof_headers (abfd, exec)
1142 bfd *abfd ATTRIBUTE_UNUSED;
1143 boolean exec ATTRIBUTE_UNUSED;
1144 {
1145 return 0;
1146 }
1147
1148 static asymbol *
1149 srec_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
1160 static long
1161 srec_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
1169 static long
1170 srec_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
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;
1214 {
1215 bfd_symbol_info (symbol, ret);
1216 }
1217
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;
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
1269 const 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
1324 const 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 };
This page took 0.056763 seconds and 5 git commands to generate.