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