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