Home | History | Annotate | Line # | Download | only in bfd
ihex.c revision 1.1.1.11
      1 /* BFD back-end for Intel Hex objects.
      2    Copyright (C) 1995-2025 Free Software Foundation, Inc.
      3    Written by Ian Lance Taylor of Cygnus Support <ian (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   bfd_byte b[9];
    490   unsigned int i;
    491   unsigned int type;
    492 
    493   ihex_init ();
    494 
    495   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    496     return NULL;
    497   if (bfd_read (b, 9, abfd) != 9)
    498     {
    499       if (bfd_get_error () == bfd_error_file_truncated)
    500 	bfd_set_error (bfd_error_wrong_format);
    501       return NULL;
    502     }
    503 
    504   if (b[0] != ':')
    505     {
    506       bfd_set_error (bfd_error_wrong_format);
    507       return NULL;
    508     }
    509 
    510   for (i = 1; i < 9; i++)
    511     {
    512       if (! ISHEX (b[i]))
    513 	{
    514 	  bfd_set_error (bfd_error_wrong_format);
    515 	  return NULL;
    516 	}
    517     }
    518 
    519   type = HEX2 (b + 7);
    520   if (type > 5)
    521     {
    522       bfd_set_error (bfd_error_wrong_format);
    523       return NULL;
    524     }
    525 
    526   /* OK, it looks like it really is an Intel Hex file.  */
    527   if (!ihex_mkobject (abfd))
    528     return NULL;
    529 
    530   if (!ihex_scan (abfd))
    531     {
    532       bfd_release (abfd, abfd->tdata.any);
    533       return NULL;
    534     }
    535 
    536   return _bfd_no_cleanup;
    537 }
    538 
    539 /* Read the contents of a section in an Intel Hex file.  */
    540 
    541 static bool
    542 ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
    543 {
    544   int c;
    545   bfd_byte *p;
    546   bfd_byte *buf = NULL;
    547   size_t bufsize;
    548   bool error;
    549 
    550   if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
    551     goto error_return;
    552 
    553   p = contents;
    554   bufsize = 0;
    555   error = false;
    556   while ((c = ihex_get_byte (abfd, &error)) != EOF)
    557     {
    558       unsigned char hdr[8];
    559       unsigned int len;
    560       unsigned int type;
    561       unsigned int i;
    562 
    563       if (c == '\r' || c == '\n')
    564 	continue;
    565 
    566       /* This is called after ihex_scan has succeeded, so we ought to
    567 	 know the exact format.  */
    568       BFD_ASSERT (c == ':');
    569 
    570       if (bfd_read (hdr, 8, abfd) != 8)
    571 	goto error_return;
    572 
    573       len = HEX2 (hdr);
    574       type = HEX2 (hdr + 6);
    575 
    576       /* We should only see type 0 records here.  */
    577       if (type != 0)
    578 	{
    579 	  _bfd_error_handler
    580 	    (_("%pB: internal error in ihex_read_section"), abfd);
    581 	  bfd_set_error (bfd_error_bad_value);
    582 	  goto error_return;
    583 	}
    584 
    585       if (len * 2 > bufsize)
    586 	{
    587 	  buf = bfd_realloc (buf, len * 2);
    588 	  if (buf == NULL)
    589 	    goto error_return;
    590 	  bufsize = len * 2;
    591 	}
    592 
    593       if (bfd_read (buf, len * 2, abfd) != len * 2)
    594 	goto error_return;
    595 
    596       for (i = 0; i < len; i++)
    597 	*p++ = HEX2 (buf + 2 * i);
    598       if ((bfd_size_type) (p - contents) >= section->size)
    599 	{
    600 	  /* We've read everything in the section.  */
    601 	  free (buf);
    602 	  return true;
    603 	}
    604 
    605       /* Skip the checksum.  */
    606       if (bfd_read (buf, 2, abfd) != 2)
    607 	goto error_return;
    608     }
    609 
    610   if ((bfd_size_type) (p - contents) < section->size)
    611     {
    612       _bfd_error_handler
    613 	(_("%pB: bad section length in ihex_read_section"), abfd);
    614       bfd_set_error (bfd_error_bad_value);
    615       goto error_return;
    616     }
    617 
    618   free (buf);
    619   return true;
    620 
    621  error_return:
    622   free (buf);
    623   return false;
    624 }
    625 
    626 /* Get the contents of a section in an Intel Hex file.  */
    627 
    628 static bool
    629 ihex_get_section_contents (bfd *abfd,
    630 			   asection *section,
    631 			   void * location,
    632 			   file_ptr offset,
    633 			   bfd_size_type count)
    634 {
    635   if (section->used_by_bfd == NULL)
    636     {
    637       section->used_by_bfd = bfd_alloc (abfd, section->size);
    638       if (section->used_by_bfd == NULL)
    639 	return false;
    640       if (! ihex_read_section (abfd, section,
    641 			       (bfd_byte *) section->used_by_bfd))
    642 	return false;
    643     }
    644 
    645   memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
    646 	  (size_t) count);
    647 
    648   return true;
    649 }
    650 
    651 /* Set the contents of a section in an Intel Hex file.  */
    652 
    653 static bool
    654 ihex_set_section_contents (bfd *abfd,
    655 			   asection *section,
    656 			   const void * location,
    657 			   file_ptr offset,
    658 			   bfd_size_type count)
    659 {
    660   struct ihex_data_list *n;
    661   bfd_byte *data;
    662   struct ihex_data_struct *tdata;
    663 
    664   if (count == 0
    665       || (section->flags & SEC_ALLOC) == 0
    666       || (section->flags & SEC_LOAD) == 0)
    667     return true;
    668 
    669   n = (struct ihex_data_list *) bfd_alloc (abfd, sizeof (* n));
    670   if (n == NULL)
    671     return false;
    672 
    673   data = (bfd_byte *) bfd_alloc (abfd, count);
    674   if (data == NULL)
    675     return false;
    676   memcpy (data, location, (size_t) count);
    677 
    678   n->data = data;
    679   n->where = section->lma + offset;
    680   n->size = count;
    681 
    682   /* Sort the records by address.  Optimize for the common case of
    683      adding a record to the end of the list.  */
    684   tdata = abfd->tdata.ihex_data;
    685   if (tdata->tail != NULL
    686       && n->where >= tdata->tail->where)
    687     {
    688       tdata->tail->next = n;
    689       n->next = NULL;
    690       tdata->tail = n;
    691     }
    692   else
    693     {
    694       struct ihex_data_list **pp;
    695 
    696       for (pp = &tdata->head;
    697 	   *pp != NULL && (*pp)->where < n->where;
    698 	   pp = &(*pp)->next)
    699 	;
    700       n->next = *pp;
    701       *pp = n;
    702       if (n->next == NULL)
    703 	tdata->tail = n;
    704     }
    705 
    706   return true;
    707 }
    708 
    709 /* Write a record out to an Intel Hex file.  */
    710 
    711 static bool
    712 ihex_write_record (bfd *abfd,
    713 		   size_t count,
    714 		   unsigned int addr,
    715 		   unsigned int type,
    716 		   bfd_byte *data)
    717 {
    718   static const char digs[] = "0123456789ABCDEF";
    719   char buf[9 + CHUNK * 2 + 4];
    720   char *p;
    721   unsigned int chksum;
    722   unsigned int i;
    723   size_t total;
    724 
    725 #define TOHEX(buf, v) \
    726   ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
    727 
    728   buf[0] = ':';
    729   TOHEX (buf + 1, count);
    730   TOHEX (buf + 3, (addr >> 8) & 0xff);
    731   TOHEX (buf + 5, addr & 0xff);
    732   TOHEX (buf + 7, type);
    733 
    734   chksum = count + addr + (addr >> 8) + type;
    735 
    736   for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
    737     {
    738       TOHEX (p, *data);
    739       chksum += *data;
    740     }
    741 
    742   TOHEX (p, (- chksum) & 0xff);
    743   p[2] = '\r';
    744   p[3] = '\n';
    745 
    746   total = 9 + count * 2 + 4;
    747   if (bfd_write (buf, total, abfd) != total)
    748     return false;
    749 
    750   return true;
    751 }
    752 
    753 /* Write out an Intel Hex file.  */
    754 
    755 static bool
    756 ihex_write_object_contents (bfd *abfd)
    757 {
    758   bfd_vma segbase;
    759   bfd_vma extbase;
    760   struct ihex_data_list *l;
    761 
    762   segbase = 0;
    763   extbase = 0;
    764   for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
    765     {
    766       bfd_vma where;
    767       bfd_byte *p;
    768       bfd_size_type count;
    769 
    770       where = l->where;
    771 
    772 #ifdef BFD64
    773       /* IHex only supports 32-bit addresses, and we want to check
    774 	 that 64-bit addresses are in range.  This isn't quite as
    775 	 obvious as it may seem, since some targets have 32-bit
    776 	 addresses that are sign extended to 64 bits.  So complain
    777 	 only if addresses overflow both unsigned and signed 32-bit
    778 	 integers.  */
    779       if (where > 0xffffffff
    780 	  && where + 0x80000000 > 0xffffffff)
    781 	{
    782 	  _bfd_error_handler
    783 	    /* xgettext:c-format */
    784 	    (_("%pB 64-bit address %#" PRIx64
    785 	       " out of range for Intel Hex file"),
    786 	     abfd, (uint64_t) where);
    787 	  bfd_set_error (bfd_error_bad_value);
    788 	  return false;
    789 	}
    790       where &= 0xffffffff;
    791 #endif
    792 
    793       p = l->data;
    794       count = l->size;
    795 
    796       while (count > 0)
    797 	{
    798 	  size_t now;
    799 	  unsigned int rec_addr;
    800 
    801 	  now = count;
    802 	  if (count > CHUNK)
    803 	    now = CHUNK;
    804 
    805 	  if (where < extbase
    806 	      || where - extbase < segbase
    807 	      || where - extbase - segbase > 0xffff)
    808 	    {
    809 	      bfd_byte addr[2];
    810 
    811 	      /* We need a new base address.  */
    812 	      if (extbase == 0 && where <= 0xfffff)
    813 		{
    814 		  segbase = where & 0xf0000;
    815 		  addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
    816 		  addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
    817 		  if (! ihex_write_record (abfd, 2, 0, 2, addr))
    818 		    return false;
    819 		}
    820 	      else
    821 		{
    822 		  /* The extended address record and the extended
    823 		     linear address record are combined, at least by
    824 		     some readers.  We need an extended linear address
    825 		     record here, so if we've already written out an
    826 		     extended address record, zero it out to avoid
    827 		     confusion.  */
    828 		  if (segbase != 0)
    829 		    {
    830 		      addr[0] = 0;
    831 		      addr[1] = 0;
    832 		      if (! ihex_write_record (abfd, 2, 0, 2, addr))
    833 			return false;
    834 		      segbase = 0;
    835 		    }
    836 
    837 		  extbase = where & 0xffff0000;
    838 		  if (where > extbase + 0xffff)
    839 		    {
    840 		      _bfd_error_handler
    841 			/* xgettext:c-format */
    842 			(_("%pB: address %#" PRIx64
    843 			   " out of range for Intel Hex file"),
    844 			 abfd, (uint64_t) where);
    845 		      bfd_set_error (bfd_error_bad_value);
    846 		      return false;
    847 		    }
    848 		  addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
    849 		  addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
    850 		  if (! ihex_write_record (abfd, 2, 0, 4, addr))
    851 		    return false;
    852 		}
    853 	    }
    854 
    855 	  rec_addr = where - (extbase + segbase);
    856 
    857 	  /* Output records shouldn't cross 64K boundaries.  */
    858 	  if (rec_addr + now > 0xffff)
    859 	    now = 0x10000 - rec_addr;
    860 
    861 	  if (! ihex_write_record (abfd, now, rec_addr, 0, p))
    862 	    return false;
    863 
    864 	  where += now;
    865 	  p += now;
    866 	  count -= now;
    867 	}
    868     }
    869 
    870   if (abfd->start_address != 0)
    871     {
    872       bfd_vma start;
    873       bfd_byte startbuf[4];
    874 
    875       start = abfd->start_address;
    876 
    877       if (start <= 0xfffff)
    878 	{
    879 	  startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
    880 	  startbuf[1] = 0;
    881 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
    882 	  startbuf[3] = (bfd_byte)start & 0xff;
    883 	  if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
    884 	    return false;
    885 	}
    886       else
    887 	{
    888 	  startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
    889 	  startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
    890 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
    891 	  startbuf[3] = (bfd_byte)start & 0xff;
    892 	  if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
    893 	    return false;
    894 	}
    895     }
    896 
    897   if (! ihex_write_record (abfd, 0, 0, 1, NULL))
    898     return false;
    899 
    900   return true;
    901 }
    902 
    903 /* Set the architecture for the output file.  The architecture is
    904    irrelevant, so we ignore errors about unknown architectures.  */
    905 
    906 static bool
    907 ihex_set_arch_mach (bfd *abfd,
    908 		    enum bfd_architecture arch,
    909 		    unsigned long mach)
    910 {
    911   if (! bfd_default_set_arch_mach (abfd, arch, mach))
    912     {
    913       if (arch != bfd_arch_unknown)
    914 	return false;
    915     }
    916   return true;
    917 }
    918 
    919 /* Some random definitions for the target vector.  */
    920 
    921 #define	ihex_close_and_cleanup			  _bfd_generic_close_and_cleanup
    922 #define ihex_bfd_free_cached_info		  _bfd_generic_bfd_free_cached_info
    923 #define ihex_new_section_hook			  _bfd_generic_new_section_hook
    924 #define ihex_sizeof_headers			  _bfd_nolink_sizeof_headers
    925 #define ihex_bfd_get_relocated_section_contents	  bfd_generic_get_relocated_section_contents
    926 #define ihex_bfd_relax_section			  bfd_generic_relax_section
    927 #define ihex_bfd_gc_sections			  bfd_generic_gc_sections
    928 #define ihex_bfd_lookup_section_flags		  bfd_generic_lookup_section_flags
    929 #define ihex_bfd_merge_sections			  bfd_generic_merge_sections
    930 #define ihex_bfd_is_group_section		  bfd_generic_is_group_section
    931 #define ihex_bfd_group_name			  bfd_generic_group_name
    932 #define ihex_bfd_discard_group			  bfd_generic_discard_group
    933 #define ihex_section_already_linked		  _bfd_generic_section_already_linked
    934 #define ihex_bfd_define_common_symbol		  bfd_generic_define_common_symbol
    935 #define ihex_bfd_link_hide_symbol		  _bfd_generic_link_hide_symbol
    936 #define ihex_bfd_define_start_stop		  bfd_generic_define_start_stop
    937 #define ihex_bfd_link_hash_table_create		  _bfd_generic_link_hash_table_create
    938 #define ihex_bfd_link_add_symbols		  _bfd_generic_link_add_symbols
    939 #define ihex_bfd_link_just_syms			  _bfd_generic_link_just_syms
    940 #define ihex_bfd_copy_link_hash_symbol_type	  _bfd_generic_copy_link_hash_symbol_type
    941 #define ihex_bfd_final_link			  _bfd_generic_final_link
    942 #define ihex_bfd_link_split_section		  _bfd_generic_link_split_section
    943 #define ihex_bfd_link_check_relocs		  _bfd_generic_link_check_relocs
    944 
    945 /* The Intel Hex target vector.  */
    946 
    947 const bfd_target ihex_vec =
    948 {
    949   "ihex",			/* Name.  */
    950   bfd_target_ihex_flavour,
    951   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
    952   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
    953   0,				/* Object flags.  */
    954   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
    955   0,				/* Leading underscore.  */
    956   ' ',				/* AR_pad_char.  */
    957   16,				/* AR_max_namelen.  */
    958   0,				/* match priority.  */
    959   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
    960   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
    961   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
    962   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
    963   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
    964   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
    965   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers. */
    966 
    967   {
    968     _bfd_dummy_target,
    969     ihex_object_p,		/* bfd_check_format.  */
    970     _bfd_dummy_target,
    971     _bfd_dummy_target,
    972   },
    973   {
    974     _bfd_bool_bfd_false_error,
    975     ihex_mkobject,
    976     _bfd_bool_bfd_false_error,
    977     _bfd_bool_bfd_false_error,
    978   },
    979   {				/* bfd_write_contents.  */
    980     _bfd_bool_bfd_false_error,
    981     ihex_write_object_contents,
    982     _bfd_bool_bfd_false_error,
    983     _bfd_bool_bfd_false_error,
    984   },
    985 
    986   BFD_JUMP_TABLE_GENERIC (ihex),
    987   BFD_JUMP_TABLE_COPY (_bfd_generic),
    988   BFD_JUMP_TABLE_CORE (_bfd_nocore),
    989   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
    990   BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
    991   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
    992   BFD_JUMP_TABLE_WRITE (ihex),
    993   BFD_JUMP_TABLE_LINK (ihex),
    994   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
    995 
    996   NULL,
    997 
    998   NULL
    999 };
   1000