Home | History | Annotate | Line # | Download | only in bfd
ihex.c revision 1.1.1.7
      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 (at) 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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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_nearest_line_with_alt		  _bfd_nosymbols_find_nearest_line_with_alt
    946 #define ihex_find_line				  _bfd_nosymbols_find_line
    947 #define ihex_find_inliner_info			  _bfd_nosymbols_find_inliner_info
    948 #define ihex_bfd_make_debug_symbol		  _bfd_nosymbols_bfd_make_debug_symbol
    949 #define ihex_read_minisymbols			  _bfd_nosymbols_read_minisymbols
    950 #define ihex_minisymbol_to_symbol		  _bfd_nosymbols_minisymbol_to_symbol
    951 #define ihex_bfd_get_relocated_section_contents	  bfd_generic_get_relocated_section_contents
    952 #define ihex_bfd_relax_section			  bfd_generic_relax_section
    953 #define ihex_bfd_gc_sections			  bfd_generic_gc_sections
    954 #define ihex_bfd_lookup_section_flags		  bfd_generic_lookup_section_flags
    955 #define ihex_bfd_merge_sections			  bfd_generic_merge_sections
    956 #define ihex_bfd_is_group_section		  bfd_generic_is_group_section
    957 #define ihex_bfd_group_name			  bfd_generic_group_name
    958 #define ihex_bfd_discard_group			  bfd_generic_discard_group
    959 #define ihex_section_already_linked		  _bfd_generic_section_already_linked
    960 #define ihex_bfd_define_common_symbol		  bfd_generic_define_common_symbol
    961 #define ihex_bfd_link_hide_symbol		  _bfd_generic_link_hide_symbol
    962 #define ihex_bfd_define_start_stop		  bfd_generic_define_start_stop
    963 #define ihex_bfd_link_hash_table_create		  _bfd_generic_link_hash_table_create
    964 #define ihex_bfd_link_add_symbols		  _bfd_generic_link_add_symbols
    965 #define ihex_bfd_link_just_syms			  _bfd_generic_link_just_syms
    966 #define ihex_bfd_copy_link_hash_symbol_type	  _bfd_generic_copy_link_hash_symbol_type
    967 #define ihex_bfd_final_link			  _bfd_generic_final_link
    968 #define ihex_bfd_link_split_section		  _bfd_generic_link_split_section
    969 #define ihex_bfd_link_check_relocs		  _bfd_generic_link_check_relocs
    970 
    971 /* The Intel Hex target vector.  */
    972 
    973 const bfd_target ihex_vec =
    974 {
    975   "ihex",			/* Name.  */
    976   bfd_target_ihex_flavour,
    977   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
    978   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
    979   0,				/* Object flags.  */
    980   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
    981   0,				/* Leading underscore.  */
    982   ' ',				/* AR_pad_char.  */
    983   16,				/* AR_max_namelen.  */
    984   0,				/* match priority.  */
    985   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
    986   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
    987   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
    988   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
    989   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
    990   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
    991   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers. */
    992 
    993   {
    994     _bfd_dummy_target,
    995     ihex_object_p,		/* bfd_check_format.  */
    996     _bfd_dummy_target,
    997     _bfd_dummy_target,
    998   },
    999   {
   1000     _bfd_bool_bfd_false_error,
   1001     ihex_mkobject,
   1002     _bfd_generic_mkarchive,
   1003     _bfd_bool_bfd_false_error,
   1004   },
   1005   {				/* bfd_write_contents.  */
   1006     _bfd_bool_bfd_false_error,
   1007     ihex_write_object_contents,
   1008     _bfd_write_archive_contents,
   1009     _bfd_bool_bfd_false_error,
   1010   },
   1011 
   1012   BFD_JUMP_TABLE_GENERIC (ihex),
   1013   BFD_JUMP_TABLE_COPY (_bfd_generic),
   1014   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   1015   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   1016   BFD_JUMP_TABLE_SYMBOLS (ihex),
   1017   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
   1018   BFD_JUMP_TABLE_WRITE (ihex),
   1019   BFD_JUMP_TABLE_LINK (ihex),
   1020   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
   1021 
   1022   NULL,
   1023 
   1024   NULL
   1025 };
   1026