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