]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/binutils/bfd/ihex.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / binutils / bfd / ihex.c
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
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
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
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
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
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 *
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
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
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
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
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
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
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
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 };