xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/ihex.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* BFD back-end for Intel Hex objects.
2    Copyright (C) 1995-2022 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_bread (&c, (bfd_size_type) 1, abfd) != 1)
198     {
199       if (bfd_get_error () != bfd_error_file_truncated)
200 	*errorptr = true;
201       return EOF;
202     }
203 
204   return (int) (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, (file_ptr) 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_bread (hdr, (bfd_size_type) 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_byte *) bfd_realloc (buf, (bfd_size_type) chars);
313 	      if (buf == NULL)
314 		goto error_return;
315 	      bufsize = chars;
316 	    }
317 
318 	  if (bfd_bread (buf, (bfd_size_type) 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, (file_ptr) 0, SEEK_SET) != 0)
497     return NULL;
498   if (bfd_bread (b, (bfd_size_type) 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_bread (hdr, (bfd_size_type) 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_byte *) bfd_realloc (buf, (bfd_size_type) len * 2);
589 	  if (buf == NULL)
590 	    goto error_return;
591 	  bufsize = len * 2;
592 	}
593 
594       if (bfd_bread (buf, (bfd_size_type) 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_bread (buf, (bfd_size_type) 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_bwrite (buf, (bfd_size_type) 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_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_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