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