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