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