Coverage Report

Created: 2026-07-12 09:22

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