* srec.c (pass_over): Don't skip too many characters when
[external/binutils.git] / bfd / srec.c
1 /* BFD back-end for s-record objects.
2    Copyright 1990, 1991, 1992, 1993, 1994 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., 675 Mass Ave, Cambridge, MA 02139, 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
110 /* Macros for converting between hex and binary */
111
112 static CONST char digs[] = "0123456789ABCDEF";
113
114 static char hex_value[1 + (unsigned char) ~0];
115
116 #define NOT_HEX 20
117 #define NIBBLE(x) hex_value[(unsigned char)(x)]
118 #define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
119 #define TOHEX(d, x, ch) \
120         d[1] = digs[(x) & 0xf]; \
121         d[0] = digs[((x)>>4)&0xf]; \
122         ch += ((x) & 0xff);
123 #define ISHEX(x)  (hex_value[(unsigned char)(x)] != NOT_HEX)
124
125
126
127 static void
128 DEFUN_VOID (srec_init)
129 {
130   unsigned int i;
131   static boolean inited = false;
132
133   if (inited == false)
134     {
135
136       inited = true;
137
138       for (i = 0; i < sizeof (hex_value); i++)
139         {
140           hex_value[i] = NOT_HEX;
141         }
142
143       for (i = 0; i < 10; i++)
144         {
145           hex_value[i + '0'] = i;
146
147         }
148       for (i = 0; i < 6; i++)
149         {
150           hex_value[i + 'a'] = i + 10;
151           hex_value[i + 'A'] = i + 10;
152         }
153     }
154 }
155
156
157 /* The maximum number of bytes on a line is FF */
158 #define MAXCHUNK 0xff
159 /* The number of bytes we fit onto a line on output */
160 #define CHUNK 21
161
162 /* We cannot output our srecords as we see them, we have to glue them
163    together, this is done in this structure : */
164
165 struct srec_data_list_struct
166 {
167   unsigned char *data;
168   bfd_vma where;
169   bfd_size_type size;
170   struct srec_data_list_struct *next;
171
172
173 };
174 typedef struct srec_data_list_struct srec_data_list_type;
175
176
177 typedef struct srec_data_struct
178   {
179     srec_data_list_type *head;
180     unsigned int type;
181
182     int done_symbol_read;
183     int count;
184     asymbol *symbols;
185     char *strings;
186     int symbol_idx;
187     int string_size;
188     int string_idx;
189   }
190 tdata_type;
191
192
193 /*
194    called once per input S-Record, used to work out vma and size of data.
195  */
196
197 static bfd_vma low, high;
198
199 /*ARGSUSED*/
200 static void
201 size_symbols (abfd, buf, len, val)
202      bfd *abfd;
203      char *buf;
204      int len;
205      int val;
206 {
207   abfd->symcount++;
208   abfd->tdata.srec_data->string_size += len + 1;
209 }
210
211 static void
212 fillup_symbols (abfd, buf, len, val)
213      bfd *abfd;
214      char *buf;
215      int len;
216      int val;
217 {
218   if (!abfd->tdata.srec_data->done_symbol_read)
219     {
220       asymbol *p;
221       if (abfd->tdata.srec_data->symbols == 0)
222         {
223           abfd->tdata.srec_data->symbols = (asymbol *) bfd_alloc (abfd, abfd->symcount * sizeof (asymbol));
224           abfd->tdata.srec_data->strings = (char *) bfd_alloc (abfd, abfd->tdata.srec_data->string_size);
225           if (!abfd->tdata.srec_data->symbols || !abfd->tdata.srec_data->strings)
226             {
227               bfd_set_error (bfd_error_no_memory);
228               abort ();         /* FIXME */
229             }
230           abfd->tdata.srec_data->symbol_idx = 0;
231           abfd->tdata.srec_data->string_idx = 0;
232         }
233
234       p = abfd->tdata.srec_data->symbols + abfd->tdata.srec_data->symbol_idx++;
235       p->the_bfd = abfd;
236       p->name = abfd->tdata.srec_data->strings + abfd->tdata.srec_data->string_idx;
237       memcpy ((char *) (p->name), buf, len + 1);
238       abfd->tdata.srec_data->string_idx += len + 1;
239       p->value = val;
240       p->flags = BSF_EXPORT | BSF_GLOBAL;
241       p->section = &bfd_abs_section;
242       p->udata = 0;
243     }
244 }
245 /*ARGSUSED*/
246 static void
247 DEFUN (size_srec, (abfd, section, address, raw, length),
248        bfd * abfd AND
249        asection * section AND
250        bfd_vma address AND
251        bfd_byte * raw AND
252        unsigned int length)
253 {
254   if (address < low)
255     low = address;
256   if (address + length > high)
257     high = address + length - 1;
258 }
259
260
261 /*
262  called once per input S-Record, copies data from input into bfd_alloc'd area
263  */
264
265 /*ARGSUSED*/
266 static void
267 DEFUN (fillup, (abfd, section, address, raw, length),
268        bfd * abfd AND
269        asection * section AND
270        bfd_vma address AND
271        bfd_byte * raw AND
272        unsigned int length)
273 {
274   unsigned int i;
275   bfd_byte *dst =
276   (bfd_byte *) (section->used_by_bfd) + address - section->vma;
277   /* length -1 because we don't read in the checksum */
278   for (i = 0; i < length - 1; i++)
279     {
280       *dst = HEX (raw);
281       dst++;
282       raw += 2;
283     }
284 }
285
286 /* Pass over an S-Record file, calling one of the above functions on each
287    record.  */
288
289 static int 
290 white (x)
291      char x;
292 {
293   return (x == ' ' || x == '\t' || x == '\n' || x == '\r');
294 }
295 static int
296 skipwhite (src, abfd)
297      char *src;
298      bfd *abfd;
299 {
300   int eof = 0;
301   while (white (*src) && !eof)
302     {
303       eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
304     }
305   return eof;
306 }
307
308 static boolean
309 DEFUN (srec_mkobject, (abfd),
310        bfd * abfd)
311 {
312   if (abfd->tdata.srec_data == 0)
313     {
314       tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
315       if (!tdata)
316         {
317           bfd_set_error (bfd_error_no_memory);
318           return false;
319         }
320       abfd->tdata.srec_data = tdata;
321       tdata->type = 1;
322       tdata->head = (srec_data_list_type *) NULL;
323     }
324   return true;
325
326 }
327
328 static void 
329 pass_over (abfd, func, symbolfunc, section)
330      bfd *abfd;
331      void (*func) ();
332      void (*symbolfunc) ();
333      asection *section;
334 {
335   unsigned int bytes_on_line;
336   boolean eof = false;
337
338   srec_mkobject (abfd);
339   /* To the front of the file */
340   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
341   while (eof == false)
342     {
343       char buffer[MAXCHUNK];
344       char *src = buffer;
345       char type;
346       bfd_vma address = 0;
347
348       /* Find first 'S' or $ */
349       eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
350       switch (*src)
351         {
352         default:
353           if (eof)
354             return;
355           break;
356
357         case '$':
358           /* Inside a symbol definition - just ignore the module name */
359           while (*src != '\n' && !eof)
360             {
361               eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
362             }
363           break;
364
365         case ' ':
366           /* spaces - maybe just before a symbol */
367           while (*src != '\n' && *src != '\r' && white (*src))
368             {
369               eof = skipwhite (src, abfd);
370
371               {
372                 int val = 0;
373                 int slen = 0;
374                 char symbol[MAXCHUNK];
375
376                 /* get the symbol part */
377                 while (!eof && !white (*src) && slen < MAXCHUNK)
378                   {
379                     symbol[slen++] = *src;
380                     eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
381                   }
382                 symbol[slen] = 0;
383                 eof = skipwhite (src, abfd);
384                 /* skip the $ for the hex value */
385                 if (*src == '$')
386                   {
387                     eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
388                   }
389
390                 /* Scan off the hex number */
391                 while (isxdigit (*src))
392                   {
393                     val *= 16;
394                     if (isdigit (*src))
395                       val += *src - '0';
396                     else if (isupper (*src))
397                       {
398                         val += *src - 'A' + 10;
399                       }
400                     else
401                       {
402                         val += *src - 'a' + 10;
403                       }
404                     eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
405                   }
406                 symbolfunc (abfd, symbol, slen, val);
407               }
408             }
409           break;
410         case 'S':
411           src++;
412
413           /* Fetch the type and the length */
414           bfd_read (src, 1, 3, abfd);
415
416           type = *src++;
417
418           if (!ISHEX (src[0]) || !ISHEX (src[1]))
419             break;
420
421           bytes_on_line = HEX (src);
422
423           if (bytes_on_line > MAXCHUNK / 2)
424             break;
425           src += 2;
426
427           bfd_read (src, 1, bytes_on_line * 2, abfd);
428
429           switch (type)
430             {
431             case '0':
432             case '5':
433               /* Prologue - ignore */
434               break;
435             case '3':
436               address = HEX (src);
437               src += 2;
438               bytes_on_line--;
439
440             case '2':
441               address = HEX (src) | (address << 8);
442               src += 2;
443               bytes_on_line--;
444             case '1':
445               address = HEX (src) | (address << 8);
446               src += 2;
447               address = HEX (src) | (address << 8);
448               src += 2;
449               bytes_on_line -= 2;
450               func (abfd, section, address, src, bytes_on_line);
451               break;
452             default:
453               return;
454             }
455         }
456     }
457
458 }
459
460 static bfd_target *
461 object_p (abfd)
462      bfd *abfd;
463 {
464   asection *section;
465   /* We create one section called .text for all the contents,
466      and allocate enough room for the entire file.  */
467
468   section = bfd_make_section (abfd, ".text");
469   section->_raw_size = 0;
470   section->vma = 0xffffffff;
471   low = 0xffffffff;
472   high = 0;
473   pass_over (abfd, size_srec, size_symbols, section);
474   section->_raw_size = high - low;
475   section->vma = low;
476   section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
477
478   if (abfd->symcount)
479     abfd->flags |= HAS_SYMS;
480   return abfd->xvec;
481 }
482
483 static bfd_target *
484 DEFUN (srec_object_p, (abfd),
485        bfd * abfd)
486 {
487   char b[4];
488
489   srec_init ();
490
491   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
492   bfd_read (b, 1, 4, abfd);
493
494   if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
495     return (bfd_target *) NULL;
496
497   /* We create one section called .text for all the contents,
498      and allocate enough room for the entire file.  */
499
500   return object_p (abfd);
501 }
502
503
504 static bfd_target *
505 DEFUN (symbolsrec_object_p, (abfd),
506        bfd * abfd)
507 {
508   char b[4];
509
510   srec_init ();
511
512   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
513   bfd_read (b, 1, 4, abfd);
514
515   if (b[0] != '$' || b[1] != '$')
516     return (bfd_target *) NULL;
517
518   return object_p (abfd);
519 }
520
521
522 static boolean
523 DEFUN (srec_get_section_contents, (abfd, section, location, offset, count),
524        bfd * abfd AND
525        asection * section AND
526        PTR location AND
527        file_ptr offset AND
528        bfd_size_type count)
529 {
530   if (section->used_by_bfd == (PTR) NULL)
531     {
532       section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size);
533       if (!section->used_by_bfd)
534         {
535           bfd_set_error (bfd_error_no_memory);
536           return false;
537         }
538
539       pass_over (abfd, fillup, fillup_symbols, section);
540     }
541   memcpy ((PTR) location,
542                  (PTR) ((char *) (section->used_by_bfd) + offset),
543                  count);
544   return true;
545 }
546
547
548
549 boolean
550 DEFUN (srec_set_arch_mach, (abfd, arch, machine),
551        bfd * abfd AND
552        enum bfd_architecture arch AND
553        unsigned long machine)
554 {
555   return bfd_default_set_arch_mach (abfd, arch, machine);
556 }
557
558
559 /* we have to save up all the Srecords for a splurge before output,
560    also remember   */
561
562 static boolean
563 DEFUN (srec_set_section_contents, (abfd, section, location, offset, bytes_to_do),
564        bfd * abfd AND
565        sec_ptr section AND
566        PTR location AND
567        file_ptr offset AND
568        bfd_size_type bytes_to_do)
569 {
570   tdata_type *tdata = abfd->tdata.srec_data;
571   srec_data_list_type *entry = (srec_data_list_type *)
572     bfd_alloc (abfd, sizeof (srec_data_list_type));
573
574   if (!entry)
575     {
576       bfd_set_error (bfd_error_no_memory);
577       return false;
578     }
579
580   if ((section->flags & SEC_ALLOC)
581       && (section->flags & SEC_LOAD))
582     {
583       unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do);
584       if (!data)
585         {
586           bfd_set_error (bfd_error_no_memory);
587           return false;
588         }
589       memcpy (data, location, bytes_to_do);
590
591       if ((section->lma + offset + bytes_to_do) <= 0xffff)
592         {
593
594         }
595       else if ((section->lma + offset + bytes_to_do) <= 0xffffff
596                && tdata->type < 2)
597         {
598           tdata->type = 2;
599         }
600       else
601         {
602           tdata->type = 3;
603         }
604
605       entry->data = data;
606       entry->where = section->lma + offset;
607       entry->size = bytes_to_do;
608       entry->next = tdata->head;
609       tdata->head = entry;
610     }
611   return true;
612 }
613
614 /* Write a record of type, of the supplied number of bytes. The
615    supplied bytes and length don't have a checksum. That's worked out
616    here
617 */
618 static
619 void 
620 DEFUN (srec_write_record, (abfd, type, address, data, end),
621        bfd * abfd AND
622        char type AND
623        bfd_vma address AND
624        CONST unsigned char *data AND
625        CONST unsigned char *end)
626
627 {
628   char buffer[MAXCHUNK];
629
630   unsigned int check_sum = 0;
631   CONST unsigned char *src = data;
632   char *dst = buffer;
633   char *length;
634
635
636   *dst++ = 'S';
637   *dst++ = '0' + type;
638
639   length = dst;
640   dst += 2;                     /* leave room for dst*/
641
642   switch (type)
643     {
644     case 3:
645     case 7:
646       TOHEX (dst, (address >> 24), check_sum);
647       dst += 2;
648     case 8:
649     case 2:
650       TOHEX (dst, (address >> 16), check_sum);
651       dst += 2;
652     case 9:
653     case 1:
654     case 0:
655       TOHEX (dst, (address >> 8), check_sum);
656       dst += 2;
657       TOHEX (dst, (address), check_sum);
658       dst += 2;
659       break;
660
661     }
662   for (src = data; src < end; src++)
663     {
664       TOHEX (dst, *src, check_sum);
665       dst += 2;
666     }
667
668   /* Fill in the length */
669   TOHEX (length, (dst - length) / 2, check_sum);
670   check_sum &= 0xff;
671   check_sum = 255 - check_sum;
672   TOHEX (dst, check_sum, check_sum);
673   dst += 2;
674
675   *dst++ = '\r';
676   *dst++ = '\n';
677   bfd_write ((PTR) buffer, 1, dst - buffer, abfd);
678 }
679
680
681
682 static void
683 DEFUN (srec_write_header, (abfd),
684        bfd * abfd)
685 {
686   unsigned char buffer[MAXCHUNK];
687   unsigned char *dst = buffer;
688   unsigned int i;
689
690   /* I'll put an arbitary 40 char limit on header size */
691   for (i = 0; i < 40 && abfd->filename[i]; i++)
692     {
693       *dst++ = abfd->filename[i];
694     }
695   srec_write_record (abfd, 0, 0, buffer, dst);
696 }
697
698 static void
699 DEFUN (srec_write_section, (abfd, tdata, list),
700        bfd * abfd AND
701        tdata_type * tdata AND
702        srec_data_list_type * list)
703 {
704   unsigned int bytes_written = 0;
705   unsigned char *location = list->data;
706
707   while (bytes_written < list->size)
708     {
709       bfd_vma address;
710
711       unsigned int bytes_this_chunk = list->size - bytes_written;
712
713       if (bytes_this_chunk > CHUNK)
714         {
715           bytes_this_chunk = CHUNK;
716         }
717
718       address = list->where + bytes_written;
719
720       srec_write_record (abfd,
721                          tdata->type,
722                          address,
723                          location,
724                          location + bytes_this_chunk);
725
726       bytes_written += bytes_this_chunk;
727       location += bytes_this_chunk;
728     }
729
730 }
731
732 static void
733 DEFUN (srec_write_terminator, (abfd, tdata),
734        bfd * abfd AND
735        tdata_type * tdata)
736 {
737   unsigned char buffer[2];
738
739   srec_write_record (abfd, 10 - tdata->type,
740                      abfd->start_address, buffer, buffer);
741 }
742
743
744
745 static void
746 srec_write_symbols (abfd)
747      bfd *abfd;
748 {
749   char buffer[MAXCHUNK];
750   /* Dump out the symbols of a bfd */
751   int i;
752   int len = bfd_get_symcount (abfd);
753
754   if (len)
755     {
756       asymbol **table = bfd_get_outsymbols (abfd);
757       sprintf (buffer, "$$ %s\r\n", abfd->filename);
758
759       bfd_write (buffer, strlen (buffer), 1, abfd);
760
761       for (i = 0; i < len; i++)
762         {
763           asymbol *s = table[i];
764 #if 0
765           int len = strlen (s->name);
766
767           /* If this symbol has a .[ocs] in it, it's probably a file name
768          and we'll output that as the module name */
769
770           if (len > 3 && s->name[len - 2] == '.')
771             {
772               int l;
773               sprintf (buffer, "$$ %s\r\n", s->name);
774               l = strlen (buffer);
775               bfd_write (buffer, l, 1, abfd);
776             }
777           else
778 #endif
779             if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
780                 && (s->flags & BSF_DEBUGGING) == 0
781                 && s->name[0] != '.'
782                 && s->name[0] != 't')
783             {
784               /* Just dump out non debug symbols */
785
786               int l;
787               char buf2[40], *p;
788
789               sprintf_vma (buf2,
790                            s->value + s->section->output_section->lma
791                            + s->section->output_offset);
792               p = buf2;
793               while (p[0] == '0' && p[1] != 0)
794                 p++;
795               sprintf (buffer, "  %s $%s\r\n", s->name, p);
796               l = strlen (buffer);
797               bfd_write (buffer, l, 1, abfd);
798             }
799         }
800       sprintf (buffer, "$$ \r\n");
801       bfd_write (buffer, strlen (buffer), 1, abfd);
802     }
803 }
804
805 static boolean
806 internal_srec_write_object_contents (abfd, symbols)
807      bfd *abfd;
808      int symbols;
809 {
810   tdata_type *tdata = abfd->tdata.srec_data;
811   srec_data_list_type *list;
812
813   if (symbols)
814     srec_write_symbols (abfd);
815
816   srec_write_header (abfd);
817
818   /* Now wander though all the sections provided and output them */
819   list = tdata->head;
820
821   while (list != (srec_data_list_type *) NULL)
822     {
823       srec_write_section (abfd, tdata, list);
824       list = list->next;
825     }
826   srec_write_terminator (abfd, tdata);
827   return true;
828 }
829
830 static boolean
831 srec_write_object_contents (abfd)
832      bfd *abfd;
833 {
834   return internal_srec_write_object_contents (abfd, 0);
835 }
836
837 static boolean
838 symbolsrec_write_object_contents (abfd)
839      bfd *abfd;
840 {
841   return internal_srec_write_object_contents (abfd, 1);
842 }
843
844 /*ARGSUSED*/
845 static int
846 DEFUN (srec_sizeof_headers, (abfd, exec),
847        bfd * abfd AND
848        boolean exec)
849 {
850   return 0;
851 }
852
853 static asymbol *
854 DEFUN (srec_make_empty_symbol, (abfd),
855        bfd * abfd)
856 {
857   asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
858   if (new)
859     new->the_bfd = abfd;
860   return new;
861 }
862
863 static unsigned int
864 srec_get_symtab_upper_bound (abfd)
865      bfd *abfd;
866 {
867   /* Read in all the info */
868   srec_get_section_contents (abfd, abfd->sections, 0, 0, 0);
869   return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
870 }
871
872 static unsigned int
873 DEFUN (srec_get_symtab, (abfd, alocation),
874        bfd * abfd AND
875        asymbol ** alocation)
876 {
877   int lim = abfd->symcount;
878   int i;
879   for (i = 0; i < lim; i++)
880     {
881       alocation[i] = abfd->tdata.srec_data->symbols + i;
882     }
883   alocation[i] = 0;
884   return lim;
885 }
886
887 /*ARGSUSED*/
888 void
889 DEFUN (srec_get_symbol_info, (ignore_abfd, symbol, ret),
890        bfd * ignore_abfd AND
891        asymbol * symbol AND
892        symbol_info * ret)
893 {
894   bfd_symbol_info (symbol, ret);
895 }
896
897 /*ARGSUSED*/
898 void
899 DEFUN (srec_print_symbol, (ignore_abfd, afile, symbol, how),
900        bfd * ignore_abfd AND
901        PTR afile AND
902        asymbol * symbol AND
903        bfd_print_symbol_type how)
904 {
905   FILE *file = (FILE *) afile;
906   switch (how)
907     {
908     case bfd_print_symbol_name:
909       fprintf (file, "%s", symbol->name);
910       break;
911     default:
912       bfd_print_symbol_vandf ((PTR) file, symbol);
913       fprintf (file, " %-5s %s",
914                symbol->section->name,
915                symbol->name);
916
917     }
918 }
919
920 #define FOO PROTO
921 #define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
922
923 #define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
924 #define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
925
926
927
928 #define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
929 #define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
930 #define srec_generic_stat_arch_elt  (FOO(int, (*), (bfd *,struct stat *))) bfd_0
931
932
933 #define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
934 #define srec_core_file_failing_signal (int (*)())bfd_0
935 #define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
936 #define srec_slurp_armap bfd_true
937 #define srec_slurp_extended_name_table bfd_true
938 #define srec_truncate_arname (void (*)())bfd_nullvoidptr
939 #define srec_write_armap  (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
940 #define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
941 #define srec_close_and_cleanup  bfd_generic_close_and_cleanup
942 #define srec_bfd_debug_info_start bfd_void
943 #define srec_bfd_debug_info_end bfd_void
944 #define srec_bfd_debug_info_accumulate  (FOO(void, (*), (bfd *,  asection *))) bfd_void
945 #define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
946 #define srec_bfd_relax_section bfd_generic_relax_section
947 #define srec_bfd_reloc_type_lookup \
948   ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
949 #define srec_bfd_make_debug_symbol \
950   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
951 #define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
952 #define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
953 #define srec_bfd_final_link _bfd_generic_final_link
954
955 bfd_target srec_vec =
956 {
957   "srec",                       /* name */
958   bfd_target_srec_flavour,
959   true,                         /* target byte order */
960   true,                         /* target headers byte order */
961   (HAS_RELOC | EXEC_P |         /* object flags */
962    HAS_LINENO | HAS_DEBUG |
963    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
964   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
965    | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
966   0,                            /* leading underscore */
967   ' ',                          /* ar_pad_char */
968   16,                           /* ar_max_namelen */
969   1,                            /* minimum alignment */
970   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
971   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
972   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
973   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
974   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
975   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
976
977   {
978     _bfd_dummy_target,
979     srec_object_p,              /* bfd_check_format */
980     (struct bfd_target * (*)()) bfd_nullvoidptr,
981     (struct bfd_target * (*)()) bfd_nullvoidptr,
982   },
983   {
984     bfd_false,
985     srec_mkobject,
986     _bfd_generic_mkarchive,
987     bfd_false,
988   },
989   {                             /* bfd_write_contents */
990     bfd_false,
991     srec_write_object_contents,
992     _bfd_write_archive_contents,
993     bfd_false,
994   },
995   JUMP_TABLE (srec)
996 };
997
998
999
1000 bfd_target symbolsrec_vec =
1001 {
1002   "symbolsrec",                 /* name */
1003   bfd_target_srec_flavour,
1004   true,                         /* target byte order */
1005   true,                         /* target headers byte order */
1006   (HAS_RELOC | EXEC_P |         /* object flags */
1007    HAS_LINENO | HAS_DEBUG |
1008    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1009   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1010    | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1011   0,                            /* leading underscore */
1012   ' ',                          /* ar_pad_char */
1013   16,                           /* ar_max_namelen */
1014   1,                            /* minimum alignment */
1015   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1016   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1017   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
1018   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1019   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1020   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
1021
1022   {
1023     _bfd_dummy_target,
1024     symbolsrec_object_p,        /* bfd_check_format */
1025     (struct bfd_target * (*)()) bfd_nullvoidptr,
1026     (struct bfd_target * (*)()) bfd_nullvoidptr,
1027   },
1028   {
1029     bfd_false,
1030     srec_mkobject,
1031     _bfd_generic_mkarchive,
1032     bfd_false,
1033   },
1034   {                             /* bfd_write_contents */
1035     bfd_false,
1036     symbolsrec_write_object_contents,
1037     _bfd_write_archive_contents,
1038     bfd_false,
1039   },
1040   JUMP_TABLE (srec),
1041   (PTR) 0
1042 };