Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/srec.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD back-end for s-record objects.
2
   Copyright (C) 1990-2025 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
361k
#define NIBBLE(x)    hex_value(x)
116
173k
#define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1]))
117
#define TOHEX(d, x, ch) \
118
0
  d[1] = digs[(x) & 0xf]; \
119
0
  d[0] = digs[((x)>>4)&0xf]; \
120
0
  ch += ((x) & 0xff);
121
59.3k
#define ISHEX(x)    hex_p(x)
122
123
/* The maximum number of address+data+crc bytes on a line is FF.  */
124
0
#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
6.85M
{
181
6.85M
  static bool inited = false;
182
183
6.85M
  if (! inited)
184
11
    {
185
11
      inited = true;
186
11
      hex_init ();
187
11
    }
188
6.85M
}
189
190
/* Set up the S-record tdata information.  */
191
192
static bool
193
srec_mkobject (bfd *abfd)
194
28.8k
{
195
28.8k
  tdata_type *tdata;
196
197
28.8k
  srec_init ();
198
199
28.8k
  tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
200
28.8k
  if (tdata == NULL)
201
0
    return false;
202
203
28.8k
  abfd->tdata.srec_data = tdata;
204
28.8k
  tdata->type = 1;
205
28.8k
  tdata->head = NULL;
206
28.8k
  tdata->tail = NULL;
207
28.8k
  tdata->symbols = NULL;
208
28.8k
  tdata->symtail = NULL;
209
28.8k
  tdata->csymbols = NULL;
210
211
28.8k
  return true;
212
28.8k
}
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
1.43M
{
220
1.43M
  bfd_byte c;
221
222
1.43M
  if (bfd_read (&c, 1, abfd) != 1)
223
20.0k
    {
224
20.0k
      if (bfd_get_error () != bfd_error_file_truncated)
225
2.92k
  *errorptr = true;
226
20.0k
      return EOF;
227
20.0k
    }
228
229
1.41M
  return (int) (c & 0xff);
230
1.43M
}
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
9.59k
{
242
9.59k
  if (c == EOF)
243
5.84k
    {
244
5.84k
      if (! error)
245
3.33k
  bfd_set_error (bfd_error_file_truncated);
246
5.84k
    }
247
3.74k
  else
248
3.74k
    {
249
3.74k
      char buf[40];
250
251
3.74k
      if (! ISPRINT (c))
252
2.06k
  sprintf (buf, "\\%03o", (unsigned int) c & 0xff);
253
1.68k
      else
254
1.68k
  {
255
1.68k
    buf[0] = c;
256
1.68k
    buf[1] = '\0';
257
1.68k
  }
258
3.74k
      _bfd_error_handler
259
  /* xgettext:c-format */
260
3.74k
  (_("%pB:%d: unexpected character `%s' in S-record file"),
261
3.74k
   abfd, lineno, buf);
262
3.74k
      bfd_set_error (bfd_error_bad_value);
263
3.74k
    }
264
9.59k
}
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
23.1k
{
271
23.1k
  struct srec_symbol *n;
272
273
23.1k
  n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (* n));
274
23.1k
  if (n == NULL)
275
0
    return false;
276
277
23.1k
  n->name = name;
278
23.1k
  n->val = val;
279
280
23.1k
  if (abfd->tdata.srec_data->symbols == NULL)
281
11.0k
    abfd->tdata.srec_data->symbols = n;
282
12.0k
  else
283
12.0k
    abfd->tdata.srec_data->symtail->next = n;
284
23.1k
  abfd->tdata.srec_data->symtail = n;
285
23.1k
  n->next = NULL;
286
287
23.1k
  ++abfd->symcount;
288
289
23.1k
  return true;
290
23.1k
}
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
28.8k
{
298
28.8k
  int c;
299
28.8k
  unsigned int lineno = 1;
300
28.8k
  bool error = false;
301
28.8k
  bfd_byte *buf = NULL;
302
28.8k
  size_t bufsize = 0;
303
28.8k
  asection *sec = NULL;
304
28.8k
  char *symbuf = NULL;
305
306
28.8k
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
307
0
    goto error_return;
308
309
132k
  while ((c = srec_get_byte (abfd, &error)) != EOF)
310
118k
    {
311
      /* We only build sections from contiguous S-records, so if this
312
   is not an S-record, then stop building a section.  */
313
118k
      if (c != 'S' && c != '\r' && c != '\n')
314
62.6k
  sec = NULL;
315
316
118k
      switch (c)
317
118k
  {
318
1.61k
  default:
319
1.61k
    srec_bad_byte (abfd, lineno, c, error);
320
1.61k
    goto error_return;
321
322
25.9k
  case '\n':
323
25.9k
    ++lineno;
324
25.9k
    break;
325
326
7.71k
  case '\r':
327
7.71k
    break;
328
329
33.3k
  case '$':
330
    /* Starting a module name, which we ignore.  */
331
803k
    while ((c = srec_get_byte (abfd, &error)) != '\n'
332
803k
     && c != EOF)
333
769k
      ;
334
33.3k
    if (c == EOF)
335
1.02k
      {
336
1.02k
        srec_bad_byte (abfd, lineno, c, error);
337
1.02k
        goto error_return;
338
1.02k
      }
339
340
32.3k
    ++lineno;
341
32.3k
    break;
342
343
27.6k
  case ' ':
344
27.6k
    do
345
36.5k
      {
346
36.5k
        bfd_size_type alc;
347
36.5k
        char *p, *symname;
348
36.5k
        bfd_vma symval;
349
350
        /* Starting a symbol definition.  */
351
61.1k
        while ((c = srec_get_byte (abfd, &error)) != EOF
352
61.1k
         && (c == ' ' || c == '\t'))
353
24.5k
    ;
354
355
36.5k
        if (c == '\n' || c == '\r')
356
8.66k
    break;
357
358
27.9k
        if (c == EOF)
359
1.19k
    {
360
1.19k
      srec_bad_byte (abfd, lineno, c, error);
361
1.19k
      goto error_return;
362
1.19k
    }
363
364
26.7k
        alc = 10;
365
26.7k
        symbuf = (char *) bfd_malloc (alc + 1);
366
26.7k
        if (symbuf == NULL)
367
0
    goto error_return;
368
369
26.7k
        p = symbuf;
370
371
26.7k
        *p++ = c;
372
375k
        while ((c = srec_get_byte (abfd, &error)) != EOF
373
375k
         && ! ISSPACE (c))
374
348k
    {
375
348k
      if ((bfd_size_type) (p - symbuf) >= alc)
376
8.91k
        {
377
8.91k
          char *n;
378
379
8.91k
          alc *= 2;
380
8.91k
          n = (char *) bfd_realloc (symbuf, alc + 1);
381
8.91k
          if (n == NULL)
382
0
      goto error_return;
383
8.91k
          p = n + (p - symbuf);
384
8.91k
          symbuf = n;
385
8.91k
        }
386
387
348k
      *p++ = c;
388
348k
    }
389
390
26.7k
        if (c == EOF)
391
1.37k
    {
392
1.37k
      srec_bad_byte (abfd, lineno, c, error);
393
1.37k
      goto error_return;
394
1.37k
    }
395
396
25.3k
        *p++ = '\0';
397
25.3k
        symname = (char *) bfd_alloc (abfd, (bfd_size_type) (p - symbuf));
398
25.3k
        if (symname == NULL)
399
0
    goto error_return;
400
25.3k
        strcpy (symname, symbuf);
401
25.3k
        free (symbuf);
402
25.3k
        symbuf = NULL;
403
404
40.0k
        while ((c = srec_get_byte (abfd, &error)) != EOF
405
40.0k
         && (c == ' ' || c == '\t'))
406
14.6k
    ;
407
25.3k
        if (c == EOF)
408
882
    {
409
882
      srec_bad_byte (abfd, lineno, c, error);
410
882
      goto error_return;
411
882
    }
412
413
        /* Skip a dollar sign before the hex value.  */
414
24.4k
        if (c == '$')
415
7.69k
    {
416
7.69k
      c = srec_get_byte (abfd, &error);
417
7.69k
      if (c == EOF)
418
420
        {
419
420
          srec_bad_byte (abfd, lineno, c, error);
420
420
          goto error_return;
421
420
        }
422
7.69k
    }
423
424
24.0k
        symval = 0;
425
24.0k
        while (ISHEX (c))
426
14.7k
    {
427
14.7k
      symval <<= 4;
428
14.7k
      symval += NIBBLE (c);
429
14.7k
      c = srec_get_byte (abfd, &error);
430
14.7k
      if (c == EOF)
431
946
        {
432
946
          srec_bad_byte (abfd, lineno, c, error);
433
946
          goto error_return;
434
946
        }
435
14.7k
    }
436
437
23.1k
        if (! srec_new_symbol (abfd, symname, symval))
438
0
    goto error_return;
439
23.1k
      }
440
27.6k
    while (c == ' ' || c == '\t')
441
22.8k
      ;
442
443
22.8k
    if (c == '\n')
444
9.31k
      ++lineno;
445
13.5k
    else if (c != '\r')
446
1.28k
      {
447
1.28k
        srec_bad_byte (abfd, lineno, c, error);
448
1.28k
        goto error_return;
449
1.28k
      }
450
451
21.5k
    break;
452
453
22.3k
  case 'S':
454
22.3k
    {
455
22.3k
      file_ptr pos;
456
22.3k
      unsigned char hdr[3];
457
22.3k
      unsigned int bytes, min_bytes;
458
22.3k
      bfd_vma address;
459
22.3k
      bfd_byte *data;
460
22.3k
      unsigned char check_sum;
461
462
      /* Starting an S-record.  */
463
464
22.3k
      pos = bfd_tell (abfd) - 1;
465
466
22.3k
      if (bfd_read (hdr, 3, abfd) != 3)
467
323
        goto error_return;
468
469
22.0k
      if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
470
847
        {
471
847
    if (! ISHEX (hdr[1]))
472
534
      c = hdr[1];
473
313
    else
474
313
      c = hdr[2];
475
847
    srec_bad_byte (abfd, lineno, c, error);
476
847
    goto error_return;
477
847
        }
478
479
21.1k
      check_sum = bytes = HEX (hdr + 1);
480
21.1k
      min_bytes = 3;
481
21.1k
      if (hdr[0] == '2' || hdr[0] == '8')
482
6.95k
        min_bytes = 4;
483
14.2k
      else if (hdr[0] == '3' || hdr[0] == '7')
484
1.83k
        min_bytes = 5;
485
21.1k
      if (bytes < min_bytes)
486
411
        {
487
    /* xgettext:c-format */
488
411
    _bfd_error_handler (_("%pB:%d: byte count %d too small"),
489
411
            abfd, lineno, bytes);
490
411
    bfd_set_error (bfd_error_bad_value);
491
411
    goto error_return;
492
411
        }
493
494
20.7k
      if (bytes * 2 > bufsize)
495
9.31k
        {
496
9.31k
    free (buf);
497
9.31k
    buf = bfd_malloc (bytes * 2);
498
9.31k
    if (buf == NULL)
499
0
      goto error_return;
500
9.31k
    bufsize = bytes * 2;
501
9.31k
        }
502
503
20.7k
      if (bfd_read (buf, bytes * 2, abfd) != bytes * 2)
504
1.83k
        goto error_return;
505
506
      /* Ignore the checksum byte.  */
507
18.9k
      --bytes;
508
509
18.9k
      address = 0;
510
18.9k
      data = buf;
511
18.9k
      switch (hdr[0])
512
18.9k
        {
513
1.95k
        case '0':
514
2.99k
        case '5':
515
    /* Prologue--ignore the file name, but stop building a
516
       section at this point.  */
517
2.99k
    sec = NULL;
518
2.99k
    break;
519
520
903
        case '3':
521
903
    check_sum += HEX (data);
522
903
    address = HEX (data);
523
903
    data += 2;
524
903
    --bytes;
525
    /* Fall through.  */
526
6.68k
        case '2':
527
6.68k
    check_sum += HEX (data);
528
6.68k
    address = (address << 8) | HEX (data);
529
6.68k
    data += 2;
530
6.68k
    --bytes;
531
    /* Fall through.  */
532
9.97k
        case '1':
533
9.97k
    check_sum += HEX (data);
534
9.97k
    address = (address << 8) | HEX (data);
535
9.97k
    data += 2;
536
9.97k
    check_sum += HEX (data);
537
9.97k
    address = (address << 8) | HEX (data);
538
9.97k
    data += 2;
539
9.97k
    bytes -= 2;
540
541
9.97k
    if (sec != NULL
542
9.97k
        && sec->vma + sec->size == address)
543
826
      {
544
        /* This data goes at the end of the section we are
545
           currently building.  */
546
826
        sec->size += bytes;
547
826
      }
548
9.14k
    else
549
9.14k
      {
550
9.14k
        char secbuf[20];
551
9.14k
        char *secname;
552
9.14k
        size_t amt;
553
9.14k
        flagword flags;
554
555
9.14k
        sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
556
9.14k
        amt = strlen (secbuf) + 1;
557
9.14k
        secname = (char *) bfd_alloc (abfd, amt);
558
9.14k
        strcpy (secname, secbuf);
559
9.14k
        flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
560
9.14k
        sec = bfd_make_section_with_flags (abfd, secname, flags);
561
9.14k
        if (sec == NULL)
562
0
          goto error_return;
563
9.14k
        sec->vma = address;
564
9.14k
        sec->lma = address;
565
9.14k
        sec->size = bytes;
566
9.14k
        sec->filepos = pos;
567
9.14k
      }
568
569
83.4k
    while (bytes > 0)
570
73.4k
      {
571
73.4k
        check_sum += HEX (data);
572
73.4k
        data += 2;
573
73.4k
        bytes--;
574
73.4k
      }
575
9.97k
    check_sum = 255 - (check_sum & 0xff);
576
9.97k
    if (check_sum != HEX (data))
577
1.21k
      {
578
1.21k
        _bfd_error_handler
579
          /* xgettext:c-format */
580
1.21k
          (_("%pB:%d: bad checksum in S-record file"),
581
1.21k
           abfd, lineno);
582
1.21k
        bfd_set_error (bfd_error_bad_value);
583
1.21k
        goto error_return;
584
1.21k
      }
585
586
8.75k
    break;
587
588
8.75k
        case '7':
589
310
    check_sum += HEX (data);
590
310
    address = HEX (data);
591
310
    data += 2;
592
    /* Fall through.  */
593
860
        case '8':
594
860
    check_sum += HEX (data);
595
860
    address = (address << 8) | HEX (data);
596
860
    data += 2;
597
    /* Fall through.  */
598
1.30k
        case '9':
599
1.30k
    check_sum += HEX (data);
600
1.30k
    address = (address << 8) | HEX (data);
601
1.30k
    data += 2;
602
1.30k
    check_sum += HEX (data);
603
1.30k
    address = (address << 8) | HEX (data);
604
1.30k
    data += 2;
605
606
    /* This is a termination record.  */
607
1.30k
    abfd->start_address = address;
608
609
1.30k
    check_sum = 255 - (check_sum & 0xff);
610
1.30k
    if (check_sum != HEX (data))
611
827
      {
612
827
        _bfd_error_handler
613
          /* xgettext:c-format */
614
827
          (_("%pB:%d: bad checksum in S-record file"),
615
827
           abfd, lineno);
616
827
        bfd_set_error (bfd_error_bad_value);
617
827
        goto error_return;
618
827
      }
619
620
478
    free (buf);
621
478
    return true;
622
18.9k
        }
623
18.9k
    }
624
16.4k
    break;
625
118k
  }
626
118k
    }
627
628
14.1k
  if (error)
629
418
    goto error_return;
630
631
13.7k
  free (buf);
632
13.7k
  return true;
633
634
14.6k
 error_return:
635
14.6k
  free (symbuf);
636
14.6k
  free (buf);
637
14.6k
  return false;
638
14.1k
}
639
640
/* Check whether an existing file is an S-record file.  */
641
642
static bfd_cleanup
643
srec_object_p (bfd *abfd)
644
3.41M
{
645
3.41M
  bfd_byte b[4];
646
647
3.41M
  srec_init ();
648
649
3.41M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
650
3.41M
      || bfd_read (b, 4, abfd) != 4)
651
3.74k
    return NULL;
652
653
3.40M
  if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
654
3.40M
    {
655
3.40M
      bfd_set_error (bfd_error_wrong_format);
656
3.40M
      return NULL;
657
3.40M
    }
658
659
4.17k
  if (!srec_mkobject (abfd))
660
0
    return NULL;
661
662
4.17k
  if (!srec_scan (abfd))
663
2.42k
    {
664
2.42k
      bfd_release (abfd, abfd->tdata.any);
665
2.42k
      return NULL;
666
2.42k
    }
667
668
1.75k
  if (abfd->symcount > 0)
669
471
    abfd->flags |= HAS_SYMS;
670
671
1.75k
  return _bfd_no_cleanup;
672
4.17k
}
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
3.41M
{
679
3.41M
  char b[2];
680
681
3.41M
  srec_init ();
682
683
3.41M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
684
3.41M
      || bfd_read (b, 2, abfd) != 2)
685
1.90k
    return NULL;
686
687
3.41M
  if (b[0] != '$' || b[1] != '$')
688
3.38M
    {
689
3.38M
      bfd_set_error (bfd_error_wrong_format);
690
3.38M
      return NULL;
691
3.38M
    }
692
693
24.6k
  if (!srec_mkobject (abfd))
694
0
    return NULL;
695
696
24.6k
  if (!srec_scan (abfd))
697
12.1k
    {
698
12.1k
      bfd_release (abfd, abfd->tdata.any);
699
12.1k
      return NULL;
700
12.1k
    }
701
702
12.4k
  if (abfd->symcount > 0)
703
6.69k
    abfd->flags |= HAS_SYMS;
704
705
12.4k
  return _bfd_no_cleanup;
706
24.6k
}
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
685
{
713
685
  int c;
714
685
  bfd_size_type sofar = 0;
715
685
  bool error = false;
716
685
  bfd_byte *buf = NULL;
717
685
  size_t bufsize = 0;
718
719
685
  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
720
0
    goto error_return;
721
722
2.09k
  while ((c = srec_get_byte (abfd, &error)) != EOF)
723
2.08k
    {
724
2.08k
      bfd_byte hdr[3];
725
2.08k
      unsigned int bytes;
726
2.08k
      bfd_vma address;
727
2.08k
      bfd_byte *data;
728
729
2.08k
      if (c == '\r' || c == '\n')
730
727
  continue;
731
732
      /* This is called after srec_scan has already been called, so we
733
   ought to know the exact format.  */
734
1.35k
      if (c != 'S')
735
4
  goto error_return;
736
737
1.35k
      if (bfd_read (hdr, 3, abfd) != 3)
738
0
  goto error_return;
739
740
1.35k
      BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
741
742
1.35k
      bytes = HEX (hdr + 1);
743
744
1.35k
      if (bytes * 2 > bufsize)
745
685
  {
746
685
    free (buf);
747
685
    buf = bfd_malloc (bytes * 2);
748
685
    if (buf == NULL)
749
0
      goto error_return;
750
685
    bufsize = bytes * 2;
751
685
  }
752
753
1.35k
      if (bfd_read (buf, bytes * 2, abfd) != bytes * 2)
754
0
  goto error_return;
755
756
1.35k
      address = 0;
757
1.35k
      data = buf;
758
1.35k
      switch (hdr[0])
759
1.35k
  {
760
9
  default:
761
9
    if (sofar != section->size)
762
0
      goto error_return;
763
9
    free (buf);
764
9
    return true;
765
766
0
  case '3':
767
0
    address = HEX (data);
768
0
    data += 2;
769
0
    --bytes;
770
    /* Fall through.  */
771
2
  case '2':
772
2
    address = (address << 8) | HEX (data);
773
2
    data += 2;
774
2
    --bytes;
775
    /* Fall through.  */
776
1.34k
  case '1':
777
1.34k
    address = (address << 8) | HEX (data);
778
1.34k
    data += 2;
779
1.34k
    address = (address << 8) | HEX (data);
780
1.34k
    data += 2;
781
1.34k
    bytes -= 2;
782
783
1.34k
    if (address != section->vma + sofar)
784
659
      {
785
        /* We've come to the end of this section.  */
786
659
        if (sofar != section->size)
787
0
    goto error_return;
788
659
        free (buf);
789
659
        return true;
790
659
      }
791
792
    /* Don't consider checksum.  */
793
686
    --bytes;
794
795
1.37k
    while (bytes-- != 0)
796
686
      {
797
686
        contents[sofar] = HEX (data);
798
686
        data += 2;
799
686
        ++sofar;
800
686
      }
801
802
686
    break;
803
1.35k
  }
804
1.35k
    }
805
806
13
  if (error)
807
0
    goto error_return;
808
809
13
  if (sofar != section->size)
810
0
    goto error_return;
811
812
13
  free (buf);
813
13
  return true;
814
815
4
 error_return:
816
4
  free (buf);
817
4
  return false;
818
13
}
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
685
{
829
685
  if (count == 0)
830
0
    return true;
831
832
685
  if (offset + count < count
833
685
      || offset + count > section->size)
834
0
    {
835
0
      bfd_set_error (bfd_error_invalid_operation);
836
0
      return false;
837
0
    }
838
839
685
  if (section->used_by_bfd == NULL)
840
685
    {
841
685
      section->used_by_bfd = bfd_alloc (abfd, section->size);
842
685
      if (section->used_by_bfd == NULL)
843
0
  return false;
844
845
685
      if (! srec_read_section (abfd, section,
846
685
             (bfd_byte *) section->used_by_bfd))
847
4
  return false;
848
685
    }
849
850
681
  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
851
681
    (size_t) count);
852
853
681
  return true;
854
685
}
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
0
{
861
0
  if (arch != bfd_arch_unknown)
862
0
    return bfd_default_set_arch_mach (abfd, arch, mach);
863
864
0
  abfd->arch_info = & bfd_default_arch_struct;
865
0
  return true;
866
0
}
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
0
{
877
0
  int opb = bfd_octets_per_byte (abfd, NULL);
878
0
  tdata_type *tdata = abfd->tdata.srec_data;
879
0
  srec_data_list_type *entry;
880
881
0
  entry = (srec_data_list_type *) bfd_alloc (abfd, sizeof (* entry));
882
0
  if (entry == NULL)
883
0
    return false;
884
885
0
  if (bytes_to_do
886
0
      && (section->flags & SEC_ALLOC)
887
0
      && (section->flags & SEC_LOAD))
888
0
    {
889
0
      bfd_byte *data;
890
891
0
      data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
892
0
      if (data == NULL)
893
0
  return false;
894
0
      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
0
      if (_bfd_srec_forceS3)
899
0
  tdata->type = 3;
900
0
      else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffff)
901
0
  ;  /* The default, S1, is OK.  */
902
0
      else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffffff
903
0
         && tdata->type <= 2)
904
0
  tdata->type = 2;
905
0
      else
906
0
  tdata->type = 3;
907
908
0
      entry->data = data;
909
0
      entry->where = section->lma + offset / opb;
910
0
      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
0
      if (tdata->tail != NULL
915
0
    && entry->where >= tdata->tail->where)
916
0
  {
917
0
    tdata->tail->next = entry;
918
0
    entry->next = NULL;
919
0
    tdata->tail = entry;
920
0
  }
921
0
      else
922
0
  {
923
0
    srec_data_list_type **look;
924
925
0
    for (look = &tdata->head;
926
0
         *look != NULL && (*look)->where < entry->where;
927
0
         look = &(*look)->next)
928
0
      ;
929
0
    entry->next = *look;
930
0
    *look = entry;
931
0
    if (entry->next == NULL)
932
0
      tdata->tail = entry;
933
0
  }
934
0
    }
935
0
  return true;
936
0
}
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
0
{
949
0
  char buffer[2 * MAXCHUNK + 6];
950
0
  unsigned int check_sum = 0;
951
0
  const bfd_byte *src = data;
952
0
  char *dst = buffer;
953
0
  char *length;
954
0
  bfd_size_type wrlen;
955
956
0
  *dst++ = 'S';
957
0
  *dst++ = '0' + type;
958
959
0
  length = dst;
960
0
  dst += 2;     /* Leave room for dst.  */
961
962
0
  switch (type)
963
0
    {
964
0
    case 3:
965
0
    case 7:
966
0
      TOHEX (dst, (address >> 24), check_sum);
967
0
      dst += 2;
968
      /* Fall through.  */
969
0
    case 8:
970
0
    case 2:
971
0
      TOHEX (dst, (address >> 16), check_sum);
972
0
      dst += 2;
973
      /* Fall through.  */
974
0
    case 9:
975
0
    case 1:
976
0
    case 0:
977
0
      TOHEX (dst, (address >> 8), check_sum);
978
0
      dst += 2;
979
0
      TOHEX (dst, (address), check_sum);
980
0
      dst += 2;
981
0
      break;
982
983
0
    }
984
0
  for (src = data; src < end; src++)
985
0
    {
986
0
      TOHEX (dst, *src, check_sum);
987
0
      dst += 2;
988
0
    }
989
990
  /* Fill in the length.  */
991
0
  TOHEX (length, (dst - length) / 2, check_sum);
992
0
  check_sum &= 0xff;
993
0
  check_sum = 255 - check_sum;
994
0
  TOHEX (dst, check_sum, check_sum);
995
0
  dst += 2;
996
997
0
  *dst++ = '\r';
998
0
  *dst++ = '\n';
999
0
  wrlen = dst - buffer;
1000
1001
0
  return bfd_write (buffer, wrlen, abfd) == wrlen;
1002
0
}
1003
1004
static bool
1005
srec_write_header (bfd *abfd)
1006
0
{
1007
0
  unsigned int len = strlen (bfd_get_filename (abfd));
1008
1009
  /* I'll put an arbitrary 40 char limit on header size.  */
1010
0
  if (len > 40)
1011
0
    len = 40;
1012
1013
0
  return srec_write_record (abfd, 0, (bfd_vma) 0,
1014
0
          (bfd_byte *) bfd_get_filename (abfd),
1015
0
          (bfd_byte *) bfd_get_filename (abfd) + len);
1016
0
}
1017
1018
static bool
1019
srec_write_section (bfd *abfd,
1020
        tdata_type *tdata,
1021
        srec_data_list_type *list)
1022
0
{
1023
0
  unsigned int octets_written = 0;
1024
0
  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
0
  if (_bfd_srec_len == 0)
1033
0
    _bfd_srec_len = 1;
1034
0
  else if (_bfd_srec_len > MAXCHUNK - tdata->type - 2)
1035
0
    _bfd_srec_len = MAXCHUNK - tdata->type - 2;
1036
1037
0
  while (octets_written < list->size)
1038
0
    {
1039
0
      bfd_vma address;
1040
0
      unsigned int octets_this_chunk = list->size - octets_written;
1041
1042
0
      if (octets_this_chunk > _bfd_srec_len)
1043
0
  octets_this_chunk = _bfd_srec_len;
1044
1045
0
      address = list->where + (octets_written
1046
0
             / bfd_octets_per_byte (abfd, NULL));
1047
1048
0
      if (! srec_write_record (abfd,
1049
0
             tdata->type,
1050
0
             address,
1051
0
             location,
1052
0
             location + octets_this_chunk))
1053
0
  return false;
1054
1055
0
      octets_written += octets_this_chunk;
1056
0
      location += octets_this_chunk;
1057
0
    }
1058
1059
0
  return true;
1060
0
}
1061
1062
static bool
1063
srec_write_terminator (bfd *abfd, tdata_type *tdata)
1064
0
{
1065
0
  return srec_write_record (abfd, 10 - tdata->type,
1066
0
          abfd->start_address, NULL, NULL);
1067
0
}
1068
1069
static bool
1070
srec_write_symbols (bfd *abfd)
1071
0
{
1072
  /* Dump out the symbols of a bfd.  */
1073
0
  int i;
1074
0
  int count = bfd_get_symcount (abfd);
1075
1076
0
  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
0
  return true;
1118
1119
0
 fail:
1120
0
  return false;
1121
0
}
1122
1123
static bool
1124
internal_srec_write_object_contents (bfd *abfd, int symbols)
1125
0
{
1126
0
  tdata_type *tdata = abfd->tdata.srec_data;
1127
0
  srec_data_list_type *list;
1128
1129
0
  if (symbols)
1130
0
    {
1131
0
      if (! srec_write_symbols (abfd))
1132
0
  return false;
1133
0
    }
1134
1135
0
  if (! srec_write_header (abfd))
1136
0
    return false;
1137
1138
  /* Now wander though all the sections provided and output them.  */
1139
0
  list = tdata->head;
1140
1141
0
  while (list != (srec_data_list_type *) NULL)
1142
0
    {
1143
0
      if (! srec_write_section (abfd, tdata, list))
1144
0
  return false;
1145
0
      list = list->next;
1146
0
    }
1147
0
  return srec_write_terminator (abfd, tdata);
1148
0
}
1149
1150
static bool
1151
srec_write_object_contents (bfd *abfd)
1152
0
{
1153
0
  return internal_srec_write_object_contents (abfd, 0);
1154
0
}
1155
1156
static bool
1157
symbolsrec_write_object_contents (bfd *abfd)
1158
0
{
1159
0
  return internal_srec_write_object_contents (abfd, 1);
1160
0
}
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
179
{
1174
179
  return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
1175
179
}
1176
1177
/* Return the symbol table.  */
1178
1179
static long
1180
srec_canonicalize_symtab (bfd *abfd, asymbol **alocation)
1181
179
{
1182
179
  bfd_size_type symcount = bfd_get_symcount (abfd);
1183
179
  asymbol *csymbols;
1184
179
  unsigned int i;
1185
1186
179
  csymbols = abfd->tdata.srec_data->csymbols;
1187
179
  if (csymbols == NULL && symcount != 0)
1188
110
    {
1189
110
      asymbol *c;
1190
110
      struct srec_symbol *s;
1191
1192
110
      csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
1193
110
      if (csymbols == NULL)
1194
0
  return -1;
1195
110
      abfd->tdata.srec_data->csymbols = csymbols;
1196
1197
110
      for (s = abfd->tdata.srec_data->symbols, c = csymbols;
1198
2.98k
     s != NULL;
1199
2.87k
     s = s->next, ++c)
1200
2.87k
  {
1201
2.87k
    c->the_bfd = abfd;
1202
2.87k
    c->name = s->name;
1203
2.87k
    c->value = s->val;
1204
2.87k
    c->flags = BSF_GLOBAL;
1205
2.87k
    c->section = bfd_abs_section_ptr;
1206
2.87k
    c->udata.p = NULL;
1207
2.87k
  }
1208
110
    }
1209
1210
5.17k
  for (i = 0; i < symcount; i++)
1211
4.99k
    *alocation++ = csymbols++;
1212
179
  *alocation = NULL;
1213
1214
179
  return symcount;
1215
179
}
1216
1217
static void
1218
srec_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
1219
          asymbol *symbol,
1220
          symbol_info *ret)
1221
2.13k
{
1222
2.13k
  bfd_symbol_info (symbol, ret);
1223
2.13k
}
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_merge_sections       bfd_generic_merge_sections
1266
#define srec_bfd_is_group_section     bfd_generic_is_group_section
1267
#define srec_bfd_group_name       bfd_generic_group_name
1268
#define srec_bfd_discard_group        bfd_generic_discard_group
1269
#define srec_section_already_linked     _bfd_generic_section_already_linked
1270
#define srec_bfd_define_common_symbol     bfd_generic_define_common_symbol
1271
#define srec_bfd_link_hide_symbol     _bfd_generic_link_hide_symbol
1272
#define srec_bfd_define_start_stop      bfd_generic_define_start_stop
1273
#define srec_bfd_link_hash_table_create     _bfd_generic_link_hash_table_create
1274
#define srec_bfd_link_add_symbols     _bfd_generic_link_add_symbols
1275
#define srec_bfd_link_just_syms       _bfd_generic_link_just_syms
1276
#define srec_bfd_copy_link_hash_symbol_type   _bfd_generic_copy_link_hash_symbol_type
1277
#define srec_bfd_final_link       _bfd_generic_final_link
1278
#define srec_bfd_link_split_section     _bfd_generic_link_split_section
1279
#define srec_bfd_link_check_relocs      _bfd_generic_link_check_relocs
1280
1281
const bfd_target srec_vec =
1282
{
1283
  "srec",     /* Name.  */
1284
  bfd_target_srec_flavour,
1285
  BFD_ENDIAN_UNKNOWN,   /* Target byte order.  */
1286
  BFD_ENDIAN_UNKNOWN,   /* Target headers byte order.  */
1287
  EXEC_P,     /* Object flags.  */
1288
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1289
   | SEC_ALLOC | SEC_LOAD), /* Section flags.  */
1290
  0,        /* Leading underscore.  */
1291
  ' ',        /* AR_pad_char.  */
1292
  16,       /* AR_max_namelen.  */
1293
  0,        /* match priority.  */
1294
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
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
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1351
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1352
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
1353
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1354
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1355
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1356
1357
  {
1358
    _bfd_dummy_target,
1359
    symbolsrec_object_p,  /* bfd_check_format.  */
1360
    _bfd_dummy_target,
1361
    _bfd_dummy_target,
1362
  },
1363
  {
1364
    _bfd_bool_bfd_false_error,
1365
    srec_mkobject,
1366
    _bfd_bool_bfd_false_error,
1367
    _bfd_bool_bfd_false_error,
1368
  },
1369
  {       /* bfd_write_contents.  */
1370
    _bfd_bool_bfd_false_error,
1371
    symbolsrec_write_object_contents,
1372
    _bfd_bool_bfd_false_error,
1373
    _bfd_bool_bfd_false_error,
1374
  },
1375
1376
  BFD_JUMP_TABLE_GENERIC (srec),
1377
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1378
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1379
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1380
  BFD_JUMP_TABLE_SYMBOLS (srec),
1381
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1382
  BFD_JUMP_TABLE_WRITE (srec),
1383
  BFD_JUMP_TABLE_LINK (srec),
1384
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1385
1386
  NULL,
1387
1388
  NULL
1389
};