Coverage Report

Created: 2025-06-24 06:45

/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-2025 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
74.9k
#define NIBBLE(x)    (hex_value (x))
135
42.3k
#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
136
6.14k
#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
137
115k
#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
3.41M
{
163
3.41M
  static bool inited;
164
165
3.41M
  if (! inited)
166
11
    {
167
11
      inited = true;
168
11
      hex_init ();
169
11
    }
170
3.41M
}
171
172
/* Create an ihex object.  */
173
174
static bool
175
ihex_mkobject (bfd *abfd)
176
5.39k
{
177
5.39k
  struct ihex_data_struct *tdata;
178
179
5.39k
  tdata = (struct ihex_data_struct *) bfd_alloc (abfd, sizeof (* tdata));
180
5.39k
  if (tdata == NULL)
181
0
    return false;
182
183
5.39k
  abfd->tdata.ihex_data = tdata;
184
5.39k
  tdata->head = NULL;
185
5.39k
  tdata->tail = NULL;
186
5.39k
  return true;
187
5.39k
}
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
14.0k
{
195
14.0k
  bfd_byte c;
196
197
14.0k
  if (bfd_read (&c, 1, abfd) != 1)
198
1.99k
    {
199
1.99k
      if (bfd_get_error () != bfd_error_file_truncated)
200
311
  *errorptr = true;
201
1.99k
      return EOF;
202
1.99k
    }
203
204
12.0k
  return c & 0xff;
205
14.0k
}
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
1.84k
{
212
1.84k
  if (c == EOF)
213
0
    {
214
0
      if (! error)
215
0
  bfd_set_error (bfd_error_file_truncated);
216
0
    }
217
1.84k
  else
218
1.84k
    {
219
1.84k
      char buf[10];
220
221
1.84k
      if (! ISPRINT (c))
222
975
  sprintf (buf, "\\%03o", (unsigned int) c & 0xff);
223
871
      else
224
871
  {
225
871
    buf[0] = c;
226
871
    buf[1] = '\0';
227
871
  }
228
1.84k
      _bfd_error_handler
229
  /* xgettext:c-format */
230
1.84k
  (_("%pB:%d: unexpected character `%s' in Intel Hex file"),
231
1.84k
   abfd, lineno, buf);
232
1.84k
      bfd_set_error (bfd_error_bad_value);
233
1.84k
    }
234
1.84k
}
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
5.39k
{
242
5.39k
  bfd_vma segbase;
243
5.39k
  bfd_vma extbase;
244
5.39k
  asection *sec;
245
5.39k
  unsigned int lineno;
246
5.39k
  bool error;
247
5.39k
  bfd_byte *buf = NULL;
248
5.39k
  size_t bufsize;
249
5.39k
  int c;
250
251
5.39k
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
252
0
    goto error_return;
253
254
5.39k
  abfd->start_address = 0;
255
256
5.39k
  segbase = 0;
257
5.39k
  extbase = 0;
258
5.39k
  sec = NULL;
259
5.39k
  lineno = 1;
260
5.39k
  error = false;
261
5.39k
  bufsize = 0;
262
263
14.0k
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
264
12.0k
    {
265
12.0k
      if (c == '\r')
266
1.82k
  continue;
267
10.2k
      else if (c == '\n')
268
3.02k
  {
269
3.02k
    ++lineno;
270
3.02k
    continue;
271
3.02k
  }
272
7.24k
      else if (c != ':')
273
776
  {
274
776
    ihex_bad_byte (abfd, lineno, c, error);
275
776
    goto error_return;
276
776
  }
277
6.46k
      else
278
6.46k
  {
279
6.46k
    file_ptr pos;
280
6.46k
    unsigned char hdr[8];
281
6.46k
    unsigned int i;
282
6.46k
    unsigned int len;
283
6.46k
    bfd_vma addr;
284
6.46k
    unsigned int type;
285
6.46k
    unsigned int chars;
286
6.46k
    unsigned int chksum;
287
288
    /* This is a data record.  */
289
6.46k
    pos = bfd_tell (abfd) - 1;
290
291
    /* Read the header bytes.  */
292
6.46k
    if (bfd_read (hdr, 8, abfd) != 8)
293
224
      goto error_return;
294
295
54.5k
    for (i = 0; i < 8; i++)
296
48.5k
      {
297
48.5k
        if (! ISHEX (hdr[i]))
298
227
    {
299
227
      ihex_bad_byte (abfd, lineno, hdr[i], error);
300
227
      goto error_return;
301
227
    }
302
48.5k
      }
303
304
6.01k
    len = HEX2 (hdr);
305
6.01k
    addr = HEX4 (hdr + 2);
306
6.01k
    type = HEX2 (hdr + 6);
307
308
    /* Read the data bytes.  */
309
6.01k
    chars = len * 2 + 2;
310
6.01k
    if (chars >= bufsize)
311
5.90k
      {
312
5.90k
        buf = bfd_realloc (buf, chars);
313
5.90k
        if (buf == NULL)
314
0
    goto error_return;
315
5.90k
        bufsize = chars;
316
5.90k
      }
317
318
6.01k
    if (bfd_read (buf, chars, abfd) != chars)
319
330
      goto error_return;
320
321
20.6k
    for (i = 0; i < chars; i++)
322
15.7k
      {
323
15.7k
        if (! ISHEX (buf[i]))
324
843
    {
325
843
      ihex_bad_byte (abfd, lineno, buf[i], error);
326
843
      goto error_return;
327
843
    }
328
15.7k
      }
329
330
    /* Check the checksum.  */
331
4.84k
    chksum = len + addr + (addr >> 8) + type;
332
6.96k
    for (i = 0; i < len; i++)
333
2.12k
      chksum += HEX2 (buf + 2 * i);
334
4.84k
    if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
335
347
      {
336
347
        _bfd_error_handler
337
    /* xgettext:c-format */
338
347
    (_("%pB:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
339
347
     abfd, lineno,
340
347
     (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
341
347
        bfd_set_error (bfd_error_bad_value);
342
347
        goto error_return;
343
347
      }
344
345
4.49k
    switch (type)
346
4.49k
      {
347
3.70k
      case 0:
348
        /* This is a data record.  */
349
3.70k
        if (sec != NULL
350
3.70k
      && 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
3.70k
        else if (len > 0)
357
78
    {
358
78
      char secbuf[20];
359
78
      char *secname;
360
78
      size_t amt;
361
78
      flagword flags;
362
363
78
      sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
364
78
      amt = strlen (secbuf) + 1;
365
78
      secname = (char *) bfd_alloc (abfd, amt);
366
78
      if (secname == NULL)
367
0
        goto error_return;
368
78
      strcpy (secname, secbuf);
369
78
      flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
370
78
      sec = bfd_make_section_with_flags (abfd, secname, flags);
371
78
      if (sec == NULL)
372
0
        goto error_return;
373
78
      sec->vma = extbase + segbase + addr;
374
78
      sec->lma = extbase + segbase + addr;
375
78
      sec->size = len;
376
78
      sec->filepos = pos;
377
78
    }
378
3.70k
        break;
379
380
3.70k
      case 1:
381
        /* An end record.  */
382
341
        if (abfd->start_address == 0)
383
341
    abfd->start_address = addr;
384
341
        free (buf);
385
341
        return true;
386
387
215
      case 2:
388
        /* An extended address record.  */
389
215
        if (len != 2)
390
105
    {
391
105
      _bfd_error_handler
392
        /* xgettext:c-format */
393
105
        (_("%pB:%u: bad extended address record length in Intel Hex file"),
394
105
         abfd, lineno);
395
105
      bfd_set_error (bfd_error_bad_value);
396
105
      goto error_return;
397
105
    }
398
399
110
        segbase = HEX4 (buf) << 4;
400
401
110
        sec = NULL;
402
403
110
        break;
404
405
2
      case 3:
406
        /* An extended start address record.  */
407
2
        if (len != 4)
408
2
    {
409
2
      _bfd_error_handler
410
        /* xgettext:c-format */
411
2
        (_("%pB:%u: bad extended start address length in Intel Hex file"),
412
2
         abfd, lineno);
413
2
      bfd_set_error (bfd_error_bad_value);
414
2
      goto error_return;
415
2
    }
416
417
0
        abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
418
419
0
        sec = NULL;
420
421
0
        break;
422
423
116
      case 4:
424
        /* An extended linear address record.  */
425
116
        if (len != 2)
426
104
    {
427
104
      _bfd_error_handler
428
        /* xgettext:c-format */
429
104
        (_("%pB:%u: bad extended linear address record length in Intel Hex file"),
430
104
         abfd, lineno);
431
104
      bfd_set_error (bfd_error_bad_value);
432
104
      goto error_return;
433
104
    }
434
435
12
        extbase = HEX4 (buf) << 16;
436
437
12
        sec = NULL;
438
439
12
        break;
440
441
13
      case 5:
442
        /* An extended linear start address record.  */
443
13
        if (len != 2 && len != 4)
444
3
    {
445
3
      _bfd_error_handler
446
        /* xgettext:c-format */
447
3
        (_("%pB:%u: bad extended linear start address length in Intel Hex file"),
448
3
         abfd, lineno);
449
3
      bfd_set_error (bfd_error_bad_value);
450
3
      goto error_return;
451
3
    }
452
453
10
        if (len == 2)
454
10
    abfd->start_address += HEX4 (buf) << 16;
455
0
        else
456
0
    abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
457
458
10
        sec = NULL;
459
460
10
        break;
461
462
105
      default:
463
105
        _bfd_error_handler
464
    /* xgettext:c-format */
465
105
    (_("%pB:%u: unrecognized ihex type %u in Intel Hex file"),
466
105
     abfd, lineno, type);
467
105
        bfd_set_error (bfd_error_bad_value);
468
105
        goto error_return;
469
4.49k
      }
470
4.49k
  }
471
12.0k
    }
472
473
1.99k
  if (error)
474
311
    goto error_return;
475
476
1.67k
  free (buf);
477
1.67k
  return true;
478
479
3.37k
 error_return:
480
3.37k
  free (buf);
481
3.37k
  return false;
482
1.99k
}
483
484
/* Try to recognize an Intel Hex file.  */
485
486
static bfd_cleanup
487
ihex_object_p (bfd *abfd)
488
3.41M
{
489
3.41M
  bfd_byte b[9];
490
3.41M
  unsigned int i;
491
3.41M
  unsigned int type;
492
493
3.41M
  ihex_init ();
494
495
3.41M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
496
0
    return NULL;
497
3.41M
  if (bfd_read (b, 9, abfd) != 9)
498
14.4k
    {
499
14.4k
      if (bfd_get_error () == bfd_error_file_truncated)
500
9.43k
  bfd_set_error (bfd_error_wrong_format);
501
14.4k
      return NULL;
502
14.4k
    }
503
504
3.39M
  if (b[0] != ':')
505
3.39M
    {
506
3.39M
      bfd_set_error (bfd_error_wrong_format);
507
3.39M
      return NULL;
508
3.39M
    }
509
510
57.1k
  for (i = 1; i < 9; i++)
511
51.3k
    {
512
51.3k
      if (! ISHEX (b[i]))
513
1.04k
  {
514
1.04k
    bfd_set_error (bfd_error_wrong_format);
515
1.04k
    return NULL;
516
1.04k
  }
517
51.3k
    }
518
519
5.81k
  type = HEX2 (b + 7);
520
5.81k
  if (type > 5)
521
418
    {
522
418
      bfd_set_error (bfd_error_wrong_format);
523
418
      return NULL;
524
418
    }
525
526
  /* OK, it looks like it really is an Intel Hex file.  */
527
5.39k
  if (!ihex_mkobject (abfd))
528
0
    return NULL;
529
530
5.39k
  if (!ihex_scan (abfd))
531
3.37k
    {
532
3.37k
      bfd_release (abfd, abfd->tdata.any);
533
3.37k
      return NULL;
534
3.37k
    }
535
536
2.02k
  return _bfd_no_cleanup;
537
5.39k
}
538
539
/* Read the contents of a section in an Intel Hex file.  */
540
541
static bool
542
ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
543
1
{
544
1
  int c;
545
1
  bfd_byte *p;
546
1
  bfd_byte *buf = NULL;
547
1
  size_t bufsize;
548
1
  bool error;
549
550
1
  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
551
0
    goto error_return;
552
553
1
  p = contents;
554
1
  bufsize = 0;
555
1
  error = false;
556
1
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
557
1
    {
558
1
      unsigned char hdr[8];
559
1
      unsigned int len;
560
1
      unsigned int type;
561
1
      unsigned int i;
562
563
1
      if (c == '\r' || c == '\n')
564
0
  continue;
565
566
      /* This is called after ihex_scan has succeeded, so we ought to
567
   know the exact format.  */
568
1
      BFD_ASSERT (c == ':');
569
570
1
      if (bfd_read (hdr, 8, abfd) != 8)
571
0
  goto error_return;
572
573
1
      len = HEX2 (hdr);
574
1
      type = HEX2 (hdr + 6);
575
576
      /* We should only see type 0 records here.  */
577
1
      if (type != 0)
578
0
  {
579
0
    _bfd_error_handler
580
0
      (_("%pB: internal error in ihex_read_section"), abfd);
581
0
    bfd_set_error (bfd_error_bad_value);
582
0
    goto error_return;
583
0
  }
584
585
1
      if (len * 2 > bufsize)
586
1
  {
587
1
    buf = bfd_realloc (buf, len * 2);
588
1
    if (buf == NULL)
589
0
      goto error_return;
590
1
    bufsize = len * 2;
591
1
  }
592
593
1
      if (bfd_read (buf, len * 2, abfd) != len * 2)
594
0
  goto error_return;
595
596
3
      for (i = 0; i < len; i++)
597
2
  *p++ = HEX2 (buf + 2 * i);
598
1
      if ((bfd_size_type) (p - contents) >= section->size)
599
1
  {
600
    /* We've read everything in the section.  */
601
1
    free (buf);
602
1
    return true;
603
1
  }
604
605
      /* Skip the checksum.  */
606
0
      if (bfd_read (buf, 2, abfd) != 2)
607
0
  goto error_return;
608
0
    }
609
610
0
  if ((bfd_size_type) (p - contents) < section->size)
611
0
    {
612
0
      _bfd_error_handler
613
0
  (_("%pB: bad section length in ihex_read_section"), abfd);
614
0
      bfd_set_error (bfd_error_bad_value);
615
0
      goto error_return;
616
0
    }
617
618
0
  free (buf);
619
0
  return true;
620
621
0
 error_return:
622
0
  free (buf);
623
0
  return false;
624
0
}
625
626
/* Get the contents of a section in an Intel Hex file.  */
627
628
static bool
629
ihex_get_section_contents (bfd *abfd,
630
         asection *section,
631
         void * location,
632
         file_ptr offset,
633
         bfd_size_type count)
634
1
{
635
1
  if (section->used_by_bfd == NULL)
636
1
    {
637
1
      section->used_by_bfd = bfd_alloc (abfd, section->size);
638
1
      if (section->used_by_bfd == NULL)
639
0
  return false;
640
1
      if (! ihex_read_section (abfd, section,
641
1
             (bfd_byte *) section->used_by_bfd))
642
0
  return false;
643
1
    }
644
645
1
  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
646
1
    (size_t) count);
647
648
1
  return true;
649
1
}
650
651
/* Set the contents of a section in an Intel Hex file.  */
652
653
static bool
654
ihex_set_section_contents (bfd *abfd,
655
         asection *section,
656
         const void * location,
657
         file_ptr offset,
658
         bfd_size_type count)
659
0
{
660
0
  struct ihex_data_list *n;
661
0
  bfd_byte *data;
662
0
  struct ihex_data_struct *tdata;
663
664
0
  if (count == 0
665
0
      || (section->flags & SEC_ALLOC) == 0
666
0
      || (section->flags & SEC_LOAD) == 0)
667
0
    return true;
668
669
0
  n = (struct ihex_data_list *) bfd_alloc (abfd, sizeof (* n));
670
0
  if (n == NULL)
671
0
    return false;
672
673
0
  data = (bfd_byte *) bfd_alloc (abfd, count);
674
0
  if (data == NULL)
675
0
    return false;
676
0
  memcpy (data, location, (size_t) count);
677
678
0
  n->data = data;
679
0
  n->where = section->lma + offset;
680
0
  n->size = count;
681
682
  /* Sort the records by address.  Optimize for the common case of
683
     adding a record to the end of the list.  */
684
0
  tdata = abfd->tdata.ihex_data;
685
0
  if (tdata->tail != NULL
686
0
      && n->where >= tdata->tail->where)
687
0
    {
688
0
      tdata->tail->next = n;
689
0
      n->next = NULL;
690
0
      tdata->tail = n;
691
0
    }
692
0
  else
693
0
    {
694
0
      struct ihex_data_list **pp;
695
696
0
      for (pp = &tdata->head;
697
0
     *pp != NULL && (*pp)->where < n->where;
698
0
     pp = &(*pp)->next)
699
0
  ;
700
0
      n->next = *pp;
701
0
      *pp = n;
702
0
      if (n->next == NULL)
703
0
  tdata->tail = n;
704
0
    }
705
706
0
  return true;
707
0
}
708
709
/* Write a record out to an Intel Hex file.  */
710
711
static bool
712
ihex_write_record (bfd *abfd,
713
       size_t count,
714
       unsigned int addr,
715
       unsigned int type,
716
       bfd_byte *data)
717
0
{
718
0
  static const char digs[] = "0123456789ABCDEF";
719
0
  char buf[9 + CHUNK * 2 + 4];
720
0
  char *p;
721
0
  unsigned int chksum;
722
0
  unsigned int i;
723
0
  size_t total;
724
725
0
#define TOHEX(buf, v) \
726
0
  ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
727
728
0
  buf[0] = ':';
729
0
  TOHEX (buf + 1, count);
730
0
  TOHEX (buf + 3, (addr >> 8) & 0xff);
731
0
  TOHEX (buf + 5, addr & 0xff);
732
0
  TOHEX (buf + 7, type);
733
734
0
  chksum = count + addr + (addr >> 8) + type;
735
736
0
  for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
737
0
    {
738
0
      TOHEX (p, *data);
739
0
      chksum += *data;
740
0
    }
741
742
0
  TOHEX (p, (- chksum) & 0xff);
743
0
  p[2] = '\r';
744
0
  p[3] = '\n';
745
746
0
  total = 9 + count * 2 + 4;
747
0
  if (bfd_write (buf, total, abfd) != total)
748
0
    return false;
749
750
0
  return true;
751
0
}
752
753
/* Write out an Intel Hex file.  */
754
755
static bool
756
ihex_write_object_contents (bfd *abfd)
757
0
{
758
0
  bfd_vma segbase;
759
0
  bfd_vma extbase;
760
0
  struct ihex_data_list *l;
761
762
0
  segbase = 0;
763
0
  extbase = 0;
764
0
  for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
765
0
    {
766
0
      bfd_vma where;
767
0
      bfd_byte *p;
768
0
      bfd_size_type count;
769
770
0
      where = l->where;
771
772
0
#ifdef BFD64
773
      /* IHex only supports 32-bit addresses, and we want to check
774
   that 64-bit addresses are in range.  This isn't quite as
775
   obvious as it may seem, since some targets have 32-bit
776
   addresses that are sign extended to 64 bits.  So complain
777
   only if addresses overflow both unsigned and signed 32-bit
778
   integers.  */
779
0
      if (where > 0xffffffff
780
0
    && where + 0x80000000 > 0xffffffff)
781
0
  {
782
0
    _bfd_error_handler
783
      /* xgettext:c-format */
784
0
      (_("%pB 64-bit address %#" PRIx64
785
0
         " out of range for Intel Hex file"),
786
0
       abfd, (uint64_t) where);
787
0
    bfd_set_error (bfd_error_bad_value);
788
0
    return false;
789
0
  }
790
0
      where &= 0xffffffff;
791
0
#endif
792
793
0
      p = l->data;
794
0
      count = l->size;
795
796
0
      while (count > 0)
797
0
  {
798
0
    size_t now;
799
0
    unsigned int rec_addr;
800
801
0
    now = count;
802
0
    if (count > CHUNK)
803
0
      now = CHUNK;
804
805
0
    if (where < extbase
806
0
        || where - extbase < segbase
807
0
        || where - extbase - segbase > 0xffff)
808
0
      {
809
0
        bfd_byte addr[2];
810
811
        /* We need a new base address.  */
812
0
        if (extbase == 0 && where <= 0xfffff)
813
0
    {
814
0
      segbase = where & 0xf0000;
815
0
      addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
816
0
      addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
817
0
      if (! ihex_write_record (abfd, 2, 0, 2, addr))
818
0
        return false;
819
0
    }
820
0
        else
821
0
    {
822
      /* The extended address record and the extended
823
         linear address record are combined, at least by
824
         some readers.  We need an extended linear address
825
         record here, so if we've already written out an
826
         extended address record, zero it out to avoid
827
         confusion.  */
828
0
      if (segbase != 0)
829
0
        {
830
0
          addr[0] = 0;
831
0
          addr[1] = 0;
832
0
          if (! ihex_write_record (abfd, 2, 0, 2, addr))
833
0
      return false;
834
0
          segbase = 0;
835
0
        }
836
837
0
      extbase = where & 0xffff0000;
838
0
      if (where > extbase + 0xffff)
839
0
        {
840
0
          _bfd_error_handler
841
      /* xgettext:c-format */
842
0
      (_("%pB: address %#" PRIx64
843
0
         " out of range for Intel Hex file"),
844
0
       abfd, (uint64_t) where);
845
0
          bfd_set_error (bfd_error_bad_value);
846
0
          return false;
847
0
        }
848
0
      addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
849
0
      addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
850
0
      if (! ihex_write_record (abfd, 2, 0, 4, addr))
851
0
        return false;
852
0
    }
853
0
      }
854
855
0
    rec_addr = where - (extbase + segbase);
856
857
    /* Output records shouldn't cross 64K boundaries.  */
858
0
    if (rec_addr + now > 0xffff)
859
0
      now = 0x10000 - rec_addr;
860
861
0
    if (! ihex_write_record (abfd, now, rec_addr, 0, p))
862
0
      return false;
863
864
0
    where += now;
865
0
    p += now;
866
0
    count -= now;
867
0
  }
868
0
    }
869
870
0
  if (abfd->start_address != 0)
871
0
    {
872
0
      bfd_vma start;
873
0
      bfd_byte startbuf[4];
874
875
0
      start = abfd->start_address;
876
877
0
      if (start <= 0xfffff)
878
0
  {
879
0
    startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
880
0
    startbuf[1] = 0;
881
0
    startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
882
0
    startbuf[3] = (bfd_byte)start & 0xff;
883
0
    if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
884
0
      return false;
885
0
  }
886
0
      else
887
0
  {
888
0
    startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
889
0
    startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
890
0
    startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
891
0
    startbuf[3] = (bfd_byte)start & 0xff;
892
0
    if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
893
0
      return false;
894
0
  }
895
0
    }
896
897
0
  if (! ihex_write_record (abfd, 0, 0, 1, NULL))
898
0
    return false;
899
900
0
  return true;
901
0
}
902
903
/* Set the architecture for the output file.  The architecture is
904
   irrelevant, so we ignore errors about unknown architectures.  */
905
906
static bool
907
ihex_set_arch_mach (bfd *abfd,
908
        enum bfd_architecture arch,
909
        unsigned long mach)
910
0
{
911
0
  if (! bfd_default_set_arch_mach (abfd, arch, mach))
912
0
    {
913
0
      if (arch != bfd_arch_unknown)
914
0
  return false;
915
0
    }
916
0
  return true;
917
0
}
918
919
/* Some random definitions for the target vector.  */
920
921
#define ihex_close_and_cleanup        _bfd_generic_close_and_cleanup
922
#define ihex_bfd_free_cached_info     _bfd_generic_bfd_free_cached_info
923
#define ihex_new_section_hook       _bfd_generic_new_section_hook
924
#define ihex_sizeof_headers       _bfd_nolink_sizeof_headers
925
#define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
926
#define ihex_bfd_relax_section        bfd_generic_relax_section
927
#define ihex_bfd_gc_sections        bfd_generic_gc_sections
928
#define ihex_bfd_lookup_section_flags     bfd_generic_lookup_section_flags
929
#define ihex_bfd_merge_sections       bfd_generic_merge_sections
930
#define ihex_bfd_is_group_section     bfd_generic_is_group_section
931
#define ihex_bfd_group_name       bfd_generic_group_name
932
#define ihex_bfd_discard_group        bfd_generic_discard_group
933
#define ihex_section_already_linked     _bfd_generic_section_already_linked
934
#define ihex_bfd_define_common_symbol     bfd_generic_define_common_symbol
935
#define ihex_bfd_link_hide_symbol     _bfd_generic_link_hide_symbol
936
#define ihex_bfd_define_start_stop      bfd_generic_define_start_stop
937
#define ihex_bfd_link_hash_table_create     _bfd_generic_link_hash_table_create
938
#define ihex_bfd_link_add_symbols     _bfd_generic_link_add_symbols
939
#define ihex_bfd_link_just_syms       _bfd_generic_link_just_syms
940
#define ihex_bfd_copy_link_hash_symbol_type   _bfd_generic_copy_link_hash_symbol_type
941
#define ihex_bfd_final_link       _bfd_generic_final_link
942
#define ihex_bfd_link_split_section     _bfd_generic_link_split_section
943
#define ihex_bfd_link_check_relocs      _bfd_generic_link_check_relocs
944
945
/* The Intel Hex target vector.  */
946
947
const bfd_target ihex_vec =
948
{
949
  "ihex",     /* Name.  */
950
  bfd_target_ihex_flavour,
951
  BFD_ENDIAN_UNKNOWN,   /* Target byte order.  */
952
  BFD_ENDIAN_UNKNOWN,   /* Target headers byte order.  */
953
  0,        /* Object flags.  */
954
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),  /* Section flags.  */
955
  0,        /* Leading underscore.  */
956
  ' ',        /* AR_pad_char.  */
957
  16,       /* AR_max_namelen.  */
958
  0,        /* match priority.  */
959
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
960
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
961
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
962
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
963
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
964
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
965
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
966
967
  {
968
    _bfd_dummy_target,
969
    ihex_object_p,    /* bfd_check_format.  */
970
    _bfd_dummy_target,
971
    _bfd_dummy_target,
972
  },
973
  {
974
    _bfd_bool_bfd_false_error,
975
    ihex_mkobject,
976
    _bfd_bool_bfd_false_error,
977
    _bfd_bool_bfd_false_error,
978
  },
979
  {       /* bfd_write_contents.  */
980
    _bfd_bool_bfd_false_error,
981
    ihex_write_object_contents,
982
    _bfd_bool_bfd_false_error,
983
    _bfd_bool_bfd_false_error,
984
  },
985
986
  BFD_JUMP_TABLE_GENERIC (ihex),
987
  BFD_JUMP_TABLE_COPY (_bfd_generic),
988
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
989
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
990
  BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
991
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
992
  BFD_JUMP_TABLE_WRITE (ihex),
993
  BFD_JUMP_TABLE_LINK (ihex),
994
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
995
996
  NULL,
997
998
  NULL
999
};