Subversion Repositories Kolibri OS

Rev

Rev 5197 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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