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