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