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