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