xref: /NextBSD/contrib/binutils/bfd/ihex.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /* BFD back-end for Intel Hex objects.
2    Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3    2006, 2007 Free Software Foundation, Inc.
4    Written by Ian Lance Taylor of Cygnus Support <ian@cygnus.com>.
5 
6    This file is part of BFD, the Binary File Descriptor library.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21 
22 /* This is what Intel Hex files look like:
23 
24 1. INTEL FORMATS
25 
26 A. Intel 1
27 
28    16-bit address-field format, for files 64k bytes in length or less.
29 
30    DATA RECORD
31    Byte 1	Header = colon(:)
32    2..3		The number of data bytes in hex notation
33    4..5		High byte of the record load address
34    6..7		Low byte of the record load address
35    8..9		Record type, must be "00"
36    10..x	Data bytes in hex notation:
37 	x = (number of bytes - 1) * 2 + 11
38    x+1..x+2	Checksum in hex notation
39    x+3..x+4	Carriage return, line feed
40 
41    END RECORD
42    Byte 1	Header = colon (:)
43    2..3		The byte count, must be "00"
44    4..7		Transfer-address (usually "0000")
45 		the jump-to address, execution start address
46    8..9		Record type, must be "01"
47    10..11	Checksum, in hex notation
48    12..13	Carriage return, line feed
49 
50 B. INTEL 2
51 
52    MCS-86 format, using a 20-bit address for files larger than 64K bytes.
53 
54    DATA RECORD
55    Byte 1	Header = colon (:)
56    2..3		The byte count of this record, hex notation
57    4..5		High byte of the record load address
58    6..7		Low byte of the record load address
59    8..9		Record type, must be "00"
60    10..x	The data bytes in hex notation:
61 	x = (number of data bytes - 1) * 2 + 11
62    x+1..x+2	Checksum in hex notation
63    x+3..x+4	Carriage return, line feed
64 
65    EXTENDED ADDRESS RECORD
66    Byte 1	Header = colon(:)
67    2..3		The byte count, must be "02"
68    4..7		Load address, must be "0000"
69    8..9		Record type, must be "02"
70    10..11	High byte of the offset address
71    12..13	Low byte of the offset address
72    14..15	Checksum in hex notation
73    16..17	Carriage return, line feed
74 
75    The checksums are the two's complement of the 8-bit sum
76    without carry of the byte count, offset address, and the
77    record type.
78 
79    START ADDRESS RECORD
80    Byte 1	Header = colon (:)
81    2..3		The byte count, must be "04"
82    4..7		Load address, must be "0000"
83    8..9		Record type, must be "03"
84    10..13	8086 CS value
85    14..17	8086 IP value
86    18..19	Checksum in hex notation
87    20..21	Carriage return, line feed
88 
89 Another document reports these additional types:
90 
91    EXTENDED LINEAR ADDRESS RECORD
92    Byte 1	Header = colon (:)
93    2..3		The byte count, must be "02"
94    4..7		Load address, must be "0000"
95    8..9		Record type, must be "04"
96    10..13	Upper 16 bits of address of subsequent records
97    14..15	Checksum in hex notation
98    16..17	Carriage return, line feed
99 
100    START LINEAR ADDRESS RECORD
101    Byte 1	Header = colon (:)
102    2..3		The byte count, must be "02"
103    4..7		Load address, must be "0000"
104    8..9		Record type, must be "05"
105    10..13	Upper 16 bits of start address
106    14..15	Checksum in hex notation
107    16..17	Carriage return, line feed
108 
109 The MRI compiler uses this, which is a repeat of type 5:
110 
111   EXTENDED START RECORD
112    Byte 1	Header = colon (:)
113    2..3		The byte count, must be "04"
114    4..7		Load address, must be "0000"
115    8..9		Record type, must be "05"
116    10..13	Upper 16 bits of start address
117    14..17	Lower 16 bits of start address
118    18..19	Checksum in hex notation
119    20..21	Carriage return, line feed.  */
120 
121 #include "sysdep.h"
122 #include "bfd.h"
123 #include "libbfd.h"
124 #include "libiberty.h"
125 #include "safe-ctype.h"
126 
127 /* The number of bytes we put on one line during output.  */
128 
129 #define CHUNK 16
130 
131 /* Macros for converting between hex and binary.  */
132 
133 #define NIBBLE(x)    (hex_value (x))
134 #define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
135 #define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
136 #define ISHEX(x)     (hex_p (x))
137 
138 /* When we write out an ihex value, the values can not be output as
139    they are seen.  Instead, we hold them in memory in this structure.  */
140 
141 struct ihex_data_list
142 {
143   struct ihex_data_list *next;
144   bfd_byte *data;
145   bfd_vma where;
146   bfd_size_type size;
147 };
148 
149 /* The ihex tdata information.  */
150 
151 struct ihex_data_struct
152 {
153   struct ihex_data_list *head;
154   struct ihex_data_list *tail;
155 };
156 
157 /* Initialize by filling in the hex conversion array.  */
158 
159 static void
ihex_init(void)160 ihex_init (void)
161 {
162   static bfd_boolean inited;
163 
164   if (! inited)
165     {
166       inited = TRUE;
167       hex_init ();
168     }
169 }
170 
171 /* Create an ihex object.  */
172 
173 static bfd_boolean
ihex_mkobject(bfd * abfd)174 ihex_mkobject (bfd *abfd)
175 {
176   struct ihex_data_struct *tdata;
177 
178   tdata = bfd_alloc (abfd, sizeof (* tdata));
179   if (tdata == NULL)
180     return FALSE;
181 
182   abfd->tdata.ihex_data = tdata;
183   tdata->head = NULL;
184   tdata->tail = NULL;
185   return TRUE;
186 }
187 
188 /* Read a byte from a BFD.  Set *ERRORPTR if an error occurred.
189    Return EOF on error or end of file.  */
190 
191 static INLINE int
ihex_get_byte(bfd * abfd,bfd_boolean * errorptr)192 ihex_get_byte (bfd *abfd, bfd_boolean *errorptr)
193 {
194   bfd_byte c;
195 
196   if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
197     {
198       if (bfd_get_error () != bfd_error_file_truncated)
199 	*errorptr = TRUE;
200       return EOF;
201     }
202 
203   return (int) (c & 0xff);
204 }
205 
206 /* Report a problem in an Intel Hex file.  */
207 
208 static void
ihex_bad_byte(bfd * abfd,unsigned int lineno,int c,bfd_boolean error)209 ihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bfd_boolean error)
210 {
211   if (c == EOF)
212     {
213       if (! error)
214 	bfd_set_error (bfd_error_file_truncated);
215     }
216   else
217     {
218       char buf[10];
219 
220       if (! ISPRINT (c))
221 	sprintf (buf, "\\%03o", (unsigned int) c);
222       else
223 	{
224 	  buf[0] = c;
225 	  buf[1] = '\0';
226 	}
227       (*_bfd_error_handler)
228 	(_("%B:%d: unexpected character `%s' in Intel Hex file"),
229 	 abfd, lineno, buf);
230       bfd_set_error (bfd_error_bad_value);
231     }
232 }
233 
234 /* Read an Intel hex file and turn it into sections.  We create a new
235    section for each contiguous set of bytes.  */
236 
237 static bfd_boolean
ihex_scan(bfd * abfd)238 ihex_scan (bfd *abfd)
239 {
240   bfd_vma segbase;
241   bfd_vma extbase;
242   asection *sec;
243   unsigned int lineno;
244   bfd_boolean error;
245   bfd_byte *buf = NULL;
246   size_t bufsize;
247   int c;
248 
249   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
250     goto error_return;
251 
252   abfd->start_address = 0;
253 
254   segbase = 0;
255   extbase = 0;
256   sec = NULL;
257   lineno = 1;
258   error = FALSE;
259   bufsize = 0;
260 
261   while ((c = ihex_get_byte (abfd, &error)) != EOF)
262     {
263       if (c == '\r')
264 	continue;
265       else if (c == '\n')
266 	{
267 	  ++lineno;
268 	  continue;
269 	}
270       else if (c != ':')
271 	{
272 	  ihex_bad_byte (abfd, lineno, c, error);
273 	  goto error_return;
274 	}
275       else
276 	{
277 	  file_ptr pos;
278 	  char hdr[8];
279 	  unsigned int i;
280 	  unsigned int len;
281 	  bfd_vma addr;
282 	  unsigned int type;
283 	  unsigned int chars;
284 	  unsigned int chksum;
285 
286 	  /* This is a data record.  */
287 	  pos = bfd_tell (abfd) - 1;
288 
289 	  /* Read the header bytes.  */
290 	  if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
291 	    goto error_return;
292 
293 	  for (i = 0; i < 8; i++)
294 	    {
295 	      if (! ISHEX (hdr[i]))
296 		{
297 		  ihex_bad_byte (abfd, lineno, hdr[i], error);
298 		  goto error_return;
299 		}
300 	    }
301 
302 	  len = HEX2 (hdr);
303 	  addr = HEX4 (hdr + 2);
304 	  type = HEX2 (hdr + 6);
305 
306 	  /* Read the data bytes.  */
307 	  chars = len * 2 + 2;
308 	  if (chars >= bufsize)
309 	    {
310 	      buf = bfd_realloc (buf, (bfd_size_type) chars);
311 	      if (buf == NULL)
312 		goto error_return;
313 	      bufsize = chars;
314 	    }
315 
316 	  if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars)
317 	    goto error_return;
318 
319 	  for (i = 0; i < chars; i++)
320 	    {
321 	      if (! ISHEX (buf[i]))
322 		{
323 		  ihex_bad_byte (abfd, lineno, hdr[i], error);
324 		  goto error_return;
325 		}
326 	    }
327 
328 	  /* Check the checksum.  */
329 	  chksum = len + addr + (addr >> 8) + type;
330 	  for (i = 0; i < len; i++)
331 	    chksum += HEX2 (buf + 2 * i);
332 	  if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
333 	    {
334 	      (*_bfd_error_handler)
335 		(_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
336 		 abfd, lineno,
337 		 (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
338 	      bfd_set_error (bfd_error_bad_value);
339 	      goto error_return;
340 	    }
341 
342 	  switch (type)
343 	    {
344 	    case 0:
345 	      /* This is a data record.  */
346 	      if (sec != NULL
347 		  && sec->vma + sec->size == extbase + segbase + addr)
348 		{
349 		  /* This data goes at the end of the section we are
350                      currently building.  */
351 		  sec->size += len;
352 		}
353 	      else if (len > 0)
354 		{
355 		  char secbuf[20];
356 		  char *secname;
357 		  bfd_size_type amt;
358 		  flagword flags;
359 
360 		  sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
361 		  amt = strlen (secbuf) + 1;
362 		  secname = bfd_alloc (abfd, amt);
363 		  if (secname == NULL)
364 		    goto error_return;
365 		  strcpy (secname, secbuf);
366 		  flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
367 		  sec = bfd_make_section_with_flags (abfd, secname, flags);
368 		  if (sec == NULL)
369 		    goto error_return;
370 		  sec->vma = extbase + segbase + addr;
371 		  sec->lma = extbase + segbase + addr;
372 		  sec->size = len;
373 		  sec->filepos = pos;
374 		}
375 	      break;
376 
377 	    case 1:
378 	      /* An end record.  */
379 	      if (abfd->start_address == 0)
380 		abfd->start_address = addr;
381 	      if (buf != NULL)
382 		free (buf);
383 	      return TRUE;
384 
385 	    case 2:
386 	      /* An extended address record.  */
387 	      if (len != 2)
388 		{
389 		  (*_bfd_error_handler)
390 		    (_("%B:%u: bad extended address record length in Intel Hex file"),
391 		     abfd, lineno);
392 		  bfd_set_error (bfd_error_bad_value);
393 		  goto error_return;
394 		}
395 
396 	      segbase = HEX4 (buf) << 4;
397 
398 	      sec = NULL;
399 
400 	      break;
401 
402 	    case 3:
403 	      /* An extended start address record.  */
404 	      if (len != 4)
405 		{
406 		  (*_bfd_error_handler)
407 		    (_("%B:%u: bad extended start address length in Intel Hex file"),
408 		     abfd, lineno);
409 		  bfd_set_error (bfd_error_bad_value);
410 		  goto error_return;
411 		}
412 
413 	      abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
414 
415 	      sec = NULL;
416 
417 	      break;
418 
419 	    case 4:
420 	      /* An extended linear address record.  */
421 	      if (len != 2)
422 		{
423 		  (*_bfd_error_handler)
424 		    (_("%B:%u: bad extended linear address record length in Intel Hex file"),
425 		     abfd, lineno);
426 		  bfd_set_error (bfd_error_bad_value);
427 		  goto error_return;
428 		}
429 
430 	      extbase = HEX4 (buf) << 16;
431 
432 	      sec = NULL;
433 
434 	      break;
435 
436 	    case 5:
437 	      /* An extended linear start address record.  */
438 	      if (len != 2 && len != 4)
439 		{
440 		  (*_bfd_error_handler)
441 		    (_("%B:%u: bad extended linear start address length in Intel Hex file"),
442 		     abfd, lineno);
443 		  bfd_set_error (bfd_error_bad_value);
444 		  goto error_return;
445 		}
446 
447 	      if (len == 2)
448 		abfd->start_address += HEX4 (buf) << 16;
449 	      else
450 		abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
451 
452 	      sec = NULL;
453 
454 	      break;
455 
456 	    default:
457 	      (*_bfd_error_handler)
458 		(_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
459 		 abfd, lineno, type);
460 	      bfd_set_error (bfd_error_bad_value);
461 	      goto error_return;
462 	    }
463 	}
464     }
465 
466   if (error)
467     goto error_return;
468 
469   if (buf != NULL)
470     free (buf);
471 
472   return TRUE;
473 
474  error_return:
475   if (buf != NULL)
476     free (buf);
477   return FALSE;
478 }
479 
480 /* Try to recognize an Intel Hex file.  */
481 
482 static const bfd_target *
ihex_object_p(bfd * abfd)483 ihex_object_p (bfd *abfd)
484 {
485   void * tdata_save;
486   bfd_byte b[9];
487   unsigned int i;
488   unsigned int type;
489 
490   ihex_init ();
491 
492   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
493     return NULL;
494   if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9)
495     {
496       if (bfd_get_error () == bfd_error_file_truncated)
497 	bfd_set_error (bfd_error_wrong_format);
498       return NULL;
499     }
500 
501   if (b[0] != ':')
502     {
503       bfd_set_error (bfd_error_wrong_format);
504       return NULL;
505     }
506 
507   for (i = 1; i < 9; i++)
508     {
509       if (! ISHEX (b[i]))
510 	{
511 	  bfd_set_error (bfd_error_wrong_format);
512 	  return NULL;
513 	}
514     }
515 
516   type = HEX2 (b + 7);
517   if (type > 5)
518     {
519       bfd_set_error (bfd_error_wrong_format);
520       return NULL;
521     }
522 
523   /* OK, it looks like it really is an Intel Hex file.  */
524   tdata_save = abfd->tdata.any;
525   if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
526     {
527       if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
528 	bfd_release (abfd, abfd->tdata.any);
529       abfd->tdata.any = tdata_save;
530       return NULL;
531     }
532 
533   return abfd->xvec;
534 }
535 
536 /* Read the contents of a section in an Intel Hex file.  */
537 
538 static bfd_boolean
ihex_read_section(bfd * abfd,asection * section,bfd_byte * contents)539 ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
540 {
541   int c;
542   bfd_byte *p;
543   bfd_byte *buf = NULL;
544   size_t bufsize;
545   bfd_boolean error;
546 
547   if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
548     goto error_return;
549 
550   p = contents;
551   bufsize = 0;
552   error = FALSE;
553   while ((c = ihex_get_byte (abfd, &error)) != EOF)
554     {
555       char hdr[8];
556       unsigned int len;
557       unsigned int type;
558       unsigned int i;
559 
560       if (c == '\r' || c == '\n')
561 	continue;
562 
563       /* This is called after ihex_scan has succeeded, so we ought to
564          know the exact format.  */
565       BFD_ASSERT (c == ':');
566 
567       if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
568 	goto error_return;
569 
570       len = HEX2 (hdr);
571       type = HEX2 (hdr + 6);
572 
573       /* We should only see type 0 records here.  */
574       if (type != 0)
575 	{
576 	  (*_bfd_error_handler)
577 	    (_("%B: internal error in ihex_read_section"), abfd);
578 	  bfd_set_error (bfd_error_bad_value);
579 	  goto error_return;
580 	}
581 
582       if (len * 2 > bufsize)
583 	{
584 	  buf = bfd_realloc (buf, (bfd_size_type) len * 2);
585 	  if (buf == NULL)
586 	    goto error_return;
587 	  bufsize = len * 2;
588 	}
589 
590       if (bfd_bread (buf, (bfd_size_type) len * 2, abfd) != len * 2)
591 	goto error_return;
592 
593       for (i = 0; i < len; i++)
594 	*p++ = HEX2 (buf + 2 * i);
595       if ((bfd_size_type) (p - contents) >= section->size)
596 	{
597 	  /* We've read everything in the section.  */
598 	  if (buf != NULL)
599 	    free (buf);
600 	  return TRUE;
601 	}
602 
603       /* Skip the checksum.  */
604       if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2)
605 	goto error_return;
606     }
607 
608   if ((bfd_size_type) (p - contents) < section->size)
609     {
610       (*_bfd_error_handler)
611 	(_("%B: bad section length in ihex_read_section"), abfd);
612       bfd_set_error (bfd_error_bad_value);
613       goto error_return;
614     }
615 
616   if (buf != NULL)
617     free (buf);
618 
619   return TRUE;
620 
621  error_return:
622   if (buf != NULL)
623     free (buf);
624   return FALSE;
625 }
626 
627 /* Get the contents of a section in an Intel Hex file.  */
628 
629 static bfd_boolean
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, 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 bfd_boolean
ihex_set_section_contents(bfd * abfd,asection * section,const void * location,file_ptr offset,bfd_size_type count)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 = bfd_alloc (abfd, sizeof (* n));
670   if (n == NULL)
671     return FALSE;
672 
673   data = 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 bfd_boolean
ihex_write_record(bfd * abfd,size_t count,unsigned int addr,unsigned int type,bfd_byte * data)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_bwrite (buf, (bfd_size_type) total, abfd) != total)
748     return FALSE;
749 
750   return TRUE;
751 }
752 
753 /* Write out an Intel Hex file.  */
754 
755 static bfd_boolean
ihex_write_object_contents(bfd * abfd)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       p = l->data;
772       count = l->size;
773 
774       while (count > 0)
775 	{
776 	  size_t now;
777 	  unsigned int rec_addr;
778 
779 	  now = count;
780 	  if (count > CHUNK)
781 	    now = CHUNK;
782 
783 	  if (where > segbase + extbase + 0xffff)
784 	    {
785 	      bfd_byte addr[2];
786 
787 	      /* We need a new base address.  */
788 	      if (where <= 0xfffff)
789 		{
790 		  /* The addresses should be sorted.  */
791 		  BFD_ASSERT (extbase == 0);
792 
793 		  segbase = where & 0xf0000;
794 		  addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
795 		  addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
796 		  if (! ihex_write_record (abfd, 2, 0, 2, addr))
797 		    return FALSE;
798 		}
799 	      else
800 		{
801 		  /* The extended address record and the extended
802                      linear address record are combined, at least by
803                      some readers.  We need an extended linear address
804                      record here, so if we've already written out an
805                      extended address record, zero it out to avoid
806                      confusion.  */
807 		  if (segbase != 0)
808 		    {
809 		      addr[0] = 0;
810 		      addr[1] = 0;
811 		      if (! ihex_write_record (abfd, 2, 0, 2, addr))
812 			return FALSE;
813 		      segbase = 0;
814 		    }
815 
816 		  extbase = where & 0xffff0000;
817 		  if (where > extbase + 0xffff)
818 		    {
819 		      char buf[20];
820 
821 		      sprintf_vma (buf, where);
822 		      (*_bfd_error_handler)
823 			(_("%s: address 0x%s out of range for Intel Hex file"),
824 			 bfd_get_filename (abfd), buf);
825 		      bfd_set_error (bfd_error_bad_value);
826 		      return FALSE;
827 		    }
828 		  addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
829 		  addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
830 		  if (! ihex_write_record (abfd, 2, 0, 4, addr))
831 		    return FALSE;
832 		}
833 	    }
834 
835 	  rec_addr = where - (extbase + segbase);
836 
837           /* Output records shouldn't cross 64K boundaries.  */
838           if (rec_addr + now > 0xffff)
839             now = 0x10000 - rec_addr;
840 
841 	  if (! ihex_write_record (abfd, now, rec_addr, 0, p))
842 	    return FALSE;
843 
844 	  where += now;
845 	  p += now;
846 	  count -= now;
847 	}
848     }
849 
850   if (abfd->start_address != 0)
851     {
852       bfd_vma start;
853       bfd_byte startbuf[4];
854 
855       start = abfd->start_address;
856 
857       if (start <= 0xfffff)
858 	{
859 	  startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
860 	  startbuf[1] = 0;
861 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
862 	  startbuf[3] = (bfd_byte)start & 0xff;
863 	  if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
864 	    return FALSE;
865 	}
866       else
867 	{
868 	  startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
869 	  startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
870 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
871 	  startbuf[3] = (bfd_byte)start & 0xff;
872 	  if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
873 	    return FALSE;
874 	}
875     }
876 
877   if (! ihex_write_record (abfd, 0, 0, 1, NULL))
878     return FALSE;
879 
880   return TRUE;
881 }
882 
883 /* Set the architecture for the output file.  The architecture is
884    irrelevant, so we ignore errors about unknown architectures.  */
885 
886 static bfd_boolean
ihex_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long mach)887 ihex_set_arch_mach (bfd *abfd,
888 		    enum bfd_architecture arch,
889 		    unsigned long mach)
890 {
891   if (! bfd_default_set_arch_mach (abfd, arch, mach))
892     {
893       if (arch != bfd_arch_unknown)
894 	return FALSE;
895     }
896   return TRUE;
897 }
898 
899 /* Get the size of the headers, for the linker.  */
900 
901 static int
ihex_sizeof_headers(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info ATTRIBUTE_UNUSED)902 ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
903 		     struct bfd_link_info *info ATTRIBUTE_UNUSED)
904 {
905   return 0;
906 }
907 
908 /* Some random definitions for the target vector.  */
909 
910 #define	ihex_close_and_cleanup                    _bfd_generic_close_and_cleanup
911 #define ihex_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
912 #define ihex_new_section_hook                     _bfd_generic_new_section_hook
913 #define ihex_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
914 #define ihex_get_symtab_upper_bound               bfd_0l
915 #define ihex_canonicalize_symtab                  ((long (*) (bfd *, asymbol **)) bfd_0l)
916 #define ihex_make_empty_symbol                    _bfd_generic_make_empty_symbol
917 #define ihex_print_symbol                         _bfd_nosymbols_print_symbol
918 #define ihex_get_symbol_info                      _bfd_nosymbols_get_symbol_info
919 #define ihex_bfd_is_target_special_symbol         ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
920 #define ihex_bfd_is_local_label_name              _bfd_nosymbols_bfd_is_local_label_name
921 #define ihex_get_lineno                           _bfd_nosymbols_get_lineno
922 #define ihex_find_nearest_line                    _bfd_nosymbols_find_nearest_line
923 #define ihex_find_inliner_info                    _bfd_nosymbols_find_inliner_info
924 #define ihex_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
925 #define ihex_read_minisymbols                     _bfd_nosymbols_read_minisymbols
926 #define ihex_minisymbol_to_symbol                 _bfd_nosymbols_minisymbol_to_symbol
927 #define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
928 #define ihex_bfd_relax_section                    bfd_generic_relax_section
929 #define ihex_bfd_gc_sections                      bfd_generic_gc_sections
930 #define ihex_bfd_merge_sections                   bfd_generic_merge_sections
931 #define ihex_bfd_is_group_section                 bfd_generic_is_group_section
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_link_hash_table_create           _bfd_generic_link_hash_table_create
935 #define ihex_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
936 #define ihex_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
937 #define ihex_bfd_link_just_syms                   _bfd_generic_link_just_syms
938 #define ihex_bfd_final_link                       _bfd_generic_final_link
939 #define ihex_bfd_link_split_section               _bfd_generic_link_split_section
940 
941 /* The Intel Hex target vector.  */
942 
943 const bfd_target ihex_vec =
944 {
945   "ihex",			/* Name.  */
946   bfd_target_ihex_flavour,
947   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
948   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
949   0,				/* Object flags.  */
950   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
951   0,				/* Leading underscore.  */
952   ' ',				/* AR_pad_char.  */
953   16,				/* AR_max_namelen.  */
954   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
955   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
956   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
957   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
958   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
959   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers. */
960 
961   {
962     _bfd_dummy_target,
963     ihex_object_p,		/* bfd_check_format.  */
964     _bfd_dummy_target,
965     _bfd_dummy_target,
966   },
967   {
968     bfd_false,
969     ihex_mkobject,
970     _bfd_generic_mkarchive,
971     bfd_false,
972   },
973   {				/* bfd_write_contents.  */
974     bfd_false,
975     ihex_write_object_contents,
976     _bfd_write_archive_contents,
977     bfd_false,
978   },
979 
980   BFD_JUMP_TABLE_GENERIC (ihex),
981   BFD_JUMP_TABLE_COPY (_bfd_generic),
982   BFD_JUMP_TABLE_CORE (_bfd_nocore),
983   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
984   BFD_JUMP_TABLE_SYMBOLS (ihex),
985   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
986   BFD_JUMP_TABLE_WRITE (ihex),
987   BFD_JUMP_TABLE_LINK (ihex),
988   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
989 
990   NULL,
991 
992   NULL
993 };
994