xref: /openbsd/gnu/usr.bin/binutils-2.17/bfd/ihex.c (revision 3d8817e4)
1 /* BFD back-end for Intel Hex objects.
2    Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    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 "bfd.h"
122 #include "sysdep.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 
359 		  sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
360 		  amt = strlen (secbuf) + 1;
361 		  secname = bfd_alloc (abfd, amt);
362 		  if (secname == NULL)
363 		    goto error_return;
364 		  strcpy (secname, secbuf);
365 		  sec = bfd_make_section (abfd, secname);
366 		  if (sec == NULL)
367 		    goto error_return;
368 		  sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
369 		  sec->vma = extbase + segbase + addr;
370 		  sec->lma = extbase + segbase + addr;
371 		  sec->size = len;
372 		  sec->filepos = pos;
373 		}
374 	      break;
375 
376 	    case 1:
377 	      /* An end record.  */
378 	      if (abfd->start_address == 0)
379 		abfd->start_address = addr;
380 	      if (buf != NULL)
381 		free (buf);
382 	      return TRUE;
383 
384 	    case 2:
385 	      /* An extended address record.  */
386 	      if (len != 2)
387 		{
388 		  (*_bfd_error_handler)
389 		    (_("%B:%u: bad extended address record length in Intel Hex file"),
390 		     abfd, lineno);
391 		  bfd_set_error (bfd_error_bad_value);
392 		  goto error_return;
393 		}
394 
395 	      segbase = HEX4 (buf) << 4;
396 
397 	      sec = NULL;
398 
399 	      break;
400 
401 	    case 3:
402 	      /* An extended start address record.  */
403 	      if (len != 4)
404 		{
405 		  (*_bfd_error_handler)
406 		    (_("%B:%u: bad extended start address length in Intel Hex file"),
407 		     abfd, lineno);
408 		  bfd_set_error (bfd_error_bad_value);
409 		  goto error_return;
410 		}
411 
412 	      abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
413 
414 	      sec = NULL;
415 
416 	      break;
417 
418 	    case 4:
419 	      /* An extended linear address record.  */
420 	      if (len != 2)
421 		{
422 		  (*_bfd_error_handler)
423 		    (_("%B:%u: bad extended linear address record length in Intel Hex file"),
424 		     abfd, lineno);
425 		  bfd_set_error (bfd_error_bad_value);
426 		  goto error_return;
427 		}
428 
429 	      extbase = HEX4 (buf) << 16;
430 
431 	      sec = NULL;
432 
433 	      break;
434 
435 	    case 5:
436 	      /* An extended linear start address record.  */
437 	      if (len != 2 && len != 4)
438 		{
439 		  (*_bfd_error_handler)
440 		    (_("%B:%u: bad extended linear start address length in Intel Hex file"),
441 		     abfd, lineno);
442 		  bfd_set_error (bfd_error_bad_value);
443 		  goto error_return;
444 		}
445 
446 	      if (len == 2)
447 		abfd->start_address += HEX4 (buf) << 16;
448 	      else
449 		abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
450 
451 	      sec = NULL;
452 
453 	      break;
454 
455 	    default:
456 	      (*_bfd_error_handler)
457 		(_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
458 		 abfd, lineno, type);
459 	      bfd_set_error (bfd_error_bad_value);
460 	      goto error_return;
461 	    }
462 	}
463     }
464 
465   if (error)
466     goto error_return;
467 
468   if (buf != NULL)
469     free (buf);
470 
471   return TRUE;
472 
473  error_return:
474   if (buf != NULL)
475     free (buf);
476   return FALSE;
477 }
478 
479 /* Try to recognize an Intel Hex file.  */
480 
481 static const bfd_target *
ihex_object_p(bfd * abfd)482 ihex_object_p (bfd *abfd)
483 {
484   void * tdata_save;
485   bfd_byte b[9];
486   unsigned int i;
487   unsigned int type;
488 
489   ihex_init ();
490 
491   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
492     return NULL;
493   if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9)
494     {
495       if (bfd_get_error () == bfd_error_file_truncated)
496 	bfd_set_error (bfd_error_wrong_format);
497       return NULL;
498     }
499 
500   if (b[0] != ':')
501     {
502       bfd_set_error (bfd_error_wrong_format);
503       return NULL;
504     }
505 
506   for (i = 1; i < 9; i++)
507     {
508       if (! ISHEX (b[i]))
509 	{
510 	  bfd_set_error (bfd_error_wrong_format);
511 	  return NULL;
512 	}
513     }
514 
515   type = HEX2 (b + 7);
516   if (type > 5)
517     {
518       bfd_set_error (bfd_error_wrong_format);
519       return NULL;
520     }
521 
522   /* OK, it looks like it really is an Intel Hex file.  */
523   tdata_save = abfd->tdata.any;
524   if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
525     {
526       if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
527 	bfd_release (abfd, abfd->tdata.any);
528       abfd->tdata.any = tdata_save;
529       return NULL;
530     }
531 
532   return abfd->xvec;
533 }
534 
535 /* Read the contents of a section in an Intel Hex file.  */
536 
537 static bfd_boolean
ihex_read_section(bfd * abfd,asection * section,bfd_byte * contents)538 ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
539 {
540   int c;
541   bfd_byte *p;
542   bfd_byte *buf = NULL;
543   size_t bufsize;
544   bfd_boolean error;
545 
546   if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
547     goto error_return;
548 
549   p = contents;
550   bufsize = 0;
551   error = FALSE;
552   while ((c = ihex_get_byte (abfd, &error)) != EOF)
553     {
554       char hdr[8];
555       unsigned int len;
556       bfd_vma addr;
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       addr = HEX4 (hdr + 2);
572       type = HEX2 (hdr + 6);
573 
574       /* We should only see type 0 records here.  */
575       if (type != 0)
576 	{
577 	  (*_bfd_error_handler)
578 	    (_("%B: internal error in ihex_read_section"), abfd);
579 	  bfd_set_error (bfd_error_bad_value);
580 	  goto error_return;
581 	}
582 
583       if (len * 2 > bufsize)
584 	{
585 	  buf = bfd_realloc (buf, (bfd_size_type) len * 2);
586 	  if (buf == NULL)
587 	    goto error_return;
588 	  bufsize = len * 2;
589 	}
590 
591       if (bfd_bread (buf, (bfd_size_type) len * 2, abfd) != len * 2)
592 	goto error_return;
593 
594       for (i = 0; i < len; i++)
595 	*p++ = HEX2 (buf + 2 * i);
596       if ((bfd_size_type) (p - contents) >= section->size)
597 	{
598 	  /* We've read everything in the section.  */
599 	  if (buf != NULL)
600 	    free (buf);
601 	  return TRUE;
602 	}
603 
604       /* Skip the checksum.  */
605       if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2)
606 	goto error_return;
607     }
608 
609   if ((bfd_size_type) (p - contents) < section->size)
610     {
611       (*_bfd_error_handler)
612 	(_("%B: bad section length in ihex_read_section"), abfd);
613       bfd_set_error (bfd_error_bad_value);
614       goto error_return;
615     }
616 
617   if (buf != NULL)
618     free (buf);
619 
620   return TRUE;
621 
622  error_return:
623   if (buf != NULL)
624     free (buf);
625   return FALSE;
626 }
627 
628 /* Get the contents of a section in an Intel Hex file.  */
629 
630 static bfd_boolean
ihex_get_section_contents(bfd * abfd,asection * section,void * location,file_ptr offset,bfd_size_type count)631 ihex_get_section_contents (bfd *abfd,
632 			   asection *section,
633 			   void * location,
634 			   file_ptr offset,
635 			   bfd_size_type count)
636 {
637   if (section->used_by_bfd == NULL)
638     {
639       section->used_by_bfd = bfd_alloc (abfd, section->size);
640       if (section->used_by_bfd == NULL)
641 	return FALSE;
642       if (! ihex_read_section (abfd, section, 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 bfd_boolean
ihex_set_section_contents(bfd * abfd,asection * section,const void * location,file_ptr offset,bfd_size_type count)655 ihex_set_section_contents (bfd *abfd,
656 			   asection *section,
657 			   const void * location,
658 			   file_ptr offset,
659 			   bfd_size_type count)
660 {
661   struct ihex_data_list *n;
662   bfd_byte *data;
663   struct ihex_data_struct *tdata;
664 
665   if (count == 0
666       || (section->flags & SEC_ALLOC) == 0
667       || (section->flags & SEC_LOAD) == 0)
668     return TRUE;
669 
670   n = bfd_alloc (abfd, sizeof (* n));
671   if (n == NULL)
672     return FALSE;
673 
674   data = 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 bfd_boolean
ihex_write_record(bfd * abfd,size_t count,unsigned int addr,unsigned int type,bfd_byte * data)713 ihex_write_record (bfd *abfd,
714 		   size_t count,
715 		   unsigned int addr,
716 		   unsigned int type,
717 		   bfd_byte *data)
718 {
719   static const char digs[] = "0123456789ABCDEF";
720   char buf[9 + CHUNK * 2 + 4];
721   char *p;
722   unsigned int chksum;
723   unsigned int i;
724   size_t total;
725 
726 #define TOHEX(buf, v) \
727   ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
728 
729   buf[0] = ':';
730   TOHEX (buf + 1, count);
731   TOHEX (buf + 3, (addr >> 8) & 0xff);
732   TOHEX (buf + 5, addr & 0xff);
733   TOHEX (buf + 7, type);
734 
735   chksum = count + addr + (addr >> 8) + type;
736 
737   for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
738     {
739       TOHEX (p, *data);
740       chksum += *data;
741     }
742 
743   TOHEX (p, (- chksum) & 0xff);
744   p[2] = '\r';
745   p[3] = '\n';
746 
747   total = 9 + count * 2 + 4;
748   if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total)
749     return FALSE;
750 
751   return TRUE;
752 }
753 
754 /* Write out an Intel Hex file.  */
755 
756 static bfd_boolean
ihex_write_object_contents(bfd * abfd)757 ihex_write_object_contents (bfd *abfd)
758 {
759   bfd_vma segbase;
760   bfd_vma extbase;
761   struct ihex_data_list *l;
762 
763   segbase = 0;
764   extbase = 0;
765   for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
766     {
767       bfd_vma where;
768       bfd_byte *p;
769       bfd_size_type count;
770 
771       where = l->where;
772       p = l->data;
773       count = l->size;
774 
775       while (count > 0)
776 	{
777 	  size_t now;
778 	  unsigned int rec_addr;
779 
780 	  now = count;
781 	  if (count > CHUNK)
782 	    now = CHUNK;
783 
784 	  if (where > segbase + extbase + 0xffff)
785 	    {
786 	      bfd_byte addr[2];
787 
788 	      /* We need a new base address.  */
789 	      if (where <= 0xfffff)
790 		{
791 		  /* The addresses should be sorted.  */
792 		  BFD_ASSERT (extbase == 0);
793 
794 		  segbase = where & 0xf0000;
795 		  addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
796 		  addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
797 		  if (! ihex_write_record (abfd, 2, 0, 2, addr))
798 		    return FALSE;
799 		}
800 	      else
801 		{
802 		  /* The extended address record and the extended
803                      linear address record are combined, at least by
804                      some readers.  We need an extended linear address
805                      record here, so if we've already written out an
806                      extended address record, zero it out to avoid
807                      confusion.  */
808 		  if (segbase != 0)
809 		    {
810 		      addr[0] = 0;
811 		      addr[1] = 0;
812 		      if (! ihex_write_record (abfd, 2, 0, 2, addr))
813 			return FALSE;
814 		      segbase = 0;
815 		    }
816 
817 		  extbase = where & 0xffff0000;
818 		  if (where > extbase + 0xffff)
819 		    {
820 		      char buf[20];
821 
822 		      sprintf_vma (buf, where);
823 		      (*_bfd_error_handler)
824 			(_("%s: address 0x%s out of range for Intel Hex file"),
825 			 bfd_get_filename (abfd), buf);
826 		      bfd_set_error (bfd_error_bad_value);
827 		      return FALSE;
828 		    }
829 		  addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
830 		  addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
831 		  if (! ihex_write_record (abfd, 2, 0, 4, addr))
832 		    return FALSE;
833 		}
834 	    }
835 
836 	  rec_addr = where - (extbase + segbase);
837 
838           /* Output records shouldn't cross 64K boundaries.  */
839           if (rec_addr + now > 0xffff)
840             now = 0x10000 - rec_addr;
841 
842 	  if (! ihex_write_record (abfd, now, rec_addr, 0, p))
843 	    return FALSE;
844 
845 	  where += now;
846 	  p += now;
847 	  count -= now;
848 	}
849     }
850 
851   if (abfd->start_address != 0)
852     {
853       bfd_vma start;
854       bfd_byte startbuf[4];
855 
856       start = abfd->start_address;
857 
858       if (start <= 0xfffff)
859 	{
860 	  startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
861 	  startbuf[1] = 0;
862 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
863 	  startbuf[3] = (bfd_byte)start & 0xff;
864 	  if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
865 	    return FALSE;
866 	}
867       else
868 	{
869 	  startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
870 	  startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
871 	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
872 	  startbuf[3] = (bfd_byte)start & 0xff;
873 	  if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
874 	    return FALSE;
875 	}
876     }
877 
878   if (! ihex_write_record (abfd, 0, 0, 1, NULL))
879     return FALSE;
880 
881   return TRUE;
882 }
883 
884 /* Set the architecture for the output file.  The architecture is
885    irrelevant, so we ignore errors about unknown architectures.  */
886 
887 static bfd_boolean
ihex_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long mach)888 ihex_set_arch_mach (bfd *abfd,
889 		    enum bfd_architecture arch,
890 		    unsigned long mach)
891 {
892   if (! bfd_default_set_arch_mach (abfd, arch, mach))
893     {
894       if (arch != bfd_arch_unknown)
895 	return FALSE;
896     }
897   return TRUE;
898 }
899 
900 /* Get the size of the headers, for the linker.  */
901 
902 static int
ihex_sizeof_headers(bfd * abfd ATTRIBUTE_UNUSED,bfd_boolean exec ATTRIBUTE_UNUSED)903 ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean exec 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_get_reloc_upper_bound                ((long (*) (bfd *, asection *)) bfd_0l)
928 #define ihex_canonicalize_reloc                   ((long (*) (bfd *, asection *, arelent **, asymbol **)) bfd_0l)
929 #define ihex_bfd_reloc_type_lookup                _bfd_norelocs_bfd_reloc_type_lookup
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_merge_sections                   bfd_generic_merge_sections
934 #define ihex_bfd_is_group_section                 bfd_generic_is_group_section
935 #define ihex_bfd_discard_group                    bfd_generic_discard_group
936 #define ihex_section_already_linked               _bfd_generic_section_already_linked
937 #define ihex_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
938 #define ihex_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
939 #define ihex_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
940 #define ihex_bfd_link_just_syms                   _bfd_generic_link_just_syms
941 #define ihex_bfd_final_link                       _bfd_generic_final_link
942 #define ihex_bfd_link_split_section               _bfd_generic_link_split_section
943 
944 /* The Intel Hex target vector.  */
945 
946 const bfd_target ihex_vec =
947 {
948   "ihex",			/* Name.  */
949   bfd_target_ihex_flavour,
950   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
951   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
952   0,				/* Object flags.  */
953   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
954   0,				/* Leading underscore.  */
955   ' ',				/* AR_pad_char.  */
956   16,				/* AR_max_namelen.  */
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,	/* Data.  */
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,	/* Headers. */
963 
964   {
965     _bfd_dummy_target,
966     ihex_object_p,		/* bfd_check_format.  */
967     _bfd_dummy_target,
968     _bfd_dummy_target,
969   },
970   {
971     bfd_false,
972     ihex_mkobject,
973     _bfd_generic_mkarchive,
974     bfd_false,
975   },
976   {				/* bfd_write_contents.  */
977     bfd_false,
978     ihex_write_object_contents,
979     _bfd_write_archive_contents,
980     bfd_false,
981   },
982 
983   BFD_JUMP_TABLE_GENERIC (ihex),
984   BFD_JUMP_TABLE_COPY (_bfd_generic),
985   BFD_JUMP_TABLE_CORE (_bfd_nocore),
986   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
987   BFD_JUMP_TABLE_SYMBOLS (ihex),
988   BFD_JUMP_TABLE_RELOCS (ihex),
989   BFD_JUMP_TABLE_WRITE (ihex),
990   BFD_JUMP_TABLE_LINK (ihex),
991   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
992 
993   NULL,
994 
995   NULL
996 };
997