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