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