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