133965Sjdp/* BFD back-end for Intel Hex objects.
2218822Sdim   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3218822Sdim   2006, 2007 Free Software Foundation, Inc.
433965Sjdp   Written by Ian Lance Taylor of Cygnus Support <ian@cygnus.com>.
533965Sjdp
6104834Sobrien   This file is part of BFD, the Binary File Descriptor library.
733965Sjdp
8104834Sobrien   This program is free software; you can redistribute it and/or modify
9104834Sobrien   it under the terms of the GNU General Public License as published by
10104834Sobrien   the Free Software Foundation; either version 2 of the License, or
11104834Sobrien   (at your option) any later version.
1233965Sjdp
13104834Sobrien   This program is distributed in the hope that it will be useful,
14104834Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
15104834Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16104834Sobrien   GNU General Public License for more details.
1733965Sjdp
18104834Sobrien   You should have received a copy of the GNU General Public License
19104834Sobrien   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2133965Sjdp
2233965Sjdp/* This is what Intel Hex files look like:
2333965Sjdp
2433965Sjdp1. INTEL FORMATS
2533965Sjdp
2633965SjdpA. Intel 1
2733965Sjdp
2833965Sjdp   16-bit address-field format, for files 64k bytes in length or less.
2933965Sjdp
3033965Sjdp   DATA RECORD
3133965Sjdp   Byte 1	Header = colon(:)
3233965Sjdp   2..3		The number of data bytes in hex notation
3333965Sjdp   4..5		High byte of the record load address
3433965Sjdp   6..7		Low byte of the record load address
3533965Sjdp   8..9		Record type, must be "00"
3633965Sjdp   10..x	Data bytes in hex notation:
3733965Sjdp	x = (number of bytes - 1) * 2 + 11
3833965Sjdp   x+1..x+2	Checksum in hex notation
3933965Sjdp   x+3..x+4	Carriage return, line feed
4033965Sjdp
4133965Sjdp   END RECORD
4233965Sjdp   Byte 1	Header = colon (:)
4333965Sjdp   2..3		The byte count, must be "00"
4433965Sjdp   4..7		Transfer-address (usually "0000")
4533965Sjdp		the jump-to address, execution start address
4633965Sjdp   8..9		Record type, must be "01"
4733965Sjdp   10..11	Checksum, in hex notation
4833965Sjdp   12..13	Carriage return, line feed
4933965Sjdp
5033965SjdpB. INTEL 2
5133965Sjdp
5233965Sjdp   MCS-86 format, using a 20-bit address for files larger than 64K bytes.
5333965Sjdp
5433965Sjdp   DATA RECORD
5533965Sjdp   Byte 1	Header = colon (:)
5633965Sjdp   2..3		The byte count of this record, hex notation
5733965Sjdp   4..5		High byte of the record load address
5833965Sjdp   6..7		Low byte of the record load address
5933965Sjdp   8..9		Record type, must be "00"
6033965Sjdp   10..x	The data bytes in hex notation:
6133965Sjdp	x = (number of data bytes - 1) * 2 + 11
6233965Sjdp   x+1..x+2	Checksum in hex notation
6333965Sjdp   x+3..x+4	Carriage return, line feed
6433965Sjdp
6533965Sjdp   EXTENDED ADDRESS RECORD
6633965Sjdp   Byte 1	Header = colon(:)
6733965Sjdp   2..3		The byte count, must be "02"
6833965Sjdp   4..7		Load address, must be "0000"
6933965Sjdp   8..9		Record type, must be "02"
7033965Sjdp   10..11	High byte of the offset address
7133965Sjdp   12..13	Low byte of the offset address
7233965Sjdp   14..15	Checksum in hex notation
7333965Sjdp   16..17	Carriage return, line feed
7433965Sjdp
7533965Sjdp   The checksums are the two's complement of the 8-bit sum
7633965Sjdp   without carry of the byte count, offset address, and the
7733965Sjdp   record type.
7833965Sjdp
7933965Sjdp   START ADDRESS RECORD
8033965Sjdp   Byte 1	Header = colon (:)
8133965Sjdp   2..3		The byte count, must be "04"
8233965Sjdp   4..7		Load address, must be "0000"
8333965Sjdp   8..9		Record type, must be "03"
8433965Sjdp   10..13	8086 CS value
8533965Sjdp   14..17	8086 IP value
8633965Sjdp   18..19	Checksum in hex notation
8733965Sjdp   20..21	Carriage return, line feed
8833965Sjdp
8933965SjdpAnother document reports these additional types:
9033965Sjdp
9133965Sjdp   EXTENDED LINEAR ADDRESS RECORD
9233965Sjdp   Byte 1	Header = colon (:)
9333965Sjdp   2..3		The byte count, must be "02"
9433965Sjdp   4..7		Load address, must be "0000"
9533965Sjdp   8..9		Record type, must be "04"
9633965Sjdp   10..13	Upper 16 bits of address of subsequent records
9733965Sjdp   14..15	Checksum in hex notation
9833965Sjdp   16..17	Carriage return, line feed
9933965Sjdp
10033965Sjdp   START LINEAR ADDRESS RECORD
10133965Sjdp   Byte 1	Header = colon (:)
10233965Sjdp   2..3		The byte count, must be "02"
10333965Sjdp   4..7		Load address, must be "0000"
10433965Sjdp   8..9		Record type, must be "05"
10533965Sjdp   10..13	Upper 16 bits of start address
10633965Sjdp   14..15	Checksum in hex notation
10733965Sjdp   16..17	Carriage return, line feed
10833965Sjdp
10933965SjdpThe MRI compiler uses this, which is a repeat of type 5:
11033965Sjdp
11133965Sjdp  EXTENDED START RECORD
11233965Sjdp   Byte 1	Header = colon (:)
11333965Sjdp   2..3		The byte count, must be "04"
11433965Sjdp   4..7		Load address, must be "0000"
11533965Sjdp   8..9		Record type, must be "05"
11633965Sjdp   10..13	Upper 16 bits of start address
11733965Sjdp   14..17	Lower 16 bits of start address
11833965Sjdp   18..19	Checksum in hex notation
119218822Sdim   20..21	Carriage return, line feed.  */
12033965Sjdp
121218822Sdim#include "sysdep.h"
12233965Sjdp#include "bfd.h"
12333965Sjdp#include "libbfd.h"
12433965Sjdp#include "libiberty.h"
12589857Sobrien#include "safe-ctype.h"
12633965Sjdp
12733965Sjdp/* The number of bytes we put on one line during output.  */
12833965Sjdp
12960484Sobrien#define CHUNK 16
13033965Sjdp
131104834Sobrien/* Macros for converting between hex and binary.  */
13233965Sjdp
133104834Sobrien#define NIBBLE(x)    (hex_value (x))
13433965Sjdp#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
13533965Sjdp#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
136104834Sobrien#define ISHEX(x)     (hex_p (x))
13733965Sjdp
13833965Sjdp/* When we write out an ihex value, the values can not be output as
13933965Sjdp   they are seen.  Instead, we hold them in memory in this structure.  */
14033965Sjdp
14133965Sjdpstruct ihex_data_list
14233965Sjdp{
14333965Sjdp  struct ihex_data_list *next;
14433965Sjdp  bfd_byte *data;
14533965Sjdp  bfd_vma where;
14633965Sjdp  bfd_size_type size;
14733965Sjdp};
14833965Sjdp
14933965Sjdp/* The ihex tdata information.  */
15033965Sjdp
15133965Sjdpstruct ihex_data_struct
15233965Sjdp{
15333965Sjdp  struct ihex_data_list *head;
15433965Sjdp  struct ihex_data_list *tail;
15533965Sjdp};
15633965Sjdp
15733965Sjdp/* Initialize by filling in the hex conversion array.  */
15833965Sjdp
15933965Sjdpstatic void
160218822Sdimihex_init (void)
16133965Sjdp{
162130561Sobrien  static bfd_boolean inited;
16333965Sjdp
16433965Sjdp  if (! inited)
16533965Sjdp    {
166130561Sobrien      inited = TRUE;
16733965Sjdp      hex_init ();
16833965Sjdp    }
16933965Sjdp}
17033965Sjdp
17133965Sjdp/* Create an ihex object.  */
17233965Sjdp
173130561Sobrienstatic bfd_boolean
174218822Sdimihex_mkobject (bfd *abfd)
17533965Sjdp{
176104834Sobrien  struct ihex_data_struct *tdata;
17733965Sjdp
178218822Sdim  tdata = bfd_alloc (abfd, sizeof (* tdata));
179104834Sobrien  if (tdata == NULL)
180130561Sobrien    return FALSE;
18133965Sjdp
182104834Sobrien  abfd->tdata.ihex_data = tdata;
183104834Sobrien  tdata->head = NULL;
184104834Sobrien  tdata->tail = NULL;
185130561Sobrien  return TRUE;
18633965Sjdp}
18733965Sjdp
18833965Sjdp/* Read a byte from a BFD.  Set *ERRORPTR if an error occurred.
18933965Sjdp   Return EOF on error or end of file.  */
19033965Sjdp
19133965Sjdpstatic INLINE int
192218822Sdimihex_get_byte (bfd *abfd, bfd_boolean *errorptr)
19333965Sjdp{
19433965Sjdp  bfd_byte c;
19533965Sjdp
19689857Sobrien  if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
19733965Sjdp    {
19833965Sjdp      if (bfd_get_error () != bfd_error_file_truncated)
199130561Sobrien	*errorptr = TRUE;
20033965Sjdp      return EOF;
20133965Sjdp    }
20233965Sjdp
20333965Sjdp  return (int) (c & 0xff);
20433965Sjdp}
20533965Sjdp
20633965Sjdp/* Report a problem in an Intel Hex file.  */
20733965Sjdp
20833965Sjdpstatic void
209218822Sdimihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bfd_boolean error)
21033965Sjdp{
21133965Sjdp  if (c == EOF)
21233965Sjdp    {
21333965Sjdp      if (! error)
21433965Sjdp	bfd_set_error (bfd_error_file_truncated);
21533965Sjdp    }
21633965Sjdp  else
21733965Sjdp    {
21833965Sjdp      char buf[10];
21933965Sjdp
22089857Sobrien      if (! ISPRINT (c))
22133965Sjdp	sprintf (buf, "\\%03o", (unsigned int) c);
22233965Sjdp      else
22333965Sjdp	{
22433965Sjdp	  buf[0] = c;
22533965Sjdp	  buf[1] = '\0';
22633965Sjdp	}
22733965Sjdp      (*_bfd_error_handler)
228218822Sdim	(_("%B:%d: unexpected character `%s' in Intel Hex file"),
229218822Sdim	 abfd, lineno, buf);
23033965Sjdp      bfd_set_error (bfd_error_bad_value);
23133965Sjdp    }
23233965Sjdp}
23333965Sjdp
23433965Sjdp/* Read an Intel hex file and turn it into sections.  We create a new
23533965Sjdp   section for each contiguous set of bytes.  */
23633965Sjdp
237130561Sobrienstatic bfd_boolean
238218822Sdimihex_scan (bfd *abfd)
23933965Sjdp{
24033965Sjdp  bfd_vma segbase;
24138889Sjdp  bfd_vma extbase;
24233965Sjdp  asection *sec;
24389857Sobrien  unsigned int lineno;
244130561Sobrien  bfd_boolean error;
24533965Sjdp  bfd_byte *buf = NULL;
24633965Sjdp  size_t bufsize;
24733965Sjdp  int c;
24833965Sjdp
24933965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
25033965Sjdp    goto error_return;
25133965Sjdp
25233965Sjdp  abfd->start_address = 0;
25333965Sjdp
25433965Sjdp  segbase = 0;
25538889Sjdp  extbase = 0;
25633965Sjdp  sec = NULL;
25733965Sjdp  lineno = 1;
258130561Sobrien  error = FALSE;
25933965Sjdp  bufsize = 0;
260104834Sobrien
26133965Sjdp  while ((c = ihex_get_byte (abfd, &error)) != EOF)
26233965Sjdp    {
26333965Sjdp      if (c == '\r')
26433965Sjdp	continue;
26533965Sjdp      else if (c == '\n')
26633965Sjdp	{
26733965Sjdp	  ++lineno;
26833965Sjdp	  continue;
26933965Sjdp	}
27033965Sjdp      else if (c != ':')
27133965Sjdp	{
27233965Sjdp	  ihex_bad_byte (abfd, lineno, c, error);
27333965Sjdp	  goto error_return;
27433965Sjdp	}
27533965Sjdp      else
27633965Sjdp	{
27733965Sjdp	  file_ptr pos;
27833965Sjdp	  char hdr[8];
27933965Sjdp	  unsigned int i;
28033965Sjdp	  unsigned int len;
28133965Sjdp	  bfd_vma addr;
28233965Sjdp	  unsigned int type;
28333965Sjdp	  unsigned int chars;
28433965Sjdp	  unsigned int chksum;
28533965Sjdp
28633965Sjdp	  /* This is a data record.  */
28733965Sjdp	  pos = bfd_tell (abfd) - 1;
28833965Sjdp
28933965Sjdp	  /* Read the header bytes.  */
29089857Sobrien	  if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
29133965Sjdp	    goto error_return;
29233965Sjdp
29333965Sjdp	  for (i = 0; i < 8; i++)
29433965Sjdp	    {
29533965Sjdp	      if (! ISHEX (hdr[i]))
29633965Sjdp		{
29733965Sjdp		  ihex_bad_byte (abfd, lineno, hdr[i], error);
29833965Sjdp		  goto error_return;
29933965Sjdp		}
30033965Sjdp	    }
30133965Sjdp
30233965Sjdp	  len = HEX2 (hdr);
30333965Sjdp	  addr = HEX4 (hdr + 2);
30433965Sjdp	  type = HEX2 (hdr + 6);
30533965Sjdp
30633965Sjdp	  /* Read the data bytes.  */
30733965Sjdp	  chars = len * 2 + 2;
30833965Sjdp	  if (chars >= bufsize)
30933965Sjdp	    {
310218822Sdim	      buf = bfd_realloc (buf, (bfd_size_type) chars);
31133965Sjdp	      if (buf == NULL)
31233965Sjdp		goto error_return;
31333965Sjdp	      bufsize = chars;
31433965Sjdp	    }
31533965Sjdp
31689857Sobrien	  if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars)
31733965Sjdp	    goto error_return;
31833965Sjdp
31933965Sjdp	  for (i = 0; i < chars; i++)
32033965Sjdp	    {
32133965Sjdp	      if (! ISHEX (buf[i]))
32233965Sjdp		{
323326382Semaste		  ihex_bad_byte (abfd, lineno, buf[i], error);
32433965Sjdp		  goto error_return;
32533965Sjdp		}
32633965Sjdp	    }
32733965Sjdp
32833965Sjdp	  /* Check the checksum.  */
32933965Sjdp	  chksum = len + addr + (addr >> 8) + type;
33033965Sjdp	  for (i = 0; i < len; i++)
33133965Sjdp	    chksum += HEX2 (buf + 2 * i);
33233965Sjdp	  if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
33333965Sjdp	    {
33433965Sjdp	      (*_bfd_error_handler)
335218822Sdim		(_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
336218822Sdim		 abfd, lineno,
33733965Sjdp		 (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
33833965Sjdp	      bfd_set_error (bfd_error_bad_value);
33933965Sjdp	      goto error_return;
34033965Sjdp	    }
34133965Sjdp
34233965Sjdp	  switch (type)
34333965Sjdp	    {
34433965Sjdp	    case 0:
34533965Sjdp	      /* This is a data record.  */
34633965Sjdp	      if (sec != NULL
347218822Sdim		  && sec->vma + sec->size == extbase + segbase + addr)
34833965Sjdp		{
34933965Sjdp		  /* This data goes at the end of the section we are
35033965Sjdp                     currently building.  */
351218822Sdim		  sec->size += len;
35233965Sjdp		}
35333965Sjdp	      else if (len > 0)
35433965Sjdp		{
35533965Sjdp		  char secbuf[20];
35633965Sjdp		  char *secname;
35789857Sobrien		  bfd_size_type amt;
358218822Sdim		  flagword flags;
35933965Sjdp
36033965Sjdp		  sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
36189857Sobrien		  amt = strlen (secbuf) + 1;
362218822Sdim		  secname = bfd_alloc (abfd, amt);
36333965Sjdp		  if (secname == NULL)
36433965Sjdp		    goto error_return;
36533965Sjdp		  strcpy (secname, secbuf);
366218822Sdim		  flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
367218822Sdim		  sec = bfd_make_section_with_flags (abfd, secname, flags);
36833965Sjdp		  if (sec == NULL)
36933965Sjdp		    goto error_return;
37038889Sjdp		  sec->vma = extbase + segbase + addr;
37138889Sjdp		  sec->lma = extbase + segbase + addr;
372218822Sdim		  sec->size = len;
37333965Sjdp		  sec->filepos = pos;
37433965Sjdp		}
37533965Sjdp	      break;
37633965Sjdp
37733965Sjdp	    case 1:
37833965Sjdp	      /* An end record.  */
37933965Sjdp	      if (abfd->start_address == 0)
38033965Sjdp		abfd->start_address = addr;
38133965Sjdp	      if (buf != NULL)
38233965Sjdp		free (buf);
383130561Sobrien	      return TRUE;
38433965Sjdp
38533965Sjdp	    case 2:
38633965Sjdp	      /* An extended address record.  */
38733965Sjdp	      if (len != 2)
38833965Sjdp		{
38933965Sjdp		  (*_bfd_error_handler)
390218822Sdim		    (_("%B:%u: bad extended address record length in Intel Hex file"),
391218822Sdim		     abfd, lineno);
39233965Sjdp		  bfd_set_error (bfd_error_bad_value);
39333965Sjdp		  goto error_return;
39433965Sjdp		}
39533965Sjdp
39633965Sjdp	      segbase = HEX4 (buf) << 4;
39733965Sjdp
39833965Sjdp	      sec = NULL;
39933965Sjdp
40033965Sjdp	      break;
40133965Sjdp
40233965Sjdp	    case 3:
40333965Sjdp	      /* An extended start address record.  */
40433965Sjdp	      if (len != 4)
40533965Sjdp		{
40633965Sjdp		  (*_bfd_error_handler)
407218822Sdim		    (_("%B:%u: bad extended start address length in Intel Hex file"),
408218822Sdim		     abfd, lineno);
40933965Sjdp		  bfd_set_error (bfd_error_bad_value);
41033965Sjdp		  goto error_return;
41133965Sjdp		}
41233965Sjdp
41333965Sjdp	      abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
41433965Sjdp
41533965Sjdp	      sec = NULL;
41633965Sjdp
41733965Sjdp	      break;
41833965Sjdp
41933965Sjdp	    case 4:
42033965Sjdp	      /* An extended linear address record.  */
42133965Sjdp	      if (len != 2)
42233965Sjdp		{
42333965Sjdp		  (*_bfd_error_handler)
424218822Sdim		    (_("%B:%u: bad extended linear address record length in Intel Hex file"),
425218822Sdim		     abfd, lineno);
42633965Sjdp		  bfd_set_error (bfd_error_bad_value);
42733965Sjdp		  goto error_return;
42833965Sjdp		}
42933965Sjdp
43038889Sjdp	      extbase = HEX4 (buf) << 16;
43133965Sjdp
43233965Sjdp	      sec = NULL;
43333965Sjdp
43433965Sjdp	      break;
43533965Sjdp
43633965Sjdp	    case 5:
43733965Sjdp	      /* An extended linear start address record.  */
43833965Sjdp	      if (len != 2 && len != 4)
43933965Sjdp		{
44033965Sjdp		  (*_bfd_error_handler)
441218822Sdim		    (_("%B:%u: bad extended linear start address length in Intel Hex file"),
442218822Sdim		     abfd, lineno);
44333965Sjdp		  bfd_set_error (bfd_error_bad_value);
44433965Sjdp		  goto error_return;
44533965Sjdp		}
44633965Sjdp
44733965Sjdp	      if (len == 2)
44833965Sjdp		abfd->start_address += HEX4 (buf) << 16;
44933965Sjdp	      else
45033965Sjdp		abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
45133965Sjdp
45233965Sjdp	      sec = NULL;
45333965Sjdp
45433965Sjdp	      break;
45533965Sjdp
45633965Sjdp	    default:
45733965Sjdp	      (*_bfd_error_handler)
458218822Sdim		(_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
459218822Sdim		 abfd, lineno, type);
46033965Sjdp	      bfd_set_error (bfd_error_bad_value);
46133965Sjdp	      goto error_return;
46233965Sjdp	    }
46333965Sjdp	}
46433965Sjdp    }
46533965Sjdp
46633965Sjdp  if (error)
46733965Sjdp    goto error_return;
46833965Sjdp
46933965Sjdp  if (buf != NULL)
47033965Sjdp    free (buf);
47133965Sjdp
472130561Sobrien  return TRUE;
47333965Sjdp
47433965Sjdp error_return:
47533965Sjdp  if (buf != NULL)
47633965Sjdp    free (buf);
477130561Sobrien  return FALSE;
47833965Sjdp}
47933965Sjdp
48033965Sjdp/* Try to recognize an Intel Hex file.  */
48133965Sjdp
48233965Sjdpstatic const bfd_target *
483218822Sdimihex_object_p (bfd *abfd)
48433965Sjdp{
485218822Sdim  void * tdata_save;
48633965Sjdp  bfd_byte b[9];
48733965Sjdp  unsigned int i;
48833965Sjdp  unsigned int type;
48933965Sjdp
49033965Sjdp  ihex_init ();
49133965Sjdp
49233965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
49333965Sjdp    return NULL;
49489857Sobrien  if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9)
49533965Sjdp    {
49633965Sjdp      if (bfd_get_error () == bfd_error_file_truncated)
49733965Sjdp	bfd_set_error (bfd_error_wrong_format);
49833965Sjdp      return NULL;
49933965Sjdp    }
50033965Sjdp
50133965Sjdp  if (b[0] != ':')
50233965Sjdp    {
50333965Sjdp      bfd_set_error (bfd_error_wrong_format);
50433965Sjdp      return NULL;
50533965Sjdp    }
50633965Sjdp
50733965Sjdp  for (i = 1; i < 9; i++)
50833965Sjdp    {
50933965Sjdp      if (! ISHEX (b[i]))
51033965Sjdp	{
51133965Sjdp	  bfd_set_error (bfd_error_wrong_format);
51233965Sjdp	  return NULL;
51333965Sjdp	}
51433965Sjdp    }
51533965Sjdp
51633965Sjdp  type = HEX2 (b + 7);
51733965Sjdp  if (type > 5)
51833965Sjdp    {
51933965Sjdp      bfd_set_error (bfd_error_wrong_format);
52033965Sjdp      return NULL;
52133965Sjdp    }
52233965Sjdp
52333965Sjdp  /* OK, it looks like it really is an Intel Hex file.  */
524104834Sobrien  tdata_save = abfd->tdata.any;
525104834Sobrien  if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
526104834Sobrien    {
527104834Sobrien      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
528104834Sobrien	bfd_release (abfd, abfd->tdata.any);
529104834Sobrien      abfd->tdata.any = tdata_save;
530104834Sobrien      return NULL;
531104834Sobrien    }
53233965Sjdp
53333965Sjdp  return abfd->xvec;
53433965Sjdp}
53533965Sjdp
53633965Sjdp/* Read the contents of a section in an Intel Hex file.  */
53733965Sjdp
538130561Sobrienstatic bfd_boolean
539218822Sdimihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
54033965Sjdp{
54133965Sjdp  int c;
54233965Sjdp  bfd_byte *p;
54333965Sjdp  bfd_byte *buf = NULL;
54433965Sjdp  size_t bufsize;
545130561Sobrien  bfd_boolean error;
54633965Sjdp
54733965Sjdp  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
54833965Sjdp    goto error_return;
54933965Sjdp
55033965Sjdp  p = contents;
55133965Sjdp  bufsize = 0;
552130561Sobrien  error = FALSE;
55333965Sjdp  while ((c = ihex_get_byte (abfd, &error)) != EOF)
55433965Sjdp    {
55533965Sjdp      char hdr[8];
55633965Sjdp      unsigned int len;
55733965Sjdp      unsigned int type;
55833965Sjdp      unsigned int i;
55933965Sjdp
56033965Sjdp      if (c == '\r' || c == '\n')
56133965Sjdp	continue;
56233965Sjdp
56333965Sjdp      /* This is called after ihex_scan has succeeded, so we ought to
56433965Sjdp         know the exact format.  */
56533965Sjdp      BFD_ASSERT (c == ':');
56633965Sjdp
56789857Sobrien      if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
56833965Sjdp	goto error_return;
56933965Sjdp
57033965Sjdp      len = HEX2 (hdr);
57133965Sjdp      type = HEX2 (hdr + 6);
57233965Sjdp
57333965Sjdp      /* We should only see type 0 records here.  */
57433965Sjdp      if (type != 0)
57533965Sjdp	{
57633965Sjdp	  (*_bfd_error_handler)
577218822Sdim	    (_("%B: internal error in ihex_read_section"), abfd);
57833965Sjdp	  bfd_set_error (bfd_error_bad_value);
57933965Sjdp	  goto error_return;
58033965Sjdp	}
58133965Sjdp
58233965Sjdp      if (len * 2 > bufsize)
58333965Sjdp	{
584218822Sdim	  buf = bfd_realloc (buf, (bfd_size_type) len * 2);
58533965Sjdp	  if (buf == NULL)
58633965Sjdp	    goto error_return;
58733965Sjdp	  bufsize = len * 2;
58833965Sjdp	}
58933965Sjdp
59089857Sobrien      if (bfd_bread (buf, (bfd_size_type) len * 2, abfd) != len * 2)
59133965Sjdp	goto error_return;
59233965Sjdp
59333965Sjdp      for (i = 0; i < len; i++)
59433965Sjdp	*p++ = HEX2 (buf + 2 * i);
595218822Sdim      if ((bfd_size_type) (p - contents) >= section->size)
59633965Sjdp	{
59733965Sjdp	  /* We've read everything in the section.  */
59833965Sjdp	  if (buf != NULL)
59933965Sjdp	    free (buf);
600130561Sobrien	  return TRUE;
60133965Sjdp	}
60233965Sjdp
60333965Sjdp      /* Skip the checksum.  */
60489857Sobrien      if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2)
60533965Sjdp	goto error_return;
60633965Sjdp    }
60733965Sjdp
608218822Sdim  if ((bfd_size_type) (p - contents) < section->size)
60933965Sjdp    {
61033965Sjdp      (*_bfd_error_handler)
611218822Sdim	(_("%B: bad section length in ihex_read_section"), abfd);
61233965Sjdp      bfd_set_error (bfd_error_bad_value);
61333965Sjdp      goto error_return;
61433965Sjdp    }
61533965Sjdp
61633965Sjdp  if (buf != NULL)
61733965Sjdp    free (buf);
61833965Sjdp
619130561Sobrien  return TRUE;
62033965Sjdp
62133965Sjdp error_return:
62233965Sjdp  if (buf != NULL)
62333965Sjdp    free (buf);
624130561Sobrien  return FALSE;
62533965Sjdp}
62633965Sjdp
62733965Sjdp/* Get the contents of a section in an Intel Hex file.  */
62833965Sjdp
629130561Sobrienstatic bfd_boolean
630218822Sdimihex_get_section_contents (bfd *abfd,
631218822Sdim			   asection *section,
632218822Sdim			   void * location,
633218822Sdim			   file_ptr offset,
634218822Sdim			   bfd_size_type count)
63533965Sjdp{
63633965Sjdp  if (section->used_by_bfd == NULL)
63733965Sjdp    {
638218822Sdim      section->used_by_bfd = bfd_alloc (abfd, section->size);
63933965Sjdp      if (section->used_by_bfd == NULL)
640130561Sobrien	return FALSE;
64133965Sjdp      if (! ihex_read_section (abfd, section, section->used_by_bfd))
642130561Sobrien	return FALSE;
64333965Sjdp    }
64433965Sjdp
64533965Sjdp  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
64633965Sjdp	  (size_t) count);
64733965Sjdp
648130561Sobrien  return TRUE;
64933965Sjdp}
65033965Sjdp
65133965Sjdp/* Set the contents of a section in an Intel Hex file.  */
65233965Sjdp
653130561Sobrienstatic bfd_boolean
654218822Sdimihex_set_section_contents (bfd *abfd,
655218822Sdim			   asection *section,
656218822Sdim			   const void * location,
657218822Sdim			   file_ptr offset,
658218822Sdim			   bfd_size_type count)
65933965Sjdp{
66033965Sjdp  struct ihex_data_list *n;
66133965Sjdp  bfd_byte *data;
66233965Sjdp  struct ihex_data_struct *tdata;
66333965Sjdp
66433965Sjdp  if (count == 0
66533965Sjdp      || (section->flags & SEC_ALLOC) == 0
66633965Sjdp      || (section->flags & SEC_LOAD) == 0)
667130561Sobrien    return TRUE;
66833965Sjdp
669218822Sdim  n = bfd_alloc (abfd, sizeof (* n));
67033965Sjdp  if (n == NULL)
671130561Sobrien    return FALSE;
67233965Sjdp
673218822Sdim  data = bfd_alloc (abfd, count);
67433965Sjdp  if (data == NULL)
675130561Sobrien    return FALSE;
67633965Sjdp  memcpy (data, location, (size_t) count);
67733965Sjdp
67833965Sjdp  n->data = data;
67933965Sjdp  n->where = section->lma + offset;
68033965Sjdp  n->size = count;
68133965Sjdp
68233965Sjdp  /* Sort the records by address.  Optimize for the common case of
68333965Sjdp     adding a record to the end of the list.  */
68433965Sjdp  tdata = abfd->tdata.ihex_data;
68533965Sjdp  if (tdata->tail != NULL
68633965Sjdp      && n->where >= tdata->tail->where)
68733965Sjdp    {
68833965Sjdp      tdata->tail->next = n;
68933965Sjdp      n->next = NULL;
69033965Sjdp      tdata->tail = n;
69133965Sjdp    }
69233965Sjdp  else
69333965Sjdp    {
694218822Sdim      struct ihex_data_list **pp;
69533965Sjdp
69633965Sjdp      for (pp = &tdata->head;
69733965Sjdp	   *pp != NULL && (*pp)->where < n->where;
69833965Sjdp	   pp = &(*pp)->next)
69933965Sjdp	;
70033965Sjdp      n->next = *pp;
70133965Sjdp      *pp = n;
70233965Sjdp      if (n->next == NULL)
70333965Sjdp	tdata->tail = n;
70433965Sjdp    }
70533965Sjdp
706130561Sobrien  return TRUE;
70733965Sjdp}
70833965Sjdp
70933965Sjdp/* Write a record out to an Intel Hex file.  */
71033965Sjdp
711130561Sobrienstatic bfd_boolean
712218822Sdimihex_write_record (bfd *abfd,
713218822Sdim		   size_t count,
714218822Sdim		   unsigned int addr,
715218822Sdim		   unsigned int type,
716218822Sdim		   bfd_byte *data)
71733965Sjdp{
71833965Sjdp  static const char digs[] = "0123456789ABCDEF";
71933965Sjdp  char buf[9 + CHUNK * 2 + 4];
72033965Sjdp  char *p;
72133965Sjdp  unsigned int chksum;
72233965Sjdp  unsigned int i;
72389857Sobrien  size_t total;
72433965Sjdp
72533965Sjdp#define TOHEX(buf, v) \
72633965Sjdp  ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
72733965Sjdp
72833965Sjdp  buf[0] = ':';
72933965Sjdp  TOHEX (buf + 1, count);
73033965Sjdp  TOHEX (buf + 3, (addr >> 8) & 0xff);
73133965Sjdp  TOHEX (buf + 5, addr & 0xff);
73233965Sjdp  TOHEX (buf + 7, type);
73333965Sjdp
73433965Sjdp  chksum = count + addr + (addr >> 8) + type;
73533965Sjdp
73633965Sjdp  for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
73733965Sjdp    {
73833965Sjdp      TOHEX (p, *data);
73933965Sjdp      chksum += *data;
74033965Sjdp    }
74133965Sjdp
74233965Sjdp  TOHEX (p, (- chksum) & 0xff);
74333965Sjdp  p[2] = '\r';
74433965Sjdp  p[3] = '\n';
74533965Sjdp
74689857Sobrien  total = 9 + count * 2 + 4;
74789857Sobrien  if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total)
748130561Sobrien    return FALSE;
74933965Sjdp
750130561Sobrien  return TRUE;
75133965Sjdp}
75233965Sjdp
75333965Sjdp/* Write out an Intel Hex file.  */
75433965Sjdp
755130561Sobrienstatic bfd_boolean
756218822Sdimihex_write_object_contents (bfd *abfd)
75733965Sjdp{
75833965Sjdp  bfd_vma segbase;
75938889Sjdp  bfd_vma extbase;
76033965Sjdp  struct ihex_data_list *l;
76133965Sjdp
76233965Sjdp  segbase = 0;
76338889Sjdp  extbase = 0;
76433965Sjdp  for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
76533965Sjdp    {
76633965Sjdp      bfd_vma where;
76733965Sjdp      bfd_byte *p;
76833965Sjdp      bfd_size_type count;
76933965Sjdp
77033965Sjdp      where = l->where;
77133965Sjdp      p = l->data;
77233965Sjdp      count = l->size;
773218822Sdim
77433965Sjdp      while (count > 0)
77533965Sjdp	{
77689857Sobrien	  size_t now;
77789857Sobrien	  unsigned int rec_addr;
77833965Sjdp
77933965Sjdp	  now = count;
78089857Sobrien	  if (count > CHUNK)
78133965Sjdp	    now = CHUNK;
78233965Sjdp
78338889Sjdp	  if (where > segbase + extbase + 0xffff)
78433965Sjdp	    {
78533965Sjdp	      bfd_byte addr[2];
78633965Sjdp
78733965Sjdp	      /* We need a new base address.  */
78833965Sjdp	      if (where <= 0xfffff)
78933965Sjdp		{
79038889Sjdp		  /* The addresses should be sorted.  */
79138889Sjdp		  BFD_ASSERT (extbase == 0);
79238889Sjdp
79333965Sjdp		  segbase = where & 0xf0000;
79433965Sjdp		  addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
79533965Sjdp		  addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
79633965Sjdp		  if (! ihex_write_record (abfd, 2, 0, 2, addr))
797130561Sobrien		    return FALSE;
79833965Sjdp		}
79933965Sjdp	      else
80033965Sjdp		{
80138889Sjdp		  /* The extended address record and the extended
80238889Sjdp                     linear address record are combined, at least by
80338889Sjdp                     some readers.  We need an extended linear address
80438889Sjdp                     record here, so if we've already written out an
80538889Sjdp                     extended address record, zero it out to avoid
80638889Sjdp                     confusion.  */
80738889Sjdp		  if (segbase != 0)
80833965Sjdp		    {
80938889Sjdp		      addr[0] = 0;
81038889Sjdp		      addr[1] = 0;
81138889Sjdp		      if (! ihex_write_record (abfd, 2, 0, 2, addr))
812130561Sobrien			return FALSE;
81338889Sjdp		      segbase = 0;
81438889Sjdp		    }
81538889Sjdp
81638889Sjdp		  extbase = where & 0xffff0000;
81738889Sjdp		  if (where > extbase + 0xffff)
81838889Sjdp		    {
81933965Sjdp		      char buf[20];
82033965Sjdp
82133965Sjdp		      sprintf_vma (buf, where);
82233965Sjdp		      (*_bfd_error_handler)
82391041Sobrien			(_("%s: address 0x%s out of range for Intel Hex file"),
82433965Sjdp			 bfd_get_filename (abfd), buf);
82533965Sjdp		      bfd_set_error (bfd_error_bad_value);
826130561Sobrien		      return FALSE;
82733965Sjdp		    }
82838889Sjdp		  addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
82938889Sjdp		  addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
83033965Sjdp		  if (! ihex_write_record (abfd, 2, 0, 4, addr))
831130561Sobrien		    return FALSE;
83233965Sjdp		}
83333965Sjdp	    }
83433965Sjdp
83589857Sobrien	  rec_addr = where - (extbase + segbase);
83694536Sobrien
83794536Sobrien          /* Output records shouldn't cross 64K boundaries.  */
83899461Sobrien          if (rec_addr + now > 0xffff)
83999461Sobrien            now = 0x10000 - rec_addr;
84094536Sobrien
84189857Sobrien	  if (! ihex_write_record (abfd, now, rec_addr, 0, p))
842130561Sobrien	    return FALSE;
84333965Sjdp
84433965Sjdp	  where += now;
84533965Sjdp	  p += now;
84633965Sjdp	  count -= now;
84733965Sjdp	}
84833965Sjdp    }
84933965Sjdp
85033965Sjdp  if (abfd->start_address != 0)
85133965Sjdp    {
85233965Sjdp      bfd_vma start;
85333965Sjdp      bfd_byte startbuf[4];
85433965Sjdp
85533965Sjdp      start = abfd->start_address;
85633965Sjdp
85733965Sjdp      if (start <= 0xfffff)
85833965Sjdp	{
85933965Sjdp	  startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
86033965Sjdp	  startbuf[1] = 0;
86133965Sjdp	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
86233965Sjdp	  startbuf[3] = (bfd_byte)start & 0xff;
86333965Sjdp	  if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
864130561Sobrien	    return FALSE;
86533965Sjdp	}
86633965Sjdp      else
86733965Sjdp	{
86833965Sjdp	  startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
86933965Sjdp	  startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
87033965Sjdp	  startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
87133965Sjdp	  startbuf[3] = (bfd_byte)start & 0xff;
87233965Sjdp	  if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
873130561Sobrien	    return FALSE;
87433965Sjdp	}
87533965Sjdp    }
87633965Sjdp
87733965Sjdp  if (! ihex_write_record (abfd, 0, 0, 1, NULL))
878130561Sobrien    return FALSE;
87933965Sjdp
880130561Sobrien  return TRUE;
88133965Sjdp}
88233965Sjdp
88333965Sjdp/* Set the architecture for the output file.  The architecture is
88433965Sjdp   irrelevant, so we ignore errors about unknown architectures.  */
88533965Sjdp
886130561Sobrienstatic bfd_boolean
887218822Sdimihex_set_arch_mach (bfd *abfd,
888218822Sdim		    enum bfd_architecture arch,
889218822Sdim		    unsigned long mach)
89033965Sjdp{
89133965Sjdp  if (! bfd_default_set_arch_mach (abfd, arch, mach))
89233965Sjdp    {
89333965Sjdp      if (arch != bfd_arch_unknown)
894130561Sobrien	return FALSE;
89533965Sjdp    }
896130561Sobrien  return TRUE;
89733965Sjdp}
89833965Sjdp
89933965Sjdp/* Get the size of the headers, for the linker.  */
90033965Sjdp
90133965Sjdpstatic int
902218822Sdimihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
903218822Sdim		     struct bfd_link_info *info ATTRIBUTE_UNUSED)
90433965Sjdp{
90533965Sjdp  return 0;
90633965Sjdp}
90733965Sjdp
90833965Sjdp/* Some random definitions for the target vector.  */
90933965Sjdp
910218822Sdim#define	ihex_close_and_cleanup                    _bfd_generic_close_and_cleanup
911218822Sdim#define ihex_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
912218822Sdim#define ihex_new_section_hook                     _bfd_generic_new_section_hook
913218822Sdim#define ihex_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
914218822Sdim#define ihex_get_symtab_upper_bound               bfd_0l
915218822Sdim#define ihex_canonicalize_symtab                  ((long (*) (bfd *, asymbol **)) bfd_0l)
916218822Sdim#define ihex_make_empty_symbol                    _bfd_generic_make_empty_symbol
917218822Sdim#define ihex_print_symbol                         _bfd_nosymbols_print_symbol
918218822Sdim#define ihex_get_symbol_info                      _bfd_nosymbols_get_symbol_info
919218822Sdim#define ihex_bfd_is_target_special_symbol         ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
920218822Sdim#define ihex_bfd_is_local_label_name              _bfd_nosymbols_bfd_is_local_label_name
921218822Sdim#define ihex_get_lineno                           _bfd_nosymbols_get_lineno
922218822Sdim#define ihex_find_nearest_line                    _bfd_nosymbols_find_nearest_line
923218822Sdim#define ihex_find_inliner_info                    _bfd_nosymbols_find_inliner_info
924218822Sdim#define ihex_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
925218822Sdim#define ihex_read_minisymbols                     _bfd_nosymbols_read_minisymbols
926218822Sdim#define ihex_minisymbol_to_symbol                 _bfd_nosymbols_minisymbol_to_symbol
927218822Sdim#define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
928218822Sdim#define ihex_bfd_relax_section                    bfd_generic_relax_section
929218822Sdim#define ihex_bfd_gc_sections                      bfd_generic_gc_sections
930218822Sdim#define ihex_bfd_merge_sections                   bfd_generic_merge_sections
931218822Sdim#define ihex_bfd_is_group_section                 bfd_generic_is_group_section
932218822Sdim#define ihex_bfd_discard_group                    bfd_generic_discard_group
933218822Sdim#define ihex_section_already_linked               _bfd_generic_section_already_linked
934218822Sdim#define ihex_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
935218822Sdim#define ihex_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
936218822Sdim#define ihex_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
937218822Sdim#define ihex_bfd_link_just_syms                   _bfd_generic_link_just_syms
938218822Sdim#define ihex_bfd_final_link                       _bfd_generic_final_link
939218822Sdim#define ihex_bfd_link_split_section               _bfd_generic_link_split_section
94033965Sjdp
94133965Sjdp/* The Intel Hex target vector.  */
94233965Sjdp
94333965Sjdpconst bfd_target ihex_vec =
94433965Sjdp{
945218822Sdim  "ihex",			/* Name.  */
94633965Sjdp  bfd_target_ihex_flavour,
947218822Sdim  BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
948218822Sdim  BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
949218822Sdim  0,				/* Object flags.  */
950218822Sdim  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
951218822Sdim  0,				/* Leading underscore.  */
952218822Sdim  ' ',				/* AR_pad_char.  */
953218822Sdim  16,				/* AR_max_namelen.  */
95433965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
95533965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
956218822Sdim  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
95733965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
95833965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
959218822Sdim  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers. */
96033965Sjdp
96133965Sjdp  {
96233965Sjdp    _bfd_dummy_target,
963218822Sdim    ihex_object_p,		/* bfd_check_format.  */
96433965Sjdp    _bfd_dummy_target,
96533965Sjdp    _bfd_dummy_target,
96633965Sjdp  },
96733965Sjdp  {
96833965Sjdp    bfd_false,
96933965Sjdp    ihex_mkobject,
97033965Sjdp    _bfd_generic_mkarchive,
97133965Sjdp    bfd_false,
97233965Sjdp  },
973218822Sdim  {				/* bfd_write_contents.  */
97433965Sjdp    bfd_false,
97533965Sjdp    ihex_write_object_contents,
97633965Sjdp    _bfd_write_archive_contents,
97733965Sjdp    bfd_false,
97833965Sjdp  },
97933965Sjdp
98033965Sjdp  BFD_JUMP_TABLE_GENERIC (ihex),
98133965Sjdp  BFD_JUMP_TABLE_COPY (_bfd_generic),
98233965Sjdp  BFD_JUMP_TABLE_CORE (_bfd_nocore),
98333965Sjdp  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
98433965Sjdp  BFD_JUMP_TABLE_SYMBOLS (ihex),
985218822Sdim  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
98633965Sjdp  BFD_JUMP_TABLE_WRITE (ihex),
98733965Sjdp  BFD_JUMP_TABLE_LINK (ihex),
98833965Sjdp  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
98933965Sjdp
99060484Sobrien  NULL,
99189857Sobrien
992218822Sdim  NULL
99333965Sjdp};
994