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