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