Coverage Report

Created: 2023-06-29 07:13

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