Coverage Report

Created: 2023-08-28 06:25

/src/binutils-gdb/bfd/ihex.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD back-end for Intel Hex objects.
2
   Copyright (C) 1995-2023 Free Software Foundation, Inc.
3
   Written by Ian Lance Taylor of Cygnus Support <ian@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
/* This is what Intel Hex files look like:
24
25
1. INTEL FORMATS
26
27
A. Intel 1
28
29
   16-bit address-field format, for files 64k bytes in length or less.
30
31
   DATA RECORD
32
   Byte 1 Header = colon(:)
33
   2..3   The number of data bytes in hex notation
34
   4..5   High byte of the record load address
35
   6..7   Low byte of the record load address
36
   8..9   Record type, must be "00"
37
   10..x  Data bytes in hex notation:
38
  x = (number of bytes - 1) * 2 + 11
39
   x+1..x+2 Checksum in hex notation
40
   x+3..x+4 Carriage return, line feed
41
42
   END RECORD
43
   Byte 1 Header = colon (:)
44
   2..3   The byte count, must be "00"
45
   4..7   Transfer-address (usually "0000")
46
    the jump-to address, execution start address
47
   8..9   Record type, must be "01"
48
   10..11 Checksum, in hex notation
49
   12..13 Carriage return, line feed
50
51
B. INTEL 2
52
53
   MCS-86 format, using a 20-bit address for files larger than 64K bytes.
54
55
   DATA RECORD
56
   Byte 1 Header = colon (:)
57
   2..3   The byte count of this record, hex notation
58
   4..5   High byte of the record load address
59
   6..7   Low byte of the record load address
60
   8..9   Record type, must be "00"
61
   10..x  The data bytes in hex notation:
62
  x = (number of data bytes - 1) * 2 + 11
63
   x+1..x+2 Checksum in hex notation
64
   x+3..x+4 Carriage return, line feed
65
66
   EXTENDED ADDRESS RECORD
67
   Byte 1 Header = colon(:)
68
   2..3   The byte count, must be "02"
69
   4..7   Load address, must be "0000"
70
   8..9   Record type, must be "02"
71
   10..11 High byte of the offset address
72
   12..13 Low byte of the offset address
73
   14..15 Checksum in hex notation
74
   16..17 Carriage return, line feed
75
76
   The checksums are the two's complement of the 8-bit sum
77
   without carry of the byte count, offset address, and the
78
   record type.
79
80
   START ADDRESS RECORD
81
   Byte 1 Header = colon (:)
82
   2..3   The byte count, must be "04"
83
   4..7   Load address, must be "0000"
84
   8..9   Record type, must be "03"
85
   10..13 8086 CS value
86
   14..17 8086 IP value
87
   18..19 Checksum in hex notation
88
   20..21 Carriage return, line feed
89
90
Another document reports these additional types:
91
92
   EXTENDED LINEAR ADDRESS RECORD
93
   Byte 1 Header = colon (:)
94
   2..3   The byte count, must be "02"
95
   4..7   Load address, must be "0000"
96
   8..9   Record type, must be "04"
97
   10..13 Upper 16 bits of address of subsequent records
98
   14..15 Checksum in hex notation
99
   16..17 Carriage return, line feed
100
101
   START LINEAR ADDRESS RECORD
102
   Byte 1 Header = colon (:)
103
   2..3   The byte count, must be "02"
104
   4..7   Load address, must be "0000"
105
   8..9   Record type, must be "05"
106
   10..13 Upper 16 bits of start address
107
   14..15 Checksum in hex notation
108
   16..17 Carriage return, line feed
109
110
The MRI compiler uses this, which is a repeat of type 5:
111
112
  EXTENDED START RECORD
113
   Byte 1 Header = colon (:)
114
   2..3   The byte count, must be "04"
115
   4..7   Load address, must be "0000"
116
   8..9   Record type, must be "05"
117
   10..13 Upper 16 bits of start address
118
   14..17 Lower 16 bits of start address
119
   18..19 Checksum in hex notation
120
   20..21 Carriage return, line feed.  */
121
122
#include "sysdep.h"
123
#include "bfd.h"
124
#include "libbfd.h"
125
#include "libiberty.h"
126
#include "safe-ctype.h"
127
128
/* The number of bytes we put on one line during output.  */
129
130
0
#define CHUNK 16
131
132
/* Macros for converting between hex and binary.  */
133
134
1.63k
#define NIBBLE(x)    (hex_value (x))
135
938
#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
136
130
#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
137
1.93k
#define ISHEX(x)     (hex_p (x))
138
139
/* When we write out an ihex value, the values can not be output as
140
   they are seen.  Instead, we hold them in memory in this structure.  */
141
142
struct ihex_data_list
143
{
144
  struct ihex_data_list *next;
145
  bfd_byte *data;
146
  bfd_vma where;
147
  bfd_size_type size;
148
};
149
150
/* The ihex tdata information.  */
151
152
struct ihex_data_struct
153
{
154
  struct ihex_data_list *head;
155
  struct ihex_data_list *tail;
156
};
157
158
/* Initialize by filling in the hex conversion array.  */
159
160
static void
161
ihex_init (void)
162
115k
{
163
115k
  static bool inited;
164
165
115k
  if (! inited)
166
1
    {
167
1
      inited = true;
168
1
      hex_init ();
169
1
    }
170
115k
}
171
172
/* Create an ihex object.  */
173
174
static bool
175
ihex_mkobject (bfd *abfd)
176
42
{
177
42
  struct ihex_data_struct *tdata;
178
179
42
  tdata = (struct ihex_data_struct *) bfd_alloc (abfd, sizeof (* tdata));
180
42
  if (tdata == NULL)
181
0
    return false;
182
183
42
  abfd->tdata.ihex_data = tdata;
184
42
  tdata->head = NULL;
185
42
  tdata->tail = NULL;
186
42
  return true;
187
42
}
188
189
/* Read a byte from a BFD.  Set *ERRORPTR if an error occurred.
190
   Return EOF on error or end of file.  */
191
192
static inline int
193
ihex_get_byte (bfd *abfd, bool *errorptr)
194
1.31k
{
195
1.31k
  bfd_byte c;
196
197
1.31k
  if (bfd_read (&c, 1, abfd) != 1)
198
4
    {
199
4
      if (bfd_get_error () != bfd_error_file_truncated)
200
0
  *errorptr = true;
201
4
      return EOF;
202
4
    }
203
204
1.31k
  return c & 0xff;
205
1.31k
}
206
207
/* Report a problem in an Intel Hex file.  */
208
209
static void
210
ihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bool error)
211
22
{
212
22
  if (c == EOF)
213
0
    {
214
0
      if (! error)
215
0
  bfd_set_error (bfd_error_file_truncated);
216
0
    }
217
22
  else
218
22
    {
219
22
      char buf[10];
220
221
22
      if (! ISPRINT (c))
222
14
  sprintf (buf, "\\%03o", (unsigned int) c & 0xff);
223
8
      else
224
8
  {
225
8
    buf[0] = c;
226
8
    buf[1] = '\0';
227
8
  }
228
22
      _bfd_error_handler
229
  /* xgettext:c-format */
230
22
  (_("%pB:%d: unexpected character `%s' in Intel Hex file"),
231
22
   abfd, lineno, buf);
232
22
      bfd_set_error (bfd_error_bad_value);
233
22
    }
234
22
}
235
236
/* Read an Intel hex file and turn it into sections.  We create a new
237
   section for each contiguous set of bytes.  */
238
239
static bool
240
ihex_scan (bfd *abfd)
241
42
{
242
42
  bfd_vma segbase;
243
42
  bfd_vma extbase;
244
42
  asection *sec;
245
42
  unsigned int lineno;
246
42
  bool error;
247
42
  bfd_byte *buf = NULL;
248
42
  size_t bufsize;
249
42
  int c;
250
251
42
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
252
0
    goto error_return;
253
254
42
  abfd->start_address = 0;
255
256
42
  segbase = 0;
257
42
  extbase = 0;
258
42
  sec = NULL;
259
42
  lineno = 1;
260
42
  error = false;
261
42
  bufsize = 0;
262
263
1.31k
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
264
1.31k
    {
265
1.31k
      if (c == '\r')
266
94
  continue;
267
1.21k
      else if (c == '\n')
268
1.06k
  {
269
1.06k
    ++lineno;
270
1.06k
    continue;
271
1.06k
  }
272
152
      else if (c != ':')
273
12
  {
274
12
    ihex_bad_byte (abfd, lineno, c, error);
275
12
    goto error_return;
276
12
  }
277
140
      else
278
140
  {
279
140
    file_ptr pos;
280
140
    unsigned char hdr[8];
281
140
    unsigned int i;
282
140
    unsigned int len;
283
140
    bfd_vma addr;
284
140
    unsigned int type;
285
140
    unsigned int chars;
286
140
    unsigned int chksum;
287
288
    /* This is a data record.  */
289
140
    pos = bfd_tell (abfd) - 1;
290
291
    /* Read the header bytes.  */
292
140
    if (bfd_read (hdr, 8, abfd) != 8)
293
4
      goto error_return;
294
295
1.19k
    for (i = 0; i < 8; i++)
296
1.06k
      {
297
1.06k
        if (! ISHEX (hdr[i]))
298
6
    {
299
6
      ihex_bad_byte (abfd, lineno, hdr[i], error);
300
6
      goto error_return;
301
6
    }
302
1.06k
      }
303
304
130
    len = HEX2 (hdr);
305
130
    addr = HEX4 (hdr + 2);
306
130
    type = HEX2 (hdr + 6);
307
308
    /* Read the data bytes.  */
309
130
    chars = len * 2 + 2;
310
130
    if (chars >= bufsize)
311
130
      {
312
130
        buf = bfd_realloc (buf, chars);
313
130
        if (buf == NULL)
314
0
    goto error_return;
315
130
        bufsize = chars;
316
130
      }
317
318
130
    if (bfd_read (buf, chars, abfd) != chars)
319
4
      goto error_return;
320
321
624
    for (i = 0; i < chars; i++)
322
502
      {
323
502
        if (! ISHEX (buf[i]))
324
4
    {
325
4
      ihex_bad_byte (abfd, lineno, buf[i], error);
326
4
      goto error_return;
327
4
    }
328
502
      }
329
330
    /* Check the checksum.  */
331
122
    chksum = len + addr + (addr >> 8) + type;
332
248
    for (i = 0; i < len; i++)
333
126
      chksum += HEX2 (buf + 2 * i);
334
122
    if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
335
4
      {
336
4
        _bfd_error_handler
337
    /* xgettext:c-format */
338
4
    (_("%pB:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
339
4
     abfd, lineno,
340
4
     (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
341
4
        bfd_set_error (bfd_error_bad_value);
342
4
        goto error_return;
343
4
      }
344
345
118
    switch (type)
346
118
      {
347
114
      case 0:
348
        /* This is a data record.  */
349
114
        if (sec != NULL
350
114
      && sec->vma + sec->size == extbase + segbase + addr)
351
0
    {
352
      /* This data goes at the end of the section we are
353
         currently building.  */
354
0
      sec->size += len;
355
0
    }
356
114
        else if (len > 0)
357
0
    {
358
0
      char secbuf[20];
359
0
      char *secname;
360
0
      size_t amt;
361
0
      flagword flags;
362
363
0
      sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
364
0
      amt = strlen (secbuf) + 1;
365
0
      secname = (char *) bfd_alloc (abfd, amt);
366
0
      if (secname == NULL)
367
0
        goto error_return;
368
0
      strcpy (secname, secbuf);
369
0
      flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
370
0
      sec = bfd_make_section_with_flags (abfd, secname, flags);
371
0
      if (sec == NULL)
372
0
        goto error_return;
373
0
      sec->vma = extbase + segbase + addr;
374
0
      sec->lma = extbase + segbase + addr;
375
0
      sec->size = len;
376
0
      sec->filepos = pos;
377
0
    }
378
114
        break;
379
380
114
      case 1:
381
        /* An end record.  */
382
0
        if (abfd->start_address == 0)
383
0
    abfd->start_address = addr;
384
0
        free (buf);
385
0
        return true;
386
387
0
      case 2:
388
        /* An extended address record.  */
389
0
        if (len != 2)
390
0
    {
391
0
      _bfd_error_handler
392
        /* xgettext:c-format */
393
0
        (_("%pB:%u: bad extended address record length in Intel Hex file"),
394
0
         abfd, lineno);
395
0
      bfd_set_error (bfd_error_bad_value);
396
0
      goto error_return;
397
0
    }
398
399
0
        segbase = HEX4 (buf) << 4;
400
401
0
        sec = NULL;
402
403
0
        break;
404
405
0
      case 3:
406
        /* An extended start address record.  */
407
0
        if (len != 4)
408
0
    {
409
0
      _bfd_error_handler
410
        /* xgettext:c-format */
411
0
        (_("%pB:%u: bad extended start address length in Intel Hex file"),
412
0
         abfd, lineno);
413
0
      bfd_set_error (bfd_error_bad_value);
414
0
      goto error_return;
415
0
    }
416
417
0
        abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
418
419
0
        sec = NULL;
420
421
0
        break;
422
423
0
      case 4:
424
        /* An extended linear address record.  */
425
0
        if (len != 2)
426
0
    {
427
0
      _bfd_error_handler
428
        /* xgettext:c-format */
429
0
        (_("%pB:%u: bad extended linear address record length in Intel Hex file"),
430
0
         abfd, lineno);
431
0
      bfd_set_error (bfd_error_bad_value);
432
0
      goto error_return;
433
0
    }
434
435
0
        extbase = HEX4 (buf) << 16;
436
437
0
        sec = NULL;
438
439
0
        break;
440
441
2
      case 5:
442
        /* An extended linear start address record.  */
443
2
        if (len != 2 && len != 4)
444
2
    {
445
2
      _bfd_error_handler
446
        /* xgettext:c-format */
447
2
        (_("%pB:%u: bad extended linear start address length in Intel Hex file"),
448
2
         abfd, lineno);
449
2
      bfd_set_error (bfd_error_bad_value);
450
2
      goto error_return;
451
2
    }
452
453
0
        if (len == 2)
454
0
    abfd->start_address += HEX4 (buf) << 16;
455
0
        else
456
0
    abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
457
458
0
        sec = NULL;
459
460
0
        break;
461
462
2
      default:
463
2
        _bfd_error_handler
464
    /* xgettext:c-format */
465
2
    (_("%pB:%u: unrecognized ihex type %u in Intel Hex file"),
466
2
     abfd, lineno, type);
467
2
        bfd_set_error (bfd_error_bad_value);
468
2
        goto error_return;
469
118
      }
470
118
  }
471
1.31k
    }
472
473
4
  if (error)
474
0
    goto error_return;
475
476
4
  free (buf);
477
4
  return true;
478
479
38
 error_return:
480
38
  free (buf);
481
38
  return false;
482
4
}
483
484
/* Try to recognize an Intel Hex file.  */
485
486
static bfd_cleanup
487
ihex_object_p (bfd *abfd)
488
115k
{
489
115k
  void * tdata_save;
490
115k
  bfd_byte b[9];
491
115k
  unsigned int i;
492
115k
  unsigned int type;
493
494
115k
  ihex_init ();
495
496
115k
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
497
0
    return NULL;
498
115k
  if (bfd_read (b, 9, abfd) != 9)
499
578
    {
500
578
      if (bfd_get_error () == bfd_error_file_truncated)
501
18
  bfd_set_error (bfd_error_wrong_format);
502
578
      return NULL;
503
578
    }
504
505
114k
  if (b[0] != ':')
506
114k
    {
507
114k
      bfd_set_error (bfd_error_wrong_format);
508
114k
      return NULL;
509
114k
    }
510
511
410
  for (i = 1; i < 9; i++)
512
366
    {
513
366
      if (! ISHEX (b[i]))
514
8
  {
515
8
    bfd_set_error (bfd_error_wrong_format);
516
8
    return NULL;
517
8
  }
518
366
    }
519
520
44
  type = HEX2 (b + 7);
521
44
  if (type > 5)
522
2
    {
523
2
      bfd_set_error (bfd_error_wrong_format);
524
2
      return NULL;
525
2
    }
526
527
  /* OK, it looks like it really is an Intel Hex file.  */
528
42
  tdata_save = abfd->tdata.any;
529
42
  if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
530
38
    {
531
38
      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
532
38
  bfd_release (abfd, abfd->tdata.any);
533
38
      abfd->tdata.any = tdata_save;
534
38
      return NULL;
535
38
    }
536
537
4
  return _bfd_no_cleanup;
538
42
}
539
540
/* Read the contents of a section in an Intel Hex file.  */
541
542
static bool
543
ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
544
0
{
545
0
  int c;
546
0
  bfd_byte *p;
547
0
  bfd_byte *buf = NULL;
548
0
  size_t bufsize;
549
0
  bool error;
550
551
0
  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
552
0
    goto error_return;
553
554
0
  p = contents;
555
0
  bufsize = 0;
556
0
  error = false;
557
0
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
558
0
    {
559
0
      unsigned char hdr[8];
560
0
      unsigned int len;
561
0
      unsigned int type;
562
0
      unsigned int i;
563
564
0
      if (c == '\r' || c == '\n')
565
0
  continue;
566
567
      /* This is called after ihex_scan has succeeded, so we ought to
568
   know the exact format.  */
569
0
      BFD_ASSERT (c == ':');
570
571
0
      if (bfd_read (hdr, 8, abfd) != 8)
572
0
  goto error_return;
573
574
0
      len = HEX2 (hdr);
575
0
      type = HEX2 (hdr + 6);
576
577
      /* We should only see type 0 records here.  */
578
0
      if (type != 0)
579
0
  {
580
0
    _bfd_error_handler
581
0
      (_("%pB: internal error in ihex_read_section"), abfd);
582
0
    bfd_set_error (bfd_error_bad_value);
583
0
    goto error_return;
584
0
  }
585
586
0
      if (len * 2 > bufsize)
587
0
  {
588
0
    buf = bfd_realloc (buf, len * 2);
589
0
    if (buf == NULL)
590
0
      goto error_return;
591
0
    bufsize = len * 2;
592
0
  }
593
594
0
      if (bfd_read (buf, len * 2, abfd) != len * 2)
595
0
  goto error_return;
596
597
0
      for (i = 0; i < len; i++)
598
0
  *p++ = HEX2 (buf + 2 * i);
599
0
      if ((bfd_size_type) (p - contents) >= section->size)
600
0
  {
601
    /* We've read everything in the section.  */
602
0
    free (buf);
603
0
    return true;
604
0
  }
605
606
      /* Skip the checksum.  */
607
0
      if (bfd_read (buf, 2, abfd) != 2)
608
0
  goto error_return;
609
0
    }
610
611
0
  if ((bfd_size_type) (p - contents) < section->size)
612
0
    {
613
0
      _bfd_error_handler
614
0
  (_("%pB: bad section length in ihex_read_section"), abfd);
615
0
      bfd_set_error (bfd_error_bad_value);
616
0
      goto error_return;
617
0
    }
618
619
0
  free (buf);
620
0
  return true;
621
622
0
 error_return:
623
0
  free (buf);
624
0
  return false;
625
0
}
626
627
/* Get the contents of a section in an Intel Hex file.  */
628
629
static bool
630
ihex_get_section_contents (bfd *abfd,
631
         asection *section,
632
         void * location,
633
         file_ptr offset,
634
         bfd_size_type count)
635
0
{
636
0
  if (section->used_by_bfd == NULL)
637
0
    {
638
0
      section->used_by_bfd = bfd_alloc (abfd, section->size);
639
0
      if (section->used_by_bfd == NULL)
640
0
  return false;
641
0
      if (! ihex_read_section (abfd, section,
642
0
             (bfd_byte *) section->used_by_bfd))
643
0
  return false;
644
0
    }
645
646
0
  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
647
0
    (size_t) count);
648
649
0
  return true;
650
0
}
651
652
/* Set the contents of a section in an Intel Hex file.  */
653
654
static bool
655
ihex_set_section_contents (bfd *abfd,
656
         asection *section,
657
         const void * location,
658
         file_ptr offset,
659
         bfd_size_type count)
660
0
{
661
0
  struct ihex_data_list *n;
662
0
  bfd_byte *data;
663
0
  struct ihex_data_struct *tdata;
664
665
0
  if (count == 0
666
0
      || (section->flags & SEC_ALLOC) == 0
667
0
      || (section->flags & SEC_LOAD) == 0)
668
0
    return true;
669
670
0
  n = (struct ihex_data_list *) bfd_alloc (abfd, sizeof (* n));
671
0
  if (n == NULL)
672
0
    return false;
673
674
0
  data = (bfd_byte *) bfd_alloc (abfd, count);
675
0
  if (data == NULL)
676
0
    return false;
677
0
  memcpy (data, location, (size_t) count);
678
679
0
  n->data = data;
680
0
  n->where = section->lma + offset;
681
0
  n->size = count;
682
683
  /* Sort the records by address.  Optimize for the common case of
684
     adding a record to the end of the list.  */
685
0
  tdata = abfd->tdata.ihex_data;
686
0
  if (tdata->tail != NULL
687
0
      && n->where >= tdata->tail->where)
688
0
    {
689
0
      tdata->tail->next = n;
690
0
      n->next = NULL;
691
0
      tdata->tail = n;
692
0
    }
693
0
  else
694
0
    {
695
0
      struct ihex_data_list **pp;
696
697
0
      for (pp = &tdata->head;
698
0
     *pp != NULL && (*pp)->where < n->where;
699
0
     pp = &(*pp)->next)
700
0
  ;
701
0
      n->next = *pp;
702
0
      *pp = n;
703
0
      if (n->next == NULL)
704
0
  tdata->tail = n;
705
0
    }
706
707
0
  return true;
708
0
}
709
710
/* Write a record out to an Intel Hex file.  */
711
712
static bool
713
ihex_write_record (bfd *abfd,
714
       size_t count,
715
       unsigned int addr,
716
       unsigned int type,
717
       bfd_byte *data)
718
0
{
719
0
  static const char digs[] = "0123456789ABCDEF";
720
0
  char buf[9 + CHUNK * 2 + 4];
721
0
  char *p;
722
0
  unsigned int chksum;
723
0
  unsigned int i;
724
0
  size_t total;
725
726
0
#define TOHEX(buf, v) \
727
0
  ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
728
729
0
  buf[0] = ':';
730
0
  TOHEX (buf + 1, count);
731
0
  TOHEX (buf + 3, (addr >> 8) & 0xff);
732
0
  TOHEX (buf + 5, addr & 0xff);
733
0
  TOHEX (buf + 7, type);
734
735
0
  chksum = count + addr + (addr >> 8) + type;
736
737
0
  for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
738
0
    {
739
0
      TOHEX (p, *data);
740
0
      chksum += *data;
741
0
    }
742
743
0
  TOHEX (p, (- chksum) & 0xff);
744
0
  p[2] = '\r';
745
0
  p[3] = '\n';
746
747
0
  total = 9 + count * 2 + 4;
748
0
  if (bfd_write (buf, total, abfd) != total)
749
0
    return false;
750
751
0
  return true;
752
0
}
753
754
/* Write out an Intel Hex file.  */
755
756
static bool
757
ihex_write_object_contents (bfd *abfd)
758
0
{
759
0
  bfd_vma segbase;
760
0
  bfd_vma extbase;
761
0
  struct ihex_data_list *l;
762
763
0
  segbase = 0;
764
0
  extbase = 0;
765
0
  for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
766
0
    {
767
0
      bfd_vma where;
768
0
      bfd_byte *p;
769
0
      bfd_size_type count;
770
771
0
      where = l->where;
772
773
0
#ifdef BFD64
774
      /* IHex only supports 32-bit addresses, and we want to check
775
   that 64-bit addresses are in range.  This isn't quite as
776
   obvious as it may seem, since some targets have 32-bit
777
   addresses that are sign extended to 64 bits.  So complain
778
   only if addresses overflow both unsigned and signed 32-bit
779
   integers.  */
780
0
      if (where > 0xffffffff
781
0
    && where + 0x80000000 > 0xffffffff)
782
0
  {
783
0
    _bfd_error_handler
784
      /* xgettext:c-format */
785
0
      (_("%pB 64-bit address %#" PRIx64
786
0
         " out of range for Intel Hex file"),
787
0
       abfd, (uint64_t) where);
788
0
    bfd_set_error (bfd_error_bad_value);
789
0
    return false;
790
0
  }
791
0
      where &= 0xffffffff;
792
0
#endif
793
794
0
      p = l->data;
795
0
      count = l->size;
796
797
0
      while (count > 0)
798
0
  {
799
0
    size_t now;
800
0
    unsigned int rec_addr;
801
802
0
    now = count;
803
0
    if (count > CHUNK)
804
0
      now = CHUNK;
805
806
0
    if (where < extbase
807
0
        || where - extbase < segbase
808
0
        || where - extbase - segbase > 0xffff)
809
0
      {
810
0
        bfd_byte addr[2];
811
812
        /* We need a new base address.  */
813
0
        if (extbase == 0 && where <= 0xfffff)
814
0
    {
815
0
      segbase = where & 0xf0000;
816
0
      addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
817
0
      addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
818
0
      if (! ihex_write_record (abfd, 2, 0, 2, addr))
819
0
        return false;
820
0
    }
821
0
        else
822
0
    {
823
      /* The extended address record and the extended
824
         linear address record are combined, at least by
825
         some readers.  We need an extended linear address
826
         record here, so if we've already written out an
827
         extended address record, zero it out to avoid
828
         confusion.  */
829
0
      if (segbase != 0)
830
0
        {
831
0
          addr[0] = 0;
832
0
          addr[1] = 0;
833
0
          if (! ihex_write_record (abfd, 2, 0, 2, addr))
834
0
      return false;
835
0
          segbase = 0;
836
0
        }
837
838
0
      extbase = where & 0xffff0000;
839
0
      if (where > extbase + 0xffff)
840
0
        {
841
0
          _bfd_error_handler
842
      /* xgettext:c-format */
843
0
      (_("%pB: address %#" PRIx64
844
0
         " out of range for Intel Hex file"),
845
0
       abfd, (uint64_t) where);
846
0
          bfd_set_error (bfd_error_bad_value);
847
0
          return false;
848
0
        }
849
0
      addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
850
0
      addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
851
0
      if (! ihex_write_record (abfd, 2, 0, 4, addr))
852
0
        return false;
853
0
    }
854
0
      }
855
856
0
    rec_addr = where - (extbase + segbase);
857
858
    /* Output records shouldn't cross 64K boundaries.  */
859
0
    if (rec_addr + now > 0xffff)
860
0
      now = 0x10000 - rec_addr;
861
862
0
    if (! ihex_write_record (abfd, now, rec_addr, 0, p))
863
0
      return false;
864
865
0
    where += now;
866
0
    p += now;
867
0
    count -= now;
868
0
  }
869
0
    }
870
871
0
  if (abfd->start_address != 0)
872
0
    {
873
0
      bfd_vma start;
874
0
      bfd_byte startbuf[4];
875
876
0
      start = abfd->start_address;
877
878
0
      if (start <= 0xfffff)
879
0
  {
880
0
    startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
881
0
    startbuf[1] = 0;
882
0
    startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
883
0
    startbuf[3] = (bfd_byte)start & 0xff;
884
0
    if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
885
0
      return false;
886
0
  }
887
0
      else
888
0
  {
889
0
    startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
890
0
    startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
891
0
    startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
892
0
    startbuf[3] = (bfd_byte)start & 0xff;
893
0
    if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
894
0
      return false;
895
0
  }
896
0
    }
897
898
0
  if (! ihex_write_record (abfd, 0, 0, 1, NULL))
899
0
    return false;
900
901
0
  return true;
902
0
}
903
904
/* Set the architecture for the output file.  The architecture is
905
   irrelevant, so we ignore errors about unknown architectures.  */
906
907
static bool
908
ihex_set_arch_mach (bfd *abfd,
909
        enum bfd_architecture arch,
910
        unsigned long mach)
911
0
{
912
0
  if (! bfd_default_set_arch_mach (abfd, arch, mach))
913
0
    {
914
0
      if (arch != bfd_arch_unknown)
915
0
  return false;
916
0
    }
917
0
  return true;
918
0
}
919
920
/* Get the size of the headers, for the linker.  */
921
922
static int
923
ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
924
         struct bfd_link_info *info ATTRIBUTE_UNUSED)
925
0
{
926
0
  return 0;
927
0
}
928
929
/* Some random definitions for the target vector.  */
930
931
#define ihex_close_and_cleanup        _bfd_generic_close_and_cleanup
932
#define ihex_bfd_free_cached_info     _bfd_generic_bfd_free_cached_info
933
#define ihex_new_section_hook       _bfd_generic_new_section_hook
934
#define ihex_get_section_contents_in_window   _bfd_generic_get_section_contents_in_window
935
#define ihex_get_symtab_upper_bound     _bfd_long_bfd_0
936
#define ihex_canonicalize_symtab      _bfd_nosymbols_canonicalize_symtab
937
#define ihex_make_empty_symbol        _bfd_generic_make_empty_symbol
938
#define ihex_print_symbol       _bfd_nosymbols_print_symbol
939
#define ihex_get_symbol_info        _bfd_nosymbols_get_symbol_info
940
#define ihex_get_symbol_version_string      _bfd_nosymbols_get_symbol_version_string
941
#define ihex_bfd_is_target_special_symbol   _bfd_bool_bfd_asymbol_false
942
#define ihex_bfd_is_local_label_name      _bfd_nosymbols_bfd_is_local_label_name
943
#define ihex_get_lineno         _bfd_nosymbols_get_lineno
944
#define ihex_find_nearest_line        _bfd_nosymbols_find_nearest_line
945
#define ihex_find_nearest_line_with_alt     _bfd_nosymbols_find_nearest_line_with_alt
946
#define ihex_find_line          _bfd_nosymbols_find_line
947
#define ihex_find_inliner_info        _bfd_nosymbols_find_inliner_info
948
#define ihex_bfd_make_debug_symbol      _bfd_nosymbols_bfd_make_debug_symbol
949
#define ihex_read_minisymbols       _bfd_nosymbols_read_minisymbols
950
#define ihex_minisymbol_to_symbol     _bfd_nosymbols_minisymbol_to_symbol
951
#define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
952
#define ihex_bfd_relax_section        bfd_generic_relax_section
953
#define ihex_bfd_gc_sections        bfd_generic_gc_sections
954
#define ihex_bfd_lookup_section_flags     bfd_generic_lookup_section_flags
955
#define ihex_bfd_merge_sections       bfd_generic_merge_sections
956
#define ihex_bfd_is_group_section     bfd_generic_is_group_section
957
#define ihex_bfd_group_name       bfd_generic_group_name
958
#define ihex_bfd_discard_group        bfd_generic_discard_group
959
#define ihex_section_already_linked     _bfd_generic_section_already_linked
960
#define ihex_bfd_define_common_symbol     bfd_generic_define_common_symbol
961
#define ihex_bfd_link_hide_symbol     _bfd_generic_link_hide_symbol
962
#define ihex_bfd_define_start_stop      bfd_generic_define_start_stop
963
#define ihex_bfd_link_hash_table_create     _bfd_generic_link_hash_table_create
964
#define ihex_bfd_link_add_symbols     _bfd_generic_link_add_symbols
965
#define ihex_bfd_link_just_syms       _bfd_generic_link_just_syms
966
#define ihex_bfd_copy_link_hash_symbol_type   _bfd_generic_copy_link_hash_symbol_type
967
#define ihex_bfd_final_link       _bfd_generic_final_link
968
#define ihex_bfd_link_split_section     _bfd_generic_link_split_section
969
#define ihex_bfd_link_check_relocs      _bfd_generic_link_check_relocs
970
971
/* The Intel Hex target vector.  */
972
973
const bfd_target ihex_vec =
974
{
975
  "ihex",     /* Name.  */
976
  bfd_target_ihex_flavour,
977
  BFD_ENDIAN_UNKNOWN,   /* Target byte order.  */
978
  BFD_ENDIAN_UNKNOWN,   /* Target headers byte order.  */
979
  0,        /* Object flags.  */
980
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),  /* Section flags.  */
981
  0,        /* Leading underscore.  */
982
  ' ',        /* AR_pad_char.  */
983
  16,       /* AR_max_namelen.  */
984
  0,        /* match priority.  */
985
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
986
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
987
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
988
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
989
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
990
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
991
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
992
993
  {
994
    _bfd_dummy_target,
995
    ihex_object_p,    /* bfd_check_format.  */
996
    _bfd_dummy_target,
997
    _bfd_dummy_target,
998
  },
999
  {
1000
    _bfd_bool_bfd_false_error,
1001
    ihex_mkobject,
1002
    _bfd_generic_mkarchive,
1003
    _bfd_bool_bfd_false_error,
1004
  },
1005
  {       /* bfd_write_contents.  */
1006
    _bfd_bool_bfd_false_error,
1007
    ihex_write_object_contents,
1008
    _bfd_write_archive_contents,
1009
    _bfd_bool_bfd_false_error,
1010
  },
1011
1012
  BFD_JUMP_TABLE_GENERIC (ihex),
1013
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1014
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1015
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1016
  BFD_JUMP_TABLE_SYMBOLS (ihex),
1017
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1018
  BFD_JUMP_TABLE_WRITE (ihex),
1019
  BFD_JUMP_TABLE_LINK (ihex),
1020
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1021
1022
  NULL,
1023
1024
  NULL
1025
};