Import gdb-7.10.1
[dragonfly.git] / contrib / gdb-7 / bfd / ihex.c
1 /* BFD back-end for Intel Hex objects.
2    Copyright (C) 1995-2015 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor of Cygnus Support <ian@cygnus.com>.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22
23 /* This is what Intel Hex files look like:
24
25 1. INTEL FORMATS
26
27 A. Intel 1
28
29    16-bit address-field format, for files 64k bytes in length or less.
30
31    DATA RECORD
32    Byte 1       Header = colon(:)
33    2..3         The number of data bytes in hex notation
34    4..5         High byte of the record load address
35    6..7         Low byte of the record load address
36    8..9         Record type, must be "00"
37    10..x        Data bytes in hex notation:
38         x = (number of bytes - 1) * 2 + 11
39    x+1..x+2     Checksum in hex notation
40    x+3..x+4     Carriage return, line feed
41
42    END RECORD
43    Byte 1       Header = colon (:)
44    2..3         The byte count, must be "00"
45    4..7         Transfer-address (usually "0000")
46                 the jump-to address, execution start address
47    8..9         Record type, must be "01"
48    10..11       Checksum, in hex notation
49    12..13       Carriage return, line feed
50
51 B. INTEL 2
52
53    MCS-86 format, using a 20-bit address for files larger than 64K bytes.
54
55    DATA RECORD
56    Byte 1       Header = colon (:)
57    2..3         The byte count of this record, hex notation
58    4..5         High byte of the record load address
59    6..7         Low byte of the record load address
60    8..9         Record type, must be "00"
61    10..x        The data bytes in hex notation:
62         x = (number of data bytes - 1) * 2 + 11
63    x+1..x+2     Checksum in hex notation
64    x+3..x+4     Carriage return, line feed
65
66    EXTENDED ADDRESS RECORD
67    Byte 1       Header = colon(:)
68    2..3         The byte count, must be "02"
69    4..7         Load address, must be "0000"
70    8..9         Record type, must be "02"
71    10..11       High byte of the offset address
72    12..13       Low byte of the offset address
73    14..15       Checksum in hex notation
74    16..17       Carriage return, line feed
75
76    The checksums are the two's complement of the 8-bit sum
77    without carry of the byte count, offset address, and the
78    record type.
79
80    START ADDRESS RECORD
81    Byte 1       Header = colon (:)
82    2..3         The byte count, must be "04"
83    4..7         Load address, must be "0000"
84    8..9         Record type, must be "03"
85    10..13       8086 CS value
86    14..17       8086 IP value
87    18..19       Checksum in hex notation
88    20..21       Carriage return, line feed
89
90 Another document reports these additional types:
91
92    EXTENDED LINEAR ADDRESS RECORD
93    Byte 1       Header = colon (:)
94    2..3         The byte count, must be "02"
95    4..7         Load address, must be "0000"
96    8..9         Record type, must be "04"
97    10..13       Upper 16 bits of address of subsequent records
98    14..15       Checksum in hex notation
99    16..17       Carriage return, line feed
100
101    START LINEAR ADDRESS RECORD
102    Byte 1       Header = colon (:)
103    2..3         The byte count, must be "02"
104    4..7         Load address, must be "0000"
105    8..9         Record type, must be "05"
106    10..13       Upper 16 bits of start address
107    14..15       Checksum in hex notation
108    16..17       Carriage return, line feed
109
110 The MRI compiler uses this, which is a repeat of type 5:
111
112   EXTENDED START RECORD
113    Byte 1       Header = colon (:)
114    2..3         The byte count, must be "04"
115    4..7         Load address, must be "0000"
116    8..9         Record type, must be "05"
117    10..13       Upper 16 bits of start address
118    14..17       Lower 16 bits of start address
119    18..19       Checksum in hex notation
120    20..21       Carriage return, line feed.  */
121
122 #include "sysdep.h"
123 #include "bfd.h"
124 #include "libbfd.h"
125 #include "libiberty.h"
126 #include "safe-ctype.h"
127
128 /* The number of bytes we put on one line during output.  */
129
130 #define CHUNK 16
131
132 /* Macros for converting between hex and binary.  */
133
134 #define NIBBLE(x)    (hex_value (x))
135 #define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
136 #define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
137 #define ISHEX(x)     (hex_p (x))
138
139 /* When we write out an ihex value, the values can not be output as
140    they are seen.  Instead, we hold them in memory in this structure.  */
141
142 struct ihex_data_list
143 {
144   struct ihex_data_list *next;
145   bfd_byte *data;
146   bfd_vma where;
147   bfd_size_type size;
148 };
149
150 /* The ihex tdata information.  */
151
152 struct ihex_data_struct
153 {
154   struct ihex_data_list *head;
155   struct ihex_data_list *tail;
156 };
157
158 /* Initialize by filling in the hex conversion array.  */
159
160 static void
161 ihex_init (void)
162 {
163   static bfd_boolean inited;
164
165   if (! inited)
166     {
167       inited = TRUE;
168       hex_init ();
169     }
170 }
171
172 /* Create an ihex object.  */
173
174 static bfd_boolean
175 ihex_mkobject (bfd *abfd)
176 {
177   struct ihex_data_struct *tdata;
178
179   tdata = (struct ihex_data_struct *) bfd_alloc (abfd, sizeof (* tdata));
180   if (tdata == NULL)
181     return FALSE;
182
183   abfd->tdata.ihex_data = tdata;
184   tdata->head = NULL;
185   tdata->tail = NULL;
186   return TRUE;
187 }
188
189 /* Read a byte from a BFD.  Set *ERRORPTR if an error occurred.
190    Return EOF on error or end of file.  */
191
192 static INLINE int
193 ihex_get_byte (bfd *abfd, bfd_boolean *errorptr)
194 {
195   bfd_byte c;
196
197   if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
198     {
199       if (bfd_get_error () != bfd_error_file_truncated)
200         *errorptr = TRUE;
201       return EOF;
202     }
203
204   return (int) (c & 0xff);
205 }
206
207 /* Report a problem in an Intel Hex file.  */
208
209 static void
210 ihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bfd_boolean error)
211 {
212   if (c == EOF)
213     {
214       if (! error)
215         bfd_set_error (bfd_error_file_truncated);
216     }
217   else
218     {
219       char buf[10];
220
221       if (! ISPRINT (c))
222         sprintf (buf, "\\%03o", (unsigned int) c);
223       else
224         {
225           buf[0] = c;
226           buf[1] = '\0';
227         }
228       (*_bfd_error_handler)
229         (_("%B:%d: unexpected character `%s' in Intel Hex file"),
230          abfd, lineno, buf);
231       bfd_set_error (bfd_error_bad_value);
232     }
233 }
234
235 /* Read an Intel hex file and turn it into sections.  We create a new
236    section for each contiguous set of bytes.  */
237
238 static bfd_boolean
239 ihex_scan (bfd *abfd)
240 {
241   bfd_vma segbase;
242   bfd_vma extbase;
243   asection *sec;
244   unsigned int lineno;
245   bfd_boolean error;
246   bfd_byte *buf = NULL;
247   size_t bufsize;
248   int c;
249
250   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
251     goto error_return;
252
253   abfd->start_address = 0;
254
255   segbase = 0;
256   extbase = 0;
257   sec = NULL;
258   lineno = 1;
259   error = FALSE;
260   bufsize = 0;
261
262   while ((c = ihex_get_byte (abfd, &error)) != EOF)
263     {
264       if (c == '\r')
265         continue;
266       else if (c == '\n')
267         {
268           ++lineno;
269           continue;
270         }
271       else if (c != ':')
272         {
273           ihex_bad_byte (abfd, lineno, c, error);
274           goto error_return;
275         }
276       else
277         {
278           file_ptr pos;
279           char hdr[8];
280           unsigned int i;
281           unsigned int len;
282           bfd_vma addr;
283           unsigned int type;
284           unsigned int chars;
285           unsigned int chksum;
286
287           /* This is a data record.  */
288           pos = bfd_tell (abfd) - 1;
289
290           /* Read the header bytes.  */
291           if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
292             goto error_return;
293
294           for (i = 0; i < 8; i++)
295             {
296               if (! ISHEX (hdr[i]))
297                 {
298                   ihex_bad_byte (abfd, lineno, hdr[i], error);
299                   goto error_return;
300                 }
301             }
302
303           len = HEX2 (hdr);
304           addr = HEX4 (hdr + 2);
305           type = HEX2 (hdr + 6);
306
307           /* Read the data bytes.  */
308           chars = len * 2 + 2;
309           if (chars >= bufsize)
310             {
311               buf = (bfd_byte *) bfd_realloc (buf, (bfd_size_type) chars);
312               if (buf == NULL)
313                 goto error_return;
314               bufsize = chars;
315             }
316
317           if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars)
318             goto error_return;
319
320           for (i = 0; i < chars; i++)
321             {
322               if (! ISHEX (buf[i]))
323                 {
324                   ihex_bad_byte (abfd, lineno, buf[i], error);
325                   goto error_return;
326                 }
327             }
328
329           /* Check the checksum.  */
330           chksum = len + addr + (addr >> 8) + type;
331           for (i = 0; i < len; i++)
332             chksum += HEX2 (buf + 2 * i);
333           if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
334             {
335               (*_bfd_error_handler)
336                 (_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
337                  abfd, lineno,
338                  (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
339               bfd_set_error (bfd_error_bad_value);
340               goto error_return;
341             }
342
343           switch (type)
344             {
345             case 0:
346               /* This is a data record.  */
347               if (sec != NULL
348                   && sec->vma + sec->size == extbase + segbase + addr)
349                 {
350                   /* This data goes at the end of the section we are
351                      currently building.  */
352                   sec->size += len;
353                 }
354               else if (len > 0)
355                 {
356                   char secbuf[20];
357                   char *secname;
358                   bfd_size_type amt;
359                   flagword flags;
360
361                   sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
362                   amt = strlen (secbuf) + 1;
363                   secname = (char *) bfd_alloc (abfd, amt);
364                   if (secname == NULL)
365                     goto error_return;
366                   strcpy (secname, secbuf);
367                   flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
368                   sec = bfd_make_section_with_flags (abfd, secname, flags);
369                   if (sec == NULL)
370                     goto error_return;
371                   sec->vma = extbase + segbase + addr;
372                   sec->lma = extbase + segbase + addr;
373                   sec->size = len;
374                   sec->filepos = pos;
375                 }
376               break;
377
378             case 1:
379               /* An end record.  */
380               if (abfd->start_address == 0)
381                 abfd->start_address = addr;
382               if (buf != NULL)
383                 free (buf);
384               return TRUE;
385
386             case 2:
387               /* An extended address record.  */
388               if (len != 2)
389                 {
390                   (*_bfd_error_handler)
391                     (_("%B:%u: bad extended address record length in Intel Hex file"),
392                      abfd, lineno);
393                   bfd_set_error (bfd_error_bad_value);
394                   goto error_return;
395                 }
396
397               segbase = HEX4 (buf) << 4;
398
399               sec = NULL;
400
401               break;
402
403             case 3:
404               /* An extended start address record.  */
405               if (len != 4)
406                 {
407                   (*_bfd_error_handler)
408                     (_("%B:%u: bad extended start address length in Intel Hex file"),
409                      abfd, lineno);
410                   bfd_set_error (bfd_error_bad_value);
411                   goto error_return;
412                 }
413
414               abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
415
416               sec = NULL;
417
418               break;
419
420             case 4:
421               /* An extended linear address record.  */
422               if (len != 2)
423                 {
424                   (*_bfd_error_handler)
425                     (_("%B:%u: bad extended linear address record length in Intel Hex file"),
426                      abfd, lineno);
427                   bfd_set_error (bfd_error_bad_value);
428                   goto error_return;
429                 }
430
431               extbase = HEX4 (buf) << 16;
432
433               sec = NULL;
434
435               break;
436
437             case 5:
438               /* An extended linear start address record.  */
439               if (len != 2 && len != 4)
440                 {
441                   (*_bfd_error_handler)
442                     (_("%B:%u: bad extended linear start address length in Intel Hex file"),
443                      abfd, lineno);
444                   bfd_set_error (bfd_error_bad_value);
445                   goto error_return;
446                 }
447
448               if (len == 2)
449                 abfd->start_address += HEX4 (buf) << 16;
450               else
451                 abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
452
453               sec = NULL;
454
455               break;
456
457             default:
458               (*_bfd_error_handler)
459                 (_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
460                  abfd, lineno, type);
461               bfd_set_error (bfd_error_bad_value);
462               goto error_return;
463             }
464         }
465     }
466
467   if (error)
468     goto error_return;
469
470   if (buf != NULL)
471     free (buf);
472
473   return TRUE;
474
475  error_return:
476   if (buf != NULL)
477     free (buf);
478   return FALSE;
479 }
480
481 /* Try to recognize an Intel Hex file.  */
482
483 static const bfd_target *
484 ihex_object_p (bfd *abfd)
485 {
486   void * tdata_save;
487   bfd_byte b[9];
488   unsigned int i;
489   unsigned int type;
490
491   ihex_init ();
492
493   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
494     return NULL;
495   if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9)
496     {
497       if (bfd_get_error () == bfd_error_file_truncated)
498         bfd_set_error (bfd_error_wrong_format);
499       return NULL;
500     }
501
502   if (b[0] != ':')
503     {
504       bfd_set_error (bfd_error_wrong_format);
505       return NULL;
506     }
507
508   for (i = 1; i < 9; i++)
509     {
510       if (! ISHEX (b[i]))
511         {
512           bfd_set_error (bfd_error_wrong_format);
513           return NULL;
514         }
515     }
516
517   type = HEX2 (b + 7);
518   if (type > 5)
519     {
520       bfd_set_error (bfd_error_wrong_format);
521       return NULL;
522     }
523
524   /* OK, it looks like it really is an Intel Hex file.  */
525   tdata_save = abfd->tdata.any;
526   if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
527     {
528       if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
529         bfd_release (abfd, abfd->tdata.any);
530       abfd->tdata.any = tdata_save;
531       return NULL;
532     }
533
534   return abfd->xvec;
535 }
536
537 /* Read the contents of a section in an Intel Hex file.  */
538
539 static bfd_boolean
540 ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
541 {
542   int c;
543   bfd_byte *p;
544   bfd_byte *buf = NULL;
545   size_t bufsize;
546   bfd_boolean error;
547
548   if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
549     goto error_return;
550
551   p = contents;
552   bufsize = 0;
553   error = FALSE;
554   while ((c = ihex_get_byte (abfd, &error)) != EOF)
555     {
556       char hdr[8];
557       unsigned int len;
558       unsigned int type;
559       unsigned int i;
560
561       if (c == '\r' || c == '\n')
562         continue;
563
564       /* This is called after ihex_scan has succeeded, so we ought to
565          know the exact format.  */
566       BFD_ASSERT (c == ':');
567
568       if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
569         goto error_return;
570
571       len = HEX2 (hdr);
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_byte *) 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
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,
643                                (bfd_byte *) section->used_by_bfd))
644         return FALSE;
645     }
646
647   memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
648           (size_t) count);
649
650   return TRUE;
651 }
652
653 /* Set the contents of a section in an Intel Hex file.  */
654
655 static bfd_boolean
656 ihex_set_section_contents (bfd *abfd,
657                            asection *section,
658                            const void * location,
659                            file_ptr offset,
660                            bfd_size_type count)
661 {
662   struct ihex_data_list *n;
663   bfd_byte *data;
664   struct ihex_data_struct *tdata;
665
666   if (count == 0
667       || (section->flags & SEC_ALLOC) == 0
668       || (section->flags & SEC_LOAD) == 0)
669     return TRUE;
670
671   n = (struct ihex_data_list *) bfd_alloc (abfd, sizeof (* n));
672   if (n == NULL)
673     return FALSE;
674
675   data = (bfd_byte *) bfd_alloc (abfd, count);
676   if (data == NULL)
677     return FALSE;
678   memcpy (data, location, (size_t) count);
679
680   n->data = data;
681   n->where = section->lma + offset;
682   n->size = count;
683
684   /* Sort the records by address.  Optimize for the common case of
685      adding a record to the end of the list.  */
686   tdata = abfd->tdata.ihex_data;
687   if (tdata->tail != NULL
688       && n->where >= tdata->tail->where)
689     {
690       tdata->tail->next = n;
691       n->next = NULL;
692       tdata->tail = n;
693     }
694   else
695     {
696       struct ihex_data_list **pp;
697
698       for (pp = &tdata->head;
699            *pp != NULL && (*pp)->where < n->where;
700            pp = &(*pp)->next)
701         ;
702       n->next = *pp;
703       *pp = n;
704       if (n->next == NULL)
705         tdata->tail = n;
706     }
707
708   return TRUE;
709 }
710
711 /* Write a record out to an Intel Hex file.  */
712
713 static bfd_boolean
714 ihex_write_record (bfd *abfd,
715                    size_t count,
716                    unsigned int addr,
717                    unsigned int type,
718                    bfd_byte *data)
719 {
720   static const char digs[] = "0123456789ABCDEF";
721   char buf[9 + CHUNK * 2 + 4];
722   char *p;
723   unsigned int chksum;
724   unsigned int i;
725   size_t total;
726
727 #define TOHEX(buf, v) \
728   ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
729
730   buf[0] = ':';
731   TOHEX (buf + 1, count);
732   TOHEX (buf + 3, (addr >> 8) & 0xff);
733   TOHEX (buf + 5, addr & 0xff);
734   TOHEX (buf + 7, type);
735
736   chksum = count + addr + (addr >> 8) + type;
737
738   for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
739     {
740       TOHEX (p, *data);
741       chksum += *data;
742     }
743
744   TOHEX (p, (- chksum) & 0xff);
745   p[2] = '\r';
746   p[3] = '\n';
747
748   total = 9 + count * 2 + 4;
749   if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total)
750     return FALSE;
751
752   return TRUE;
753 }
754
755 /* Write out an Intel Hex file.  */
756
757 static bfd_boolean
758 ihex_write_object_contents (bfd *abfd)
759 {
760   bfd_vma segbase;
761   bfd_vma extbase;
762   struct ihex_data_list *l;
763
764   segbase = 0;
765   extbase = 0;
766   for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
767     {
768       bfd_vma where;
769       bfd_byte *p;
770       bfd_size_type count;
771
772       where = l->where;
773       p = l->data;
774       count = l->size;
775
776       while (count > 0)
777         {
778           size_t now;
779           unsigned int rec_addr;
780
781           now = count;
782           if (count > CHUNK)
783             now = CHUNK;
784
785           if (where > segbase + extbase + 0xffff)
786             {
787               bfd_byte addr[2];
788
789               /* We need a new base address.  */
790               if (where <= 0xfffff)
791                 {
792                   /* The addresses should be sorted.  */
793                   BFD_ASSERT (extbase == 0);
794
795                   segbase = where & 0xf0000;
796                   addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
797                   addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
798                   if (! ihex_write_record (abfd, 2, 0, 2, addr))
799                     return FALSE;
800                 }
801               else
802                 {
803                   /* The extended address record and the extended
804                      linear address record are combined, at least by
805                      some readers.  We need an extended linear address
806                      record here, so if we've already written out an
807                      extended address record, zero it out to avoid
808                      confusion.  */
809                   if (segbase != 0)
810                     {
811                       addr[0] = 0;
812                       addr[1] = 0;
813                       if (! ihex_write_record (abfd, 2, 0, 2, addr))
814                         return FALSE;
815                       segbase = 0;
816                     }
817
818                   extbase = where & 0xffff0000;
819                   if (where > extbase + 0xffff)
820                     {
821                       char buf[20];
822
823                       sprintf_vma (buf, where);
824                       (*_bfd_error_handler)
825                         (_("%s: address 0x%s out of range for Intel Hex file"),
826                          bfd_get_filename (abfd), buf);
827                       bfd_set_error (bfd_error_bad_value);
828                       return FALSE;
829                     }
830                   addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
831                   addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
832                   if (! ihex_write_record (abfd, 2, 0, 4, addr))
833                     return FALSE;
834                 }
835             }
836
837           rec_addr = where - (extbase + segbase);
838
839           /* Output records shouldn't cross 64K boundaries.  */
840           if (rec_addr + now > 0xffff)
841             now = 0x10000 - rec_addr;
842
843           if (! ihex_write_record (abfd, now, rec_addr, 0, p))
844             return FALSE;
845
846           where += now;
847           p += now;
848           count -= now;
849         }
850     }
851
852   if (abfd->start_address != 0)
853     {
854       bfd_vma start;
855       bfd_byte startbuf[4];
856
857       start = abfd->start_address;
858
859       if (start <= 0xfffff)
860         {
861           startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
862           startbuf[1] = 0;
863           startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
864           startbuf[3] = (bfd_byte)start & 0xff;
865           if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
866             return FALSE;
867         }
868       else
869         {
870           startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
871           startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
872           startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
873           startbuf[3] = (bfd_byte)start & 0xff;
874           if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
875             return FALSE;
876         }
877     }
878
879   if (! ihex_write_record (abfd, 0, 0, 1, NULL))
880     return FALSE;
881
882   return TRUE;
883 }
884
885 /* Set the architecture for the output file.  The architecture is
886    irrelevant, so we ignore errors about unknown architectures.  */
887
888 static bfd_boolean
889 ihex_set_arch_mach (bfd *abfd,
890                     enum bfd_architecture arch,
891                     unsigned long mach)
892 {
893   if (! bfd_default_set_arch_mach (abfd, arch, mach))
894     {
895       if (arch != bfd_arch_unknown)
896         return FALSE;
897     }
898   return TRUE;
899 }
900
901 /* Get the size of the headers, for the linker.  */
902
903 static int
904 ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
905                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
906 {
907   return 0;
908 }
909
910 /* Some random definitions for the target vector.  */
911
912 #define ihex_close_and_cleanup                    _bfd_generic_close_and_cleanup
913 #define ihex_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
914 #define ihex_new_section_hook                     _bfd_generic_new_section_hook
915 #define ihex_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
916 #define ihex_get_symtab_upper_bound               bfd_0l
917 #define ihex_canonicalize_symtab                  ((long (*) (bfd *, asymbol **)) bfd_0l)
918 #define ihex_make_empty_symbol                    _bfd_generic_make_empty_symbol
919 #define ihex_print_symbol                         _bfd_nosymbols_print_symbol
920 #define ihex_get_symbol_info                      _bfd_nosymbols_get_symbol_info
921 #define ihex_get_symbol_version_string            _bfd_nosymbols_get_symbol_version_string
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_line                            _bfd_nosymbols_find_line
927 #define ihex_find_inliner_info                    _bfd_nosymbols_find_inliner_info
928 #define ihex_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
929 #define ihex_read_minisymbols                     _bfd_nosymbols_read_minisymbols
930 #define ihex_minisymbol_to_symbol                 _bfd_nosymbols_minisymbol_to_symbol
931 #define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
932 #define ihex_bfd_relax_section                    bfd_generic_relax_section
933 #define ihex_bfd_gc_sections                      bfd_generic_gc_sections
934 #define ihex_bfd_lookup_section_flags             bfd_generic_lookup_section_flags
935 #define ihex_bfd_merge_sections                   bfd_generic_merge_sections
936 #define ihex_bfd_is_group_section                 bfd_generic_is_group_section
937 #define ihex_bfd_discard_group                    bfd_generic_discard_group
938 #define ihex_section_already_linked               _bfd_generic_section_already_linked
939 #define ihex_bfd_define_common_symbol             bfd_generic_define_common_symbol
940 #define ihex_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
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 };