OSDN Git Service

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