srec.c revision 60484
1126262Srwatson/* BFD back-end for s-record objects.
2189503Srwatson   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3126262Srwatson   Free Software Foundation, Inc.
4126262Srwatson   Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
5172930Srwatson
6182063SrwatsonThis file is part of BFD, the Binary File Descriptor library.
7126262Srwatson
8126262SrwatsonThis program is free software; you can redistribute it and/or modify
9126262Srwatsonit under the terms of the GNU General Public License as published by
10126262Srwatsonthe Free Software Foundation; either version 2 of the License, or
11126262Srwatson(at your option) any later version.
12126262Srwatson
13126262SrwatsonThis program is distributed in the hope that it will be useful,
14126262Srwatsonbut WITHOUT ANY WARRANTY; without even the implied warranty of
15126262SrwatsonMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16126262SrwatsonGNU General Public License for more details.
17172930Srwatson
18172930SrwatsonYou should have received a copy of the GNU General Public License
19172930Srwatsonalong with this program; if not, write to the Free Software
20189503SrwatsonFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21189503Srwatson
22189503Srwatson/*
23126262SrwatsonSUBSECTION
24126262Srwatson	S-Record handling
25126262Srwatson
26126262SrwatsonDESCRIPTION
27126262Srwatson
28126262Srwatson	Ordinary S-Records cannot hold anything but addresses and
29126262Srwatson	data, so that's all that we implement.
30126262Srwatson
31126262Srwatson	The only interesting thing is that S-Records may come out of
32126262Srwatson	order and there is no header, so an initial scan is required
33126262Srwatson	to discover the minimum and maximum addresses used to create
34126262Srwatson	the vma and size of the only section we create.  We
35126262Srwatson	arbitrarily call this section ".text".
36126262Srwatson
37126262Srwatson	When bfd_get_section_contents is called the file is read
38126262Srwatson	again, and this time the data is placed into a bfd_alloc'd
39126262Srwatson	area.
40126262Srwatson
41126262Srwatson	Any number of sections may be created for output, we save them
42126262Srwatson	up and output them when it's time to close the bfd.
43126262Srwatson
44126262Srwatson	An s record looks like:
45126262Srwatson
46126262SrwatsonEXAMPLE
47126262Srwatson	S<type><length><address><data><checksum>
48189503Srwatson
49126262SrwatsonDESCRIPTION
50126262Srwatson	Where
51126262Srwatson	o length
52126262Srwatson	is the number of bytes following upto the checksum. Note that
53126262Srwatson	this is not the number of chars following, since it takes two
54126262Srwatson	chars to represent a byte.
55126262Srwatson	o type
56126262Srwatson	is one of:
57189503Srwatson	0) header record
58126262Srwatson	1) two byte address data record
59126262Srwatson	2) three byte address data record
60126262Srwatson	3) four byte address data record
61126262Srwatson	7) four byte address termination record
62126262Srwatson	8) three byte address termination record
63126262Srwatson	9) two byte address termination record
64126262Srwatson
65126262Srwatson	o address
66126262Srwatson	is the start address of the data following, or in the case of
67126262Srwatson	a termination record, the start address of the image
68126262Srwatson	o data
69126262Srwatson	is the data.
70126262Srwatson	o checksum
71126262Srwatson	is the sum of all the raw byte data in the record, from the length
72126262Srwatson	upwards, modulo 256 and subtracted from 255.
73126262Srwatson
74163606Srwatson
75126262SrwatsonSUBSECTION
76165469Srwatson	Symbol S-Record handling
77126262Srwatson
78126262SrwatsonDESCRIPTION
79126262Srwatson	Some ICE equipment understands an addition to the standard
80126262Srwatson	S-Record format; symbols and their addresses can be sent
81126262Srwatson	before the data.
82126262Srwatson
83126262Srwatson	The format of this is:
84126262Srwatson	($$ <modulename>
85126262Srwatson		(<space> <symbol> <address>)*)
86126262Srwatson	$$
87189797Srwatson
88191731Srwatson	so a short symbol table could look like:
89189797Srwatson
90191731SrwatsonEXAMPLE
91126262Srwatson	$$ flash.x
92191731Srwatson	$$ flash.c
93126262Srwatson	  _port6 $0
94126262Srwatson	  _delay $4
95126262Srwatson	  _start $14
96126262Srwatson	  _etext $8036
97126262Srwatson	  _edata $8036
98126262Srwatson 	  _end $8036
99126262Srwatson	$$
100172930Srwatson
101126262SrwatsonDESCRIPTION
102126262Srwatson	We allow symbols to be anywhere in the data stream - the module names
103182063Srwatson	are always ignored.
104182063Srwatson
105182063Srwatson*/
106182063Srwatson
107182063Srwatson#include "bfd.h"
108182063Srwatson#include "sysdep.h"
109126262Srwatson#include "libbfd.h"
110126262Srwatson#include "libiberty.h"
111126262Srwatson#include <ctype.h>
112126262Srwatson
113126262Srwatsonstatic void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
114126262Srwatsonstatic void srec_print_symbol
115126262Srwatson PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
116126262Srwatsonstatic void srec_init PARAMS ((void));
117126262Srwatsonstatic boolean srec_mkobject PARAMS ((bfd *));
118126262Srwatsonstatic int srec_get_byte PARAMS ((bfd *, boolean *));
119126262Srwatsonstatic void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
120126262Srwatsonstatic boolean srec_scan PARAMS ((bfd *));
121126262Srwatsonstatic const bfd_target *srec_object_p PARAMS ((bfd *));
122189797Srwatsonstatic const bfd_target *symbolsrec_object_p PARAMS ((bfd *));
123191731Srwatsonstatic boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *));
124189797Srwatson
125191731Srwatsonstatic boolean srec_write_record PARAMS ((bfd *, int, bfd_vma,
126126262Srwatson					  const bfd_byte *,
127191731Srwatson					  const bfd_byte *));
128126262Srwatsonstatic boolean srec_write_header PARAMS ((bfd *));
129126262Srwatsonstatic boolean srec_write_symbols PARAMS ((bfd *));
130126262Srwatsonstatic boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma));
131126262Srwatsonstatic boolean srec_get_section_contents
132126262Srwatson  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
133126262Srwatsonstatic boolean srec_set_arch_mach
134126262Srwatson  PARAMS ((bfd *, enum bfd_architecture, unsigned long));
135179781Srwatsonstatic boolean srec_set_section_contents
136126262Srwatson  PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
137126262Srwatsonstatic boolean internal_srec_write_object_contents PARAMS ((bfd *, int));
138182063Srwatsonstatic boolean srec_write_object_contents PARAMS ((bfd *));
139182063Srwatsonstatic boolean symbolsrec_write_object_contents PARAMS ((bfd *));
140182063Srwatsonstatic int srec_sizeof_headers PARAMS ((bfd *, boolean));
141182063Srwatsonstatic asymbol *srec_make_empty_symbol PARAMS ((bfd *));
142182063Srwatsonstatic long srec_get_symtab_upper_bound PARAMS ((bfd *));
143182063Srwatsonstatic long srec_get_symtab PARAMS ((bfd *, asymbol **));
144126262Srwatson
145126262Srwatson/* Macros for converting between hex and binary. */
146126262Srwatson
147126262Srwatsonstatic CONST char digs[] = "0123456789ABCDEF";
148126262Srwatson
149126262Srwatson#define NIBBLE(x) hex_value(x)
150126262Srwatson#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
151191731Srwatson#define TOHEX(d, x, ch) \
152126262Srwatson	d[1] = digs[(x) & 0xf]; \
153126262Srwatson	d[0] = digs[((x)>>4)&0xf]; \
154126262Srwatson	ch += ((x) & 0xff);
155126262Srwatson#define	ISHEX(x)  hex_p(x)
156172930Srwatson
157126262Srwatson/* Initialize by filling in the hex conversion array. */
158126262Srwatson
159182063Srwatsonstatic void
160182063Srwatsonsrec_init ()
161182063Srwatson{
162182063Srwatson  static boolean inited = false;
163126262Srwatson
164126262Srwatson  if (inited == false)
165126262Srwatson    {
166126262Srwatson      inited = true;
167126262Srwatson      hex_init ();
168126262Srwatson    }
169191731Srwatson}
170126262Srwatson
171126262Srwatson/* The maximum number of bytes on a line is FF */
172126262Srwatson#define MAXCHUNK 0xff
173126262Srwatson/* The number of bytes we fit onto a line on output */
174179781Srwatson#define CHUNK 16
175126262Srwatson
176126262Srwatson/* When writing an S-record file, the S-records can not be output as
177182063Srwatson   they are seen.  This structure is used to hold them in memory.  */
178182063Srwatson
179182063Srwatsonstruct srec_data_list_struct
180182063Srwatson{
181126262Srwatson  struct srec_data_list_struct *next;
182126262Srwatson  bfd_byte *data;
183126262Srwatson  bfd_vma where;
184172930Srwatson  bfd_size_type size;
185126262Srwatson};
186126262Srwatson
187191731Srwatsontypedef struct srec_data_list_struct srec_data_list_type;
188189797Srwatson
189126262Srwatson/* When scanning the S-record file, a linked list of srec_symbol
190126262Srwatson   structures is built to represent the symbol table (if there is
191126262Srwatson   one).  */
192179781Srwatson
193126262Srwatsonstruct srec_symbol
194126262Srwatson{
195126262Srwatson  struct srec_symbol *next;
196193391Srwatson  const char *name;
197193391Srwatson  bfd_vma val;
198193391Srwatson};
199168955Srwatson
200126262Srwatson/* The S-record tdata information.  */
201191731Srwatson
202191731Srwatsontypedef struct srec_data_struct
203126262Srwatson  {
204126262Srwatson    srec_data_list_type *head;
205126262Srwatson    srec_data_list_type *tail;
206172930Srwatson    unsigned int type;
207126262Srwatson    struct srec_symbol *symbols;
208168955Srwatson    struct srec_symbol *symtail;
209126262Srwatson    asymbol *csymbols;
210193391Srwatson  }
211193391Srwatsontdata_type;
212193391Srwatson
213168955Srwatsonstatic boolean srec_write_section PARAMS ((bfd *, tdata_type *,
214168955Srwatson					   srec_data_list_type *));
215126262Srwatsonstatic boolean srec_write_terminator PARAMS ((bfd *, tdata_type *));
216191731Srwatson
217191731Srwatson/* Set up the S-record tdata information.  */
218126262Srwatson
219126262Srwatsonstatic boolean
220126262Srwatsonsrec_mkobject (abfd)
221179781Srwatson     bfd *abfd;
222126262Srwatson{
223126262Srwatson  srec_init ();
224126262Srwatson
225193391Srwatson  if (abfd->tdata.srec_data == NULL)
226193391Srwatson    {
227193391Srwatson      tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
228168955Srwatson      if (tdata == NULL)
229126262Srwatson	return false;
230191731Srwatson      abfd->tdata.srec_data = tdata;
231126262Srwatson      tdata->type = 1;
232126262Srwatson      tdata->head = NULL;
233126262Srwatson      tdata->tail = NULL;
234172930Srwatson      tdata->symbols = NULL;
235126262Srwatson      tdata->symtail = NULL;
236126262Srwatson      tdata->csymbols = NULL;
237126262Srwatson    }
238178321Srwatson
239193391Srwatson  return true;
240193391Srwatson}
241193391Srwatson
242193391Srwatson/* Read a byte from an S record file.  Set *ERRORPTR if an error
243126262Srwatson   occurred.  Return EOF on error or end of file.  */
244126262Srwatson
245191731Srwatsonstatic int
246189797Srwatsonsrec_get_byte (abfd, errorptr)
247126262Srwatson     bfd *abfd;
248126262Srwatson     boolean *errorptr;
249126262Srwatson{
250179781Srwatson  bfd_byte c;
251126262Srwatson
252126262Srwatson  if (bfd_read (&c, 1, 1, abfd) != 1)
253126262Srwatson    {
254126262Srwatson      if (bfd_get_error () != bfd_error_file_truncated)
255193391Srwatson	*errorptr = true;
256193391Srwatson      return EOF;
257193391Srwatson    }
258168955Srwatson
259126262Srwatson  return (int) (c & 0xff);
260126262Srwatson}
261191731Srwatson
262126262Srwatson/* Report a problem in an S record file.  FIXME: This probably should
263126262Srwatson   not call fprintf, but we really do need some mechanism for printing
264126262Srwatson   error messages.  */
265126262Srwatson
266126262Srwatsonstatic void
267173095Srwatsonsrec_bad_byte (abfd, lineno, c, error)
268173095Srwatson     bfd *abfd;
269173095Srwatson     unsigned int lineno;
270173095Srwatson     int c;
271193391Srwatson     boolean error;
272193391Srwatson{
273193391Srwatson  if (c == EOF)
274173095Srwatson    {
275173095Srwatson      if (! error)
276173095Srwatson	bfd_set_error (bfd_error_file_truncated);
277191731Srwatson    }
278191731Srwatson  else
279173095Srwatson    {
280173095Srwatson      char buf[10];
281173095Srwatson
282173095Srwatson      if (! isprint (c))
283173102Srwatson	sprintf (buf, "\\%03o", (unsigned int) c);
284126262Srwatson      else
285173102Srwatson	{
286173102Srwatson	  buf[0] = c;
287193391Srwatson	  buf[1] = '\0';
288193391Srwatson	}
289193391Srwatson      (*_bfd_error_handler)
290173102Srwatson	(_("%s:%d: Unexpected character `%s' in S-record file\n"),
291173102Srwatson	 bfd_get_filename (abfd), lineno, buf);
292173102Srwatson      bfd_set_error (bfd_error_bad_value);
293191731Srwatson    }
294191731Srwatson}
295173102Srwatson
296173102Srwatson/* Add a new symbol found in an S-record file.  */
297173102Srwatson
298173102Srwatsonstatic boolean
299173102Srwatsonsrec_new_symbol (abfd, name, val)
300126262Srwatson     bfd *abfd;
301126262Srwatson     const char *name;
302193391Srwatson     bfd_vma val;
303193391Srwatson{
304193391Srwatson  struct srec_symbol *n;
305126262Srwatson
306126262Srwatson  n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol));
307191731Srwatson  if (n == NULL)
308126262Srwatson    return false;
309168955Srwatson
310126262Srwatson  n->name = name;
311173095Srwatson  n->val = val;
312173095Srwatson
313173095Srwatson  if (abfd->tdata.srec_data->symbols == NULL)
314173095Srwatson    abfd->tdata.srec_data->symbols = n;
315193391Srwatson  else
316193391Srwatson    abfd->tdata.srec_data->symtail->next = n;
317193391Srwatson  abfd->tdata.srec_data->symtail = n;
318173095Srwatson  n->next = NULL;
319173095Srwatson
320173095Srwatson  ++abfd->symcount;
321191731Srwatson
322189797Srwatson  return true;
323173095Srwatson}
324173095Srwatson
325173095Srwatson/* Read the S record file and turn it into sections.  We create a new
326173095Srwatson   section for each contiguous set of bytes.  */
327172930Srwatson
328126262Srwatsonstatic boolean
329126262Srwatsonsrec_scan (abfd)
330126262Srwatson     bfd *abfd;
331193391Srwatson{
332193391Srwatson  int c;
333193391Srwatson  unsigned int lineno = 1;
334126262Srwatson  boolean error = false;
335126262Srwatson  bfd_byte *buf = NULL;
336191731Srwatson  size_t bufsize = 0;
337126262Srwatson  asection *sec = NULL;
338126262Srwatson  char *symbuf = NULL;
339126262Srwatson
340179781Srwatson  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
341126262Srwatson    goto error_return;
342126262Srwatson
343126262Srwatson  while ((c = srec_get_byte (abfd, &error)) != EOF)
344193391Srwatson    {
345193391Srwatson      /* We only build sections from contiguous S-records, so if this
346193391Srwatson         is not an S-record, then stop building a section.  */
347168955Srwatson      if (c != 'S' && c != '\r' && c != '\n')
348126262Srwatson	sec = NULL;
349191731Srwatson
350126262Srwatson      switch (c)
351126262Srwatson	{
352189503Srwatson	default:
353189503Srwatson	  srec_bad_byte (abfd, lineno, c, error);
354189503Srwatson	  goto error_return;
355126262Srwatson
356172930Srwatson	case '\n':
357126262Srwatson	  ++lineno;
358126262Srwatson	  break;
359126262Srwatson
360126262Srwatson	case '\r':
361126262Srwatson	  break;
362126262Srwatson
363193391Srwatson	case '$':
364193391Srwatson	  /* Starting a module name, which we ignore.  */
365193391Srwatson	  while ((c = srec_get_byte (abfd, &error)) != '\n'
366126262Srwatson		 && c != EOF)
367126262Srwatson	    ;
368191731Srwatson	  if (c == EOF)
369189797Srwatson	    {
370189503Srwatson	      srec_bad_byte (abfd, lineno, c, error);
371126262Srwatson	      goto error_return;
372126262Srwatson	    }
373126262Srwatson
374126262Srwatson	  ++lineno;
375189503Srwatson
376189503Srwatson	  break;
377189503Srwatson
378183973Sbz	case ' ':
379183973Sbz	  do
380183973Sbz	    {
381183973Sbz	      unsigned int alc;
382183973Sbz	      char *p, *symname;
383183973Sbz	      bfd_vma symval;
384183973Sbz
385191731Srwatson	      /* Starting a symbol definition.  */
386191731Srwatson	      while ((c = srec_get_byte (abfd, &error)) != EOF
387189503Srwatson		     && (c == ' ' || c == '\t'))
388183973Sbz		;
389183973Sbz
390183973Sbz	      if (c == '\n' || c == '\r')
391183973Sbz		break;
392126262Srwatson
393126262Srwatson	      if (c == EOF)
394126262Srwatson		{
395126262Srwatson		  srec_bad_byte (abfd, lineno, c, error);
396178285Srwatson		  goto error_return;
397165599Srwatson		}
398189797Srwatson
399191731Srwatson	      alc = 10;
400189797Srwatson	      symbuf = (char *) bfd_malloc (alc + 1);
401126262Srwatson	      if (symbuf == NULL)
402162238Scsjp		goto error_return;
403162238Scsjp
404173102Srwatson	      p = symbuf;
405173102Srwatson
406173102Srwatson	      *p++ = c;
407173102Srwatson	      while ((c = srec_get_byte (abfd, &error)) != EOF
408173102Srwatson		     && ! isspace (c))
409173102Srwatson		{
410173102Srwatson		  if ((unsigned int) (p - symbuf) >= alc)
411193391Srwatson		    {
412193391Srwatson		      char *n;
413193391Srwatson
414173102Srwatson		      alc *= 2;
415173102Srwatson		      n = (char *) bfd_realloc (symbuf, alc + 1);
416173102Srwatson		      if (n == NULL)
417191731Srwatson			goto error_return;
418191731Srwatson		      p = n + (p - symbuf);
419173102Srwatson		      symbuf = n;
420173102Srwatson		    }
421173102Srwatson
422173018Srwatson		  *p++ = c;
423162238Scsjp		}
424162238Scsjp
425162238Scsjp	      if (c == EOF)
426162238Scsjp		{
427189797Srwatson		  srec_bad_byte (abfd, lineno, c, error);
428193391Srwatson		  goto error_return;
429193391Srwatson		}
430193391Srwatson
431162238Scsjp	      *p++ = '\0';
432189797Srwatson	      symname = bfd_alloc (abfd, p - symbuf);
433191731Srwatson	      if (symname == NULL)
434162238Scsjp		goto error_return;
435165149Scsjp	      strcpy (symname, symbuf);
436165149Scsjp	      free (symbuf);
437165420Srwatson	      symbuf = NULL;
438165420Srwatson
439165420Srwatson	      while ((c = srec_get_byte (abfd, &error)) != EOF
440165420Srwatson		     && (c == ' ' || c == '\t'))
441165420Srwatson		;
442165420Srwatson	      if (c == EOF)
443165420Srwatson		{
444165149Scsjp		  srec_bad_byte (abfd, lineno, c, error);
445165149Scsjp		  goto error_return;
446172970Srwatson		}
447165149Scsjp
448165149Scsjp	      /* Skip a dollar sign before the hex value.  */
449182063Srwatson	      if (c == '$')
450191731Srwatson		{
451182063Srwatson		  c = srec_get_byte (abfd, &error);
452182063Srwatson		  if (c == EOF)
453182063Srwatson		    {
454165149Scsjp		      srec_bad_byte (abfd, lineno, c, error);
455165149Scsjp		      goto error_return;
456165149Scsjp		    }
457172970Srwatson		}
458165149Scsjp
459165149Scsjp	      symval = 0;
460165149Scsjp	      while (ISHEX (c))
461182063Srwatson		{
462182063Srwatson		  symval <<= 4;
463182063Srwatson		  symval += NIBBLE (c);
464182063Srwatson		  c = srec_get_byte (abfd, &error);
465182063Srwatson		}
466182063Srwatson
467182063Srwatson	      if (! srec_new_symbol (abfd, symname, symval))
468182063Srwatson		goto error_return;
469182063Srwatson	    }
470182063Srwatson	  while (c == ' ' || c == '\t');
471182063Srwatson
472191731Srwatson	  if (c == '\n')
473191731Srwatson	    ++lineno;
474182063Srwatson	  else if (c != '\r')
475191731Srwatson	    {
476191731Srwatson	      srec_bad_byte (abfd, lineno, c, error);
477182063Srwatson	      goto error_return;
478182063Srwatson	    }
479182063Srwatson
480182063Srwatson	  break;
481182063Srwatson
482182063Srwatson	case 'S':
483165149Scsjp	  {
484165149Scsjp	    file_ptr pos;
485165149Scsjp	    char hdr[3];
486172970Srwatson	    unsigned int bytes;
487165149Scsjp	    bfd_vma address;
488165149Scsjp	    bfd_byte *data;
489178285Srwatson
490189797Srwatson	    /* Starting an S-record.  */
491191731Srwatson
492165149Scsjp	    pos = bfd_tell (abfd) - 1;
493165149Scsjp
494165149Scsjp	    if (bfd_read (hdr, 1, 3, abfd) != 3)
495172970Srwatson	      goto error_return;
496165149Scsjp
497168955Srwatson	    if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
498165149Scsjp	      {
499165149Scsjp		if (! ISHEX (hdr[1]))
500189797Srwatson		  c = hdr[1];
501193391Srwatson		else
502193391Srwatson		  c = hdr[2];
503193391Srwatson		srec_bad_byte (abfd, lineno, c, error);
504168955Srwatson		goto error_return;
505189797Srwatson	      }
506191731Srwatson
507191731Srwatson	    bytes = HEX (hdr + 1);
508165149Scsjp	    if (bytes * 2 > bufsize)
509	      {
510		if (buf != NULL)
511		  free (buf);
512		buf = (bfd_byte *) bfd_malloc (bytes * 2);
513		if (buf == NULL)
514		  goto error_return;
515		bufsize = bytes * 2;
516	      }
517
518	    if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
519	      goto error_return;
520
521	    /* Ignore the checksum byte.  */
522	    --bytes;
523
524	    address = 0;
525	    data = buf;
526	    switch (hdr[0])
527	      {
528	      case '0':
529	      case '5':
530		/* Prologue--ignore the file name, but stop building a
531                   section at this point.  */
532		sec = NULL;
533		break;
534
535	      case '3':
536		address = HEX (data);
537		data += 2;
538		--bytes;
539		/* Fall through.  */
540	      case '2':
541		address = (address << 8) | HEX (data);
542		data += 2;
543		--bytes;
544		/* Fall through.  */
545	      case '1':
546		address = (address << 8) | HEX (data);
547		data += 2;
548		address = (address << 8) | HEX (data);
549		data += 2;
550		bytes -= 2;
551
552		if (sec != NULL
553		    && sec->vma + sec->_raw_size == address)
554		  {
555		    /* This data goes at the end of the section we are
556                       currently building.  */
557		    sec->_raw_size += bytes;
558		  }
559		else
560		  {
561		    char secbuf[20];
562		    char *secname;
563
564		    sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
565		    secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);
566		    strcpy (secname, secbuf);
567		    sec = bfd_make_section (abfd, secname);
568		    if (sec == NULL)
569		      goto error_return;
570		    sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
571		    sec->vma = address;
572		    sec->lma = address;
573		    sec->_raw_size = bytes;
574		    sec->filepos = pos;
575		  }
576
577		break;
578
579	      case '7':
580		address = HEX (data);
581		data += 2;
582		/* Fall through.  */
583	      case '8':
584		address = (address << 8) | HEX (data);
585		data += 2;
586		/* Fall through.  */
587	      case '9':
588		address = (address << 8) | HEX (data);
589		data += 2;
590		address = (address << 8) | HEX (data);
591		data += 2;
592
593		/* This is a termination record.  */
594		abfd->start_address = address;
595
596		if (buf != NULL)
597		  free (buf);
598
599		return true;
600	      }
601	  }
602	  break;
603	}
604    }
605
606  if (error)
607    goto error_return;
608
609  if (buf != NULL)
610    free (buf);
611
612  return true;
613
614 error_return:
615  if (symbuf != NULL)
616    free (symbuf);
617  if (buf != NULL)
618    free (buf);
619  return false;
620}
621
622/* Check whether an existing file is an S-record file.  */
623
624static const bfd_target *
625srec_object_p (abfd)
626     bfd *abfd;
627{
628  bfd_byte b[4];
629
630  srec_init ();
631
632  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
633      || bfd_read (b, 1, 4, abfd) != 4)
634    return NULL;
635
636  if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
637    {
638      bfd_set_error (bfd_error_wrong_format);
639      return NULL;
640    }
641
642  if (! srec_mkobject (abfd)
643      || ! srec_scan (abfd))
644    return NULL;
645
646  if (abfd->symcount > 0)
647    abfd->flags |= HAS_SYMS;
648
649  return abfd->xvec;
650}
651
652/* Check whether an existing file is an S-record file with symbols.  */
653
654static const bfd_target *
655symbolsrec_object_p (abfd)
656     bfd *abfd;
657{
658  char b[2];
659
660  srec_init ();
661
662  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
663      || bfd_read (b, 1, 2, abfd) != 2)
664    return NULL;
665
666  if (b[0] != '$' || b[1] != '$')
667    {
668      bfd_set_error (bfd_error_wrong_format);
669      return NULL;
670    }
671
672  if (! srec_mkobject (abfd)
673      || ! srec_scan (abfd))
674    return NULL;
675
676  if (abfd->symcount > 0)
677    abfd->flags |= HAS_SYMS;
678
679  return abfd->xvec;
680}
681
682/* Read in the contents of a section in an S-record file.  */
683
684static boolean
685srec_read_section (abfd, section, contents)
686     bfd *abfd;
687     asection *section;
688     bfd_byte *contents;
689{
690  int c;
691  bfd_size_type sofar = 0;
692  boolean error = false;
693  bfd_byte *buf = NULL;
694  size_t bufsize = 0;
695
696  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
697    goto error_return;
698
699  while ((c = srec_get_byte (abfd, &error)) != EOF)
700    {
701      bfd_byte hdr[3];
702      unsigned int bytes;
703      bfd_vma address;
704      bfd_byte *data;
705
706      if (c == '\r' || c == '\n')
707	continue;
708
709      /* This is called after srec_scan has already been called, so we
710         ought to know the exact format.  */
711      BFD_ASSERT (c == 'S');
712
713      if (bfd_read (hdr, 1, 3, abfd) != 3)
714	goto error_return;
715
716      BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
717
718      bytes = HEX (hdr + 1);
719
720      if (bytes * 2 > bufsize)
721	{
722	  if (buf != NULL)
723	    free (buf);
724	  buf = (bfd_byte *) bfd_malloc (bytes * 2);
725	  if (buf == NULL)
726	    goto error_return;
727	  bufsize = bytes * 2;
728	}
729
730      if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
731	goto error_return;
732
733      address = 0;
734      data = buf;
735      switch (hdr[0])
736	{
737	default:
738	  BFD_ASSERT (sofar == section->_raw_size);
739	  if (buf != NULL)
740	    free (buf);
741	  return true;
742
743	case '3':
744	  address = HEX (data);
745	  data += 2;
746	  --bytes;
747	  /* Fall through.  */
748	case '2':
749	  address = (address << 8) | HEX (data);
750	  data += 2;
751	  --bytes;
752	  /* Fall through.  */
753	case '1':
754	  address = (address << 8) | HEX (data);
755	  data += 2;
756	  address = (address << 8) | HEX (data);
757	  data += 2;
758	  bytes -= 2;
759
760	  if (address != section->vma + sofar)
761	    {
762	      /* We've come to the end of this section.  */
763	      BFD_ASSERT (sofar == section->_raw_size);
764	      if (buf != NULL)
765		free (buf);
766	      return true;
767	    }
768
769	  /* Don't consider checksum.  */
770	  --bytes;
771
772	  while (bytes-- != 0)
773	    {
774	      contents[sofar] = HEX (data);
775	      data += 2;
776	      ++sofar;
777	    }
778
779	  break;
780	}
781    }
782
783  if (error)
784    goto error_return;
785
786  BFD_ASSERT (sofar == section->_raw_size);
787
788  if (buf != NULL)
789    free (buf);
790
791  return true;
792
793 error_return:
794  if (buf != NULL)
795    free (buf);
796  return false;
797}
798
799/* Get the contents of a section in an S-record file.  */
800
801static boolean
802srec_get_section_contents (abfd, section, location, offset, count)
803     bfd *abfd;
804     asection *section;
805     PTR location;
806     file_ptr offset;
807     bfd_size_type count;
808{
809  if (section->used_by_bfd == NULL)
810    {
811      section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
812      if (section->used_by_bfd == NULL
813	  && section->_raw_size != 0)
814	return false;
815
816      if (! srec_read_section (abfd, section, section->used_by_bfd))
817	return false;
818    }
819
820  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
821	  (size_t) count);
822
823  return true;
824}
825
826/* Set the architecture.  We accept an unknown architecture here.  */
827
828static boolean
829srec_set_arch_mach (abfd, arch, mach)
830     bfd *abfd;
831     enum bfd_architecture arch;
832     unsigned long mach;
833{
834  if (arch == bfd_arch_unknown)
835    {
836      abfd->arch_info = &bfd_default_arch_struct;
837      return true;
838    }
839  return bfd_default_set_arch_mach (abfd, arch, mach);
840}
841
842/* we have to save up all the Srecords for a splurge before output */
843
844static boolean
845srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
846     bfd *abfd;
847     sec_ptr section;
848     PTR location;
849     file_ptr offset;
850     bfd_size_type bytes_to_do;
851{
852  tdata_type *tdata = abfd->tdata.srec_data;
853  register srec_data_list_type *entry;
854
855  entry = ((srec_data_list_type *)
856	   bfd_alloc (abfd, sizeof (srec_data_list_type)));
857  if (entry == NULL)
858    return false;
859
860  if (bytes_to_do
861      && (section->flags & SEC_ALLOC)
862      && (section->flags & SEC_LOAD))
863    {
864      bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
865      if (data == NULL)
866	return false;
867      memcpy ((PTR) data, location, (size_t) bytes_to_do);
868
869      if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
870	{
871
872	}
873      else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
874	       && tdata->type <= 2)
875	{
876	  tdata->type = 2;
877	}
878      else
879	{
880	  tdata->type = 3;
881	}
882
883      entry->data = data;
884      entry->where = section->lma + offset;
885      entry->size = bytes_to_do;
886
887      /* Sort the records by address.  Optimize for the common case of
888         adding a record to the end of the list.  */
889      if (tdata->tail != NULL
890	  && entry->where >= tdata->tail->where)
891	{
892	  tdata->tail->next = entry;
893	  entry->next = NULL;
894	  tdata->tail = entry;
895	}
896      else
897	{
898	  register srec_data_list_type **look;
899
900	  for (look = &tdata->head;
901	       *look != NULL && (*look)->where < entry->where;
902	       look = &(*look)->next)
903	    ;
904	  entry->next = *look;
905	  *look = entry;
906	  if (entry->next == NULL)
907	    tdata->tail = entry;
908	}
909    }
910  return true;
911}
912
913/* Write a record of type, of the supplied number of bytes. The
914   supplied bytes and length don't have a checksum. That's worked out
915   here
916*/
917static boolean
918srec_write_record (abfd, type, address, data, end)
919     bfd *abfd;
920     int type;
921     bfd_vma address;
922     const bfd_byte *data;
923     const bfd_byte *end;
924{
925  char buffer[MAXCHUNK];
926  unsigned int check_sum = 0;
927  CONST bfd_byte *src = data;
928  char *dst = buffer;
929  char *length;
930  bfd_size_type wrlen;
931
932  *dst++ = 'S';
933  *dst++ = '0' + type;
934
935  length = dst;
936  dst += 2;			/* leave room for dst*/
937
938  switch (type)
939    {
940    case 3:
941    case 7:
942      TOHEX (dst, (address >> 24), check_sum);
943      dst += 2;
944    case 8:
945    case 2:
946      TOHEX (dst, (address >> 16), check_sum);
947      dst += 2;
948    case 9:
949    case 1:
950    case 0:
951      TOHEX (dst, (address >> 8), check_sum);
952      dst += 2;
953      TOHEX (dst, (address), check_sum);
954      dst += 2;
955      break;
956
957    }
958  for (src = data; src < end; src++)
959    {
960      TOHEX (dst, *src, check_sum);
961      dst += 2;
962    }
963
964  /* Fill in the length */
965  TOHEX (length, (dst - length) / 2, check_sum);
966  check_sum &= 0xff;
967  check_sum = 255 - check_sum;
968  TOHEX (dst, check_sum, check_sum);
969  dst += 2;
970
971  *dst++ = '\r';
972  *dst++ = '\n';
973  wrlen = dst - buffer;
974  if (bfd_write ((PTR) buffer, 1, wrlen, abfd) != wrlen)
975    return false;
976  return true;
977}
978
979
980
981static boolean
982srec_write_header (abfd)
983     bfd *abfd;
984{
985  bfd_byte buffer[MAXCHUNK];
986  bfd_byte *dst = buffer;
987  unsigned int i;
988
989  /* I'll put an arbitary 40 char limit on header size */
990  for (i = 0; i < 40 && abfd->filename[i]; i++)
991    {
992      *dst++ = abfd->filename[i];
993    }
994  return srec_write_record (abfd, 0, 0, buffer, dst);
995}
996
997static boolean
998srec_write_section (abfd, tdata, list)
999     bfd *abfd;
1000     tdata_type *tdata;
1001     srec_data_list_type *list;
1002{
1003  unsigned int octets_written = 0;
1004  bfd_byte *location = list->data;
1005
1006  while (octets_written < list->size)
1007    {
1008      bfd_vma address;
1009      unsigned int octets_this_chunk = list->size - octets_written;
1010
1011      if (octets_this_chunk > CHUNK)
1012	octets_this_chunk = CHUNK;
1013
1014      address = list->where + octets_written / bfd_octets_per_byte (abfd);
1015
1016      if (! srec_write_record (abfd,
1017			       tdata->type,
1018			       address,
1019			       location,
1020			       location + octets_this_chunk))
1021	return false;
1022
1023      octets_written += octets_this_chunk;
1024      location += octets_this_chunk;
1025    }
1026
1027  return true;
1028}
1029
1030static boolean
1031srec_write_terminator (abfd, tdata)
1032     bfd *abfd;
1033     tdata_type *tdata;
1034{
1035  bfd_byte buffer[2];
1036
1037  return srec_write_record (abfd, 10 - tdata->type,
1038			    abfd->start_address, buffer, buffer);
1039}
1040
1041
1042
1043static boolean
1044srec_write_symbols (abfd)
1045     bfd *abfd;
1046{
1047  char buffer[MAXCHUNK];
1048  /* Dump out the symbols of a bfd */
1049  int i;
1050  int count = bfd_get_symcount (abfd);
1051
1052  if (count)
1053    {
1054      size_t len;
1055      asymbol **table = bfd_get_outsymbols (abfd);
1056      sprintf (buffer, "$$ %s\r\n", abfd->filename);
1057
1058      len = strlen (buffer);
1059      if (bfd_write (buffer, len, 1, abfd) != len)
1060	return false;
1061
1062      for (i = 0; i < count; i++)
1063	{
1064	  asymbol *s = table[i];
1065	  if (! bfd_is_local_label (abfd, s)
1066	      && (s->flags & BSF_DEBUGGING) == 0)
1067	    {
1068	      /* Just dump out non debug symbols */
1069	      bfd_size_type l;
1070	      char buf2[40], *p;
1071
1072	      sprintf_vma (buf2,
1073			   s->value + s->section->output_section->lma
1074			   + s->section->output_offset);
1075	      p = buf2;
1076	      while (p[0] == '0' && p[1] != 0)
1077		p++;
1078	      sprintf (buffer, "  %s $%s\r\n", s->name, p);
1079	      l = strlen (buffer);
1080	      if (bfd_write (buffer, l, 1, abfd) != l)
1081		return false;
1082	    }
1083	}
1084      sprintf (buffer, "$$ \r\n");
1085      len = strlen (buffer);
1086      if (bfd_write (buffer, len, 1, abfd) != len)
1087	return false;
1088    }
1089
1090  return true;
1091}
1092
1093static boolean
1094internal_srec_write_object_contents (abfd, symbols)
1095     bfd *abfd;
1096     int symbols;
1097{
1098  tdata_type *tdata = abfd->tdata.srec_data;
1099  srec_data_list_type *list;
1100
1101  if (symbols)
1102    {
1103      if (! srec_write_symbols (abfd))
1104	return false;
1105    }
1106
1107  if (! srec_write_header (abfd))
1108    return false;
1109
1110  /* Now wander though all the sections provided and output them */
1111  list = tdata->head;
1112
1113  while (list != (srec_data_list_type *) NULL)
1114    {
1115      if (! srec_write_section (abfd, tdata, list))
1116	return false;
1117      list = list->next;
1118    }
1119  return srec_write_terminator (abfd, tdata);
1120}
1121
1122static boolean
1123srec_write_object_contents (abfd)
1124     bfd *abfd;
1125{
1126  return internal_srec_write_object_contents (abfd, 0);
1127}
1128
1129static boolean
1130symbolsrec_write_object_contents (abfd)
1131     bfd *abfd;
1132{
1133  return internal_srec_write_object_contents (abfd, 1);
1134}
1135
1136/*ARGSUSED*/
1137static int
1138srec_sizeof_headers (abfd, exec)
1139     bfd *abfd ATTRIBUTE_UNUSED;
1140     boolean exec ATTRIBUTE_UNUSED;
1141{
1142  return 0;
1143}
1144
1145static asymbol *
1146srec_make_empty_symbol (abfd)
1147     bfd *abfd;
1148{
1149  asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
1150  if (new)
1151    new->the_bfd = abfd;
1152  return new;
1153}
1154
1155/* Return the amount of memory needed to read the symbol table.  */
1156
1157static long
1158srec_get_symtab_upper_bound (abfd)
1159     bfd *abfd;
1160{
1161  return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
1162}
1163
1164/* Return the symbol table.  */
1165
1166static long
1167srec_get_symtab (abfd, alocation)
1168     bfd *abfd;
1169     asymbol **alocation;
1170{
1171  unsigned int symcount = bfd_get_symcount (abfd);
1172  asymbol *csymbols;
1173  unsigned int i;
1174
1175  csymbols = abfd->tdata.srec_data->csymbols;
1176  if (csymbols == NULL)
1177    {
1178      asymbol *c;
1179      struct srec_symbol *s;
1180
1181      csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
1182      if (csymbols == NULL && symcount != 0)
1183	return false;
1184      abfd->tdata.srec_data->csymbols = csymbols;
1185
1186      for (s = abfd->tdata.srec_data->symbols, c = csymbols;
1187	   s != NULL;
1188	   s = s->next, ++c)
1189	{
1190	  c->the_bfd = abfd;
1191	  c->name = s->name;
1192	  c->value = s->val;
1193	  c->flags = BSF_GLOBAL;
1194	  c->section = bfd_abs_section_ptr;
1195	  c->udata.p = NULL;
1196	}
1197    }
1198
1199  for (i = 0; i < symcount; i++)
1200    *alocation++ = csymbols++;
1201  *alocation = NULL;
1202
1203  return symcount;
1204}
1205
1206/*ARGSUSED*/
1207static void
1208srec_get_symbol_info (ignore_abfd, symbol, ret)
1209     bfd *ignore_abfd ATTRIBUTE_UNUSED;
1210     asymbol *symbol;
1211     symbol_info *ret;
1212{
1213  bfd_symbol_info (symbol, ret);
1214}
1215
1216/*ARGSUSED*/
1217static void
1218srec_print_symbol (ignore_abfd, afile, symbol, how)
1219     bfd *ignore_abfd ATTRIBUTE_UNUSED;
1220     PTR afile;
1221     asymbol *symbol;
1222     bfd_print_symbol_type how;
1223{
1224  FILE *file = (FILE *) afile;
1225  switch (how)
1226    {
1227    case bfd_print_symbol_name:
1228      fprintf (file, "%s", symbol->name);
1229      break;
1230    default:
1231      bfd_print_symbol_vandf ((PTR) file, symbol);
1232      fprintf (file, " %-5s %s",
1233	       symbol->section->name,
1234	       symbol->name);
1235
1236    }
1237}
1238
1239#define	srec_close_and_cleanup _bfd_generic_close_and_cleanup
1240#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1241#define srec_new_section_hook _bfd_generic_new_section_hook
1242
1243#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name
1244#define srec_get_lineno _bfd_nosymbols_get_lineno
1245#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
1246#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1247#define srec_read_minisymbols _bfd_generic_read_minisymbols
1248#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1249
1250#define srec_get_reloc_upper_bound \
1251  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
1252#define srec_canonicalize_reloc \
1253  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
1254#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1255
1256#define srec_get_section_contents_in_window \
1257  _bfd_generic_get_section_contents_in_window
1258
1259#define srec_bfd_get_relocated_section_contents \
1260  bfd_generic_get_relocated_section_contents
1261#define srec_bfd_relax_section bfd_generic_relax_section
1262#define srec_bfd_gc_sections bfd_generic_gc_sections
1263#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1264#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
1265#define srec_bfd_final_link _bfd_generic_final_link
1266#define srec_bfd_link_split_section _bfd_generic_link_split_section
1267
1268const bfd_target srec_vec =
1269{
1270  "srec",			/* name */
1271  bfd_target_srec_flavour,
1272  BFD_ENDIAN_UNKNOWN,		/* target byte order */
1273  BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
1274  (HAS_RELOC | EXEC_P |		/* object flags */
1275   HAS_LINENO | HAS_DEBUG |
1276   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1277  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1278   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
1279  0,				/* leading underscore */
1280  ' ',				/* ar_pad_char */
1281  16,				/* ar_max_namelen */
1282  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1283  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1284  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
1285  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1286  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1287  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
1288
1289  {
1290    _bfd_dummy_target,
1291    srec_object_p,		/* bfd_check_format */
1292    _bfd_dummy_target,
1293    _bfd_dummy_target,
1294  },
1295  {
1296    bfd_false,
1297    srec_mkobject,
1298    _bfd_generic_mkarchive,
1299    bfd_false,
1300  },
1301  {				/* bfd_write_contents */
1302    bfd_false,
1303    srec_write_object_contents,
1304    _bfd_write_archive_contents,
1305    bfd_false,
1306  },
1307
1308  BFD_JUMP_TABLE_GENERIC (srec),
1309  BFD_JUMP_TABLE_COPY (_bfd_generic),
1310  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1311  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1312  BFD_JUMP_TABLE_SYMBOLS (srec),
1313  BFD_JUMP_TABLE_RELOCS (srec),
1314  BFD_JUMP_TABLE_WRITE (srec),
1315  BFD_JUMP_TABLE_LINK (srec),
1316  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1317
1318  NULL,
1319
1320  (PTR) 0
1321};
1322
1323
1324
1325const bfd_target symbolsrec_vec =
1326{
1327  "symbolsrec",			/* name */
1328  bfd_target_srec_flavour,
1329  BFD_ENDIAN_UNKNOWN,		/* target byte order */
1330  BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
1331  (HAS_RELOC | EXEC_P |		/* object flags */
1332   HAS_LINENO | HAS_DEBUG |
1333   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1334  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1335   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
1336  0,				/* leading underscore */
1337  ' ',				/* ar_pad_char */
1338  16,				/* ar_max_namelen */
1339  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1340  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1341  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
1342  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1343  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1344  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
1345
1346  {
1347    _bfd_dummy_target,
1348    symbolsrec_object_p,	/* bfd_check_format */
1349    _bfd_dummy_target,
1350    _bfd_dummy_target,
1351  },
1352  {
1353    bfd_false,
1354    srec_mkobject,
1355    _bfd_generic_mkarchive,
1356    bfd_false,
1357  },
1358  {				/* bfd_write_contents */
1359    bfd_false,
1360    symbolsrec_write_object_contents,
1361    _bfd_write_archive_contents,
1362    bfd_false,
1363  },
1364
1365  BFD_JUMP_TABLE_GENERIC (srec),
1366  BFD_JUMP_TABLE_COPY (_bfd_generic),
1367  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1368  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1369  BFD_JUMP_TABLE_SYMBOLS (srec),
1370  BFD_JUMP_TABLE_RELOCS (srec),
1371  BFD_JUMP_TABLE_WRITE (srec),
1372  BFD_JUMP_TABLE_LINK (srec),
1373  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1374
1375  NULL,
1376
1377  (PTR) 0
1378};
1379