133965Sjdp/* BFD backend for Extended Tektronix Hex Format  objects.
2218822Sdim   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
3218822Sdim   2003, 2004, 2007 Free Software Foundation, Inc.
433965Sjdp   Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
533965Sjdp
6218822Sdim   This file is part of BFD, the Binary File Descriptor library.
733965Sjdp
8218822Sdim   This program is free software; you can redistribute it and/or modify
9218822Sdim   it under the terms of the GNU General Public License as published by
10218822Sdim   the Free Software Foundation; either version 2 of the License, or
11218822Sdim   (at your option) any later version.
1233965Sjdp
13218822Sdim   This program is distributed in the hope that it will be useful,
14218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
15218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16218822Sdim   GNU General Public License for more details.
1733965Sjdp
18218822Sdim   You should have received a copy of the GNU General Public License
19218822Sdim   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
22218822Sdim/* SUBSECTION
2333965Sjdp	Tektronix Hex Format handling
2433965Sjdp
25218822Sdim   DESCRIPTION
2677298Sobrien
2733965Sjdp	Tek Hex records can hold symbols and data, but not
2833965Sjdp	relocations. Their main application is communication with
2933965Sjdp	devices like PROM programmers and ICE equipment.
3077298Sobrien
31130561Sobrien	It seems that the sections are described as being really big,
3233965Sjdp        the example I have says that the text section is 0..ffffffff.
3333965Sjdp	BFD would barf with this, many apps would try to alloc 4GB to
3433965Sjdp	read in the file.
3533965Sjdp
3633965Sjdp	Tex Hex may contain many sections, but the data which comes in
3733965Sjdp	has no tag saying which section it belongs to, so we create
3833965Sjdp	one section for each block of data, called "blknnnn" which we
3933965Sjdp	stick all the data into.
4033965Sjdp
4133965Sjdp	TekHex may come out of 	order and there is no header, so an
4233965Sjdp	initial scan is required  to discover the minimum and maximum
4333965Sjdp	addresses used to create the vma and size of the sections we
4433965Sjdp	create.
4533965Sjdp	We read in the data into pages of CHUNK_MASK+1 size and read
4633965Sjdp	them out from that whenever we need to.
4733965Sjdp
4833965Sjdp	Any number of sections may be created for output, we save them
4933965Sjdp	up and output them when it's time to close the bfd.
5033965Sjdp
5133965Sjdp	A TekHex record looks like:
52218822Sdim  EXAMPLE
5333965Sjdp	%<block length><type><checksum><stuff><cr>
5477298Sobrien
55218822Sdim  DESCRIPTION
5633965Sjdp	Where
5733965Sjdp	o length
5833965Sjdp	is the number of bytes in the record not including the % sign.
5933965Sjdp	o type
6033965Sjdp	is one of:
6133965Sjdp	3) symbol record
6233965Sjdp	6) data record
6333965Sjdp	8) termination record
6433965Sjdp
65218822Sdim  The data can come out of order, and may be discontigous. This is a
66218822Sdim  serial protocol, so big files are unlikely, so we keep a list of 8k chunks.  */
6733965Sjdp
68218822Sdim#include "sysdep.h"
6933965Sjdp#include "bfd.h"
7033965Sjdp#include "libbfd.h"
7133965Sjdp#include "libiberty.h"
7233965Sjdp
7333965Sjdptypedef struct
74218822Sdim{
75218822Sdim  bfd_vma low;
76218822Sdim  bfd_vma high;
77218822Sdim} addr_range_type;
7833965Sjdp
7933965Sjdptypedef struct tekhex_symbol_struct
80218822Sdim{
81218822Sdim  asymbol symbol;
82218822Sdim  struct tekhex_symbol_struct *prev;
83218822Sdim} tekhex_symbol_type;
8433965Sjdp
8533965Sjdpstatic const char digs[] = "0123456789ABCDEF";
8633965Sjdp
8733965Sjdpstatic char sum_block[256];
8833965Sjdp
89218822Sdim#define NOT_HEX      20
90218822Sdim#define NIBBLE(x)    hex_value(x)
91218822Sdim#define HEX(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
92218822Sdim#define	ISHEX(x)    hex_p(x)
93218822Sdim#define TOHEX(d, x) \
94218822Sdim  (d)[1] = digs[(x) & 0xf]; \
95218822Sdim  (d)[0] = digs[((x)>>4)&0xf];
9633965Sjdp
97218822Sdim/* Here's an example
98218822Sdim   %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
99218822Sdim   %1B3709T_SEGMENT1108FFFFFFFF
100218822Sdim   %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
101218822Sdim   %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
102218822Sdim   %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
103218822Sdim   %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
104218822Sdim   %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
105218822Sdim   %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
106218822Sdim   %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
107218822Sdim   %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
108218822Sdim   %2734D9T_SEGMENT8Bvoid$t15$151035_main10
109218822Sdim   %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
110218822Sdim   %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
111218822Sdim   %07 8 10 10
11233965Sjdp
113218822Sdim   explanation:
114218822Sdim   %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
115218822Sdim    ^ ^^ ^     ^-data
116218822Sdim    | || +------ 4 char integer 0x8000
117218822Sdim    | |+-------- checksum
118218822Sdim    | +--------- type 6 (data record)
119218822Sdim    +----------- length 3a chars
120218822Sdim   <---------------------- 3a (58 chars) ------------------->
12133965Sjdp
122218822Sdim   %1B3709T_SEGMENT1108FFFFFFFF
123218822Sdim         ^         ^^ ^- 8 character integer 0xffffffff
124218822Sdim         |         |+-   1 character integer 0
125218822Sdim         |         +--   type 1 symbol (section definition)
126218822Sdim         +------------   9 char symbol T_SEGMENT
12733965Sjdp
128218822Sdim   %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
129218822Sdim   %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
130218822Sdim   %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
131218822Sdim   %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
132218822Sdim   %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
133218822Sdim   %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
134218822Sdim   %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
135218822Sdim   %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
136218822Sdim   %2734D9T_SEGMENT8Bvoid$t15$151035_main10
137218822Sdim   %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
138218822Sdim   %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
139218822Sdim   %0781010
14033965Sjdp
141218822Sdim   Turns into
142218822Sdim   sac@thepub$ ./objdump -dx -m m68k f
14333965Sjdp
144218822Sdim   f:     file format tekhex
145218822Sdim   -----x--- 9/55728 -134219416 Sep 29 15:13 1995 f
146218822Sdim   architecture: UNKNOWN!, flags 0x00000010:
147218822Sdim   HAS_SYMS
148218822Sdim   start address 0x00000000
149218822Sdim   SECTION 0 [D00000000]	: size 00020000 vma 00000000 align 2**0
150218822Sdim   ALLOC, LOAD
151218822Sdim   SECTION 1 [D00008000]	: size 00002001 vma 00008000 align 2**0
15233965Sjdp
153218822Sdim   SECTION 2 [T_SEGMENT]	: size ffffffff vma 00000000 align 2**0
15433965Sjdp
155218822Sdim   SYMBOL TABLE:
156218822Sdim   00000000  g       T_SEGMENT gcc_compiled$
157218822Sdim   00000000  g       T_SEGMENT hello$c
158218822Sdim   00000000  g       T_SEGMENT int$t1$r1$$21474
159218822Sdim   00000000  g       T_SEGMENT char$t2$r2$0$127
160218822Sdim   00000000  g       T_SEGMENT long$int$t3$r1$$
161218822Sdim   00000000  g       T_SEGMENT unsigned$int$t4$
162218822Sdim   00000000  g       T_SEGMENT long$unsigned$in
163218822Sdim   00000000  g       T_SEGMENT short$int$t6$r1$
164218822Sdim   00000000  g       T_SEGMENT long$long$int$t7
165218822Sdim   00000000  g       T_SEGMENT short$unsigned$i
166218822Sdim   00000000  g       T_SEGMENT long$long$unsign
167218822Sdim   00000000  g       T_SEGMENT signed$char$t10$
168218822Sdim   00000000  g       T_SEGMENT unsigned$char$t1
169218822Sdim   00000000  g       T_SEGMENT float$t12$r1$4$0
170218822Sdim   00000000  g       T_SEGMENT double$t13$r1$8$
171218822Sdim   00000000  g       T_SEGMENT long$double$t14$
172218822Sdim   00000000  g       T_SEGMENT void$t15$15
173218822Sdim   00000000  g       T_SEGMENT _main
174218822Sdim   00000000  g       T_SEGMENT $
175218822Sdim   00000000  g       T_SEGMENT $
176218822Sdim   00000000  g       T_SEGMENT $
177218822Sdim   00000010  g       T_SEGMENT $
178218822Sdim   00000000  g       T_SEGMENT main$F1
179218822Sdim   fcffffff  g       T_SEGMENT i$1
180218822Sdim   00000000  g       T_SEGMENT $
181218822Sdim   00000010  g       T_SEGMENT $
18233965Sjdp
183218822Sdim   RELOCATION RECORDS FOR [D00000000]: (none)
18433965Sjdp
185218822Sdim   RELOCATION RECORDS FOR [D00008000]: (none)
18633965Sjdp
187218822Sdim   RELOCATION RECORDS FOR [T_SEGMENT]: (none)
18833965Sjdp
189218822Sdim   Disassembly of section D00000000:
190218822Sdim   ...
191218822Sdim   00008000 ($+)7ff0 linkw fp,#-4
192218822Sdim   00008004 ($+)7ff4 nop
193218822Sdim   00008006 ($+)7ff6 movel #99,d0
194218822Sdim   00008008 ($+)7ff8 cmpl fp@(-4),d0
195218822Sdim   0000800c ($+)7ffc blts 00008014 ($+)8004
196218822Sdim   0000800e ($+)7ffe addql #1,fp@(-4)
197218822Sdim   00008012 ($+)8002 bras 00008006 ($+)7ff6
198218822Sdim   00008014 ($+)8004 unlk fp
199218822Sdim   00008016 ($+)8006 rts
200218822Sdim   ...  */
20133965Sjdp
20233965Sjdpstatic void
203218822Sdimtekhex_init (void)
20433965Sjdp{
20533965Sjdp  unsigned int i;
206130561Sobrien  static bfd_boolean inited = FALSE;
20733965Sjdp  int val;
20833965Sjdp
209104834Sobrien  if (! inited)
21033965Sjdp    {
211130561Sobrien      inited = TRUE;
21233965Sjdp      hex_init ();
21333965Sjdp      val = 0;
21433965Sjdp      for (i = 0; i < 10; i++)
215218822Sdim	sum_block[i + '0'] = val++;
216218822Sdim
21733965Sjdp      for (i = 'A'; i <= 'Z'; i++)
218218822Sdim	sum_block[i] = val++;
219218822Sdim
22033965Sjdp      sum_block['$'] = val++;
22133965Sjdp      sum_block['%'] = val++;
22233965Sjdp      sum_block['.'] = val++;
22333965Sjdp      sum_block['_'] = val++;
22433965Sjdp      for (i = 'a'; i <= 'z'; i++)
225218822Sdim	sum_block[i] = val++;
22633965Sjdp    }
22733965Sjdp}
22833965Sjdp
229218822Sdim/* The maximum number of bytes on a line is FF.  */
23033965Sjdp#define MAXCHUNK 0xff
231218822Sdim/* The number of bytes we fit onto a line on output.  */
23233965Sjdp#define CHUNK 21
23333965Sjdp
23433965Sjdp/* We cannot output our tekhexords as we see them, we have to glue them
23533965Sjdp   together, this is done in this structure : */
23633965Sjdp
23733965Sjdpstruct tekhex_data_list_struct
23833965Sjdp{
23933965Sjdp  unsigned char *data;
24033965Sjdp  bfd_vma where;
24133965Sjdp  bfd_size_type size;
24233965Sjdp  struct tekhex_data_list_struct *next;
24333965Sjdp
24433965Sjdp};
24533965Sjdptypedef struct tekhex_data_list_struct tekhex_data_list_type;
24633965Sjdp
24733965Sjdp#define CHUNK_MASK 0x1fff
24833965Sjdp
24933965Sjdpstruct data_struct
250218822Sdim{
251218822Sdim  char chunk_data[CHUNK_MASK + 1];
252218822Sdim  char chunk_init[CHUNK_MASK + 1];
253218822Sdim  bfd_vma vma;
254218822Sdim  struct data_struct *next;
255218822Sdim};
25633965Sjdp
25733965Sjdptypedef struct tekhex_data_struct
25833965Sjdp{
25933965Sjdp  tekhex_data_list_type *head;
26033965Sjdp  unsigned int type;
26133965Sjdp  struct tekhex_symbol_struct *symbols;
26233965Sjdp  struct data_struct *data;
26333965Sjdp} tdata_type;
26433965Sjdp
26533965Sjdp#define enda(x) (x->vma + x->size)
26633965Sjdp
267218822Sdimstatic bfd_boolean
268218822Sdimgetvalue (char **srcp, bfd_vma *valuep)
26933965Sjdp{
27033965Sjdp  char *src = *srcp;
27133965Sjdp  bfd_vma value = 0;
272218822Sdim  unsigned int len;
27333965Sjdp
274218822Sdim  if (!ISHEX (*src))
275218822Sdim    return FALSE;
276218822Sdim
277218822Sdim  len = hex_value (*src++);
27833965Sjdp  if (len == 0)
27933965Sjdp    len = 16;
28033965Sjdp  while (len--)
28133965Sjdp    {
282218822Sdim      if (!ISHEX (*src))
283218822Sdim	return FALSE;
284218822Sdim      value = value << 4 | hex_value (*src++);
28533965Sjdp    }
286218822Sdim
28733965Sjdp  *srcp = src;
288218822Sdim  *valuep = value;
289218822Sdim  return TRUE;
29033965Sjdp}
29133965Sjdp
292218822Sdimstatic bfd_boolean
293218822Sdimgetsym (char *dstp, char **srcp, unsigned int *lenp)
29433965Sjdp{
29533965Sjdp  char *src = *srcp;
29633965Sjdp  unsigned int i;
297218822Sdim  unsigned int len;
298218822Sdim
299218822Sdim  if (!ISHEX (*src))
300218822Sdim    return FALSE;
30133965Sjdp
302218822Sdim  len = hex_value (*src++);
30333965Sjdp  if (len == 0)
30433965Sjdp    len = 16;
30533965Sjdp  for (i = 0; i < len; i++)
30633965Sjdp    dstp[i] = src[i];
30733965Sjdp  dstp[i] = 0;
30833965Sjdp  *srcp = src + i;
309218822Sdim  *lenp = len;
310218822Sdim  return TRUE;
31133965Sjdp}
31233965Sjdp
31333965Sjdpstatic struct data_struct *
314218822Sdimfind_chunk (bfd *abfd, bfd_vma vma)
31533965Sjdp{
31633965Sjdp  struct data_struct *d = abfd->tdata.tekhex_data->data;
31733965Sjdp
31833965Sjdp  vma &= ~CHUNK_MASK;
31933965Sjdp  while (d && (d->vma) != vma)
320218822Sdim    d = d->next;
321218822Sdim
32233965Sjdp  if (!d)
32333965Sjdp    {
324218822Sdim      /* No chunk for this address, so make one up.  */
325218822Sdim      d = bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct));
32633965Sjdp
327104834Sobrien      if (!d)
32833965Sjdp	return NULL;
32933965Sjdp
33033965Sjdp      d->next = abfd->tdata.tekhex_data->data;
33133965Sjdp      d->vma = vma;
33233965Sjdp      abfd->tdata.tekhex_data->data = d;
33333965Sjdp    }
33433965Sjdp  return d;
33533965Sjdp}
33633965Sjdp
33733965Sjdpstatic void
338218822Sdiminsert_byte (bfd *abfd, int value, bfd_vma addr)
33933965Sjdp{
340218822Sdim  /* Find the chunk that this byte needs and put it in.  */
34133965Sjdp  struct data_struct *d = find_chunk (abfd, addr);
34233965Sjdp
34333965Sjdp  d->chunk_data[addr & CHUNK_MASK] = value;
34433965Sjdp  d->chunk_init[addr & CHUNK_MASK] = 1;
34533965Sjdp}
34633965Sjdp
34733965Sjdp/* The first pass is to find the names of all the sections, and see
348218822Sdim  how big the data is.  */
349218822Sdim
350218822Sdimstatic bfd_boolean
351218822Sdimfirst_phase (bfd *abfd, int type, char *src)
35233965Sjdp{
35333965Sjdp  asection *section = bfd_abs_section_ptr;
35489857Sobrien  unsigned int len;
355218822Sdim  bfd_vma val;
356218822Sdim  char sym[17];			/* A symbol can only be 16chars long.  */
35733965Sjdp
35833965Sjdp  switch (type)
35933965Sjdp    {
36033965Sjdp    case '6':
361218822Sdim      /* Data record - read it and store it.  */
36233965Sjdp      {
363218822Sdim	bfd_vma addr;
36433965Sjdp
365218822Sdim	if (!getvalue (&src, &addr))
366218822Sdim	  return FALSE;
367218822Sdim
36833965Sjdp	while (*src)
36933965Sjdp	  {
37033965Sjdp	    insert_byte (abfd, HEX (src), addr);
37133965Sjdp	    src += 2;
37233965Sjdp	    addr++;
37333965Sjdp	  }
37433965Sjdp      }
37533965Sjdp
376218822Sdim      return TRUE;
37733965Sjdp    case '3':
378218822Sdim      /* Symbol record, read the segment.  */
379218822Sdim      if (!getsym (sym, &src, &len))
380218822Sdim	return FALSE;
38133965Sjdp      section = bfd_get_section_by_name (abfd, sym);
382218822Sdim      if (section == NULL)
38333965Sjdp	{
38489857Sobrien	  char *n = bfd_alloc (abfd, (bfd_size_type) len + 1);
38533965Sjdp
38633965Sjdp	  if (!n)
387218822Sdim	    return FALSE;
38833965Sjdp	  memcpy (n, sym, len + 1);
38933965Sjdp	  section = bfd_make_section (abfd, n);
39033965Sjdp	}
39133965Sjdp      while (*src)
39233965Sjdp	{
39333965Sjdp	  switch (*src)
39433965Sjdp	    {
395218822Sdim	    case '1':		/* Section range.  */
39633965Sjdp	      src++;
397218822Sdim	      if (!getvalue (&src, &section->vma))
398218822Sdim		return FALSE;
399218822Sdim	      if (!getvalue (&src, &val))
400218822Sdim		return FALSE;
401218822Sdim	      section->size = val - section->vma;
40233965Sjdp	      section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
40333965Sjdp	      break;
40433965Sjdp	    case '0':
40533965Sjdp	    case '2':
40633965Sjdp	    case '3':
40733965Sjdp	    case '4':
40833965Sjdp	    case '6':
40933965Sjdp	    case '7':
41033965Sjdp	    case '8':
411218822Sdim	      /* Symbols, add to section.  */
41233965Sjdp	      {
41389857Sobrien		bfd_size_type amt = sizeof (tekhex_symbol_type);
414218822Sdim		tekhex_symbol_type *new = bfd_alloc (abfd, amt);
41589857Sobrien		char stype = (*src);
41633965Sjdp
41733965Sjdp		if (!new)
418218822Sdim		  return FALSE;
41933965Sjdp		new->symbol.the_bfd = abfd;
42033965Sjdp		src++;
42133965Sjdp		abfd->symcount++;
42233965Sjdp		abfd->flags |= HAS_SYMS;
42333965Sjdp		new->prev = abfd->tdata.tekhex_data->symbols;
42433965Sjdp		abfd->tdata.tekhex_data->symbols = new;
425218822Sdim		if (!getsym (sym, &src, &len))
426218822Sdim		  return FALSE;
42789857Sobrien		new->symbol.name = bfd_alloc (abfd, (bfd_size_type) len + 1);
42833965Sjdp		if (!new->symbol.name)
429218822Sdim		  return FALSE;
43033965Sjdp		memcpy ((char *) (new->symbol.name), sym, len + 1);
43133965Sjdp		new->symbol.section = section;
43289857Sobrien		if (stype <= '4')
43333965Sjdp		  new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
43433965Sjdp		else
43533965Sjdp		  new->symbol.flags = BSF_LOCAL;
436218822Sdim		if (!getvalue (&src, &val))
437218822Sdim		  return FALSE;
438218822Sdim		new->symbol.value = val - section->vma;
439218822Sdim		break;
44033965Sjdp	      }
441218822Sdim	    default:
442218822Sdim	      return FALSE;
44333965Sjdp	    }
44433965Sjdp	}
44533965Sjdp    }
446218822Sdim
447218822Sdim  return TRUE;
44833965Sjdp}
44933965Sjdp
450130561Sobrien/* Pass over a tekhex, calling one of the above functions on each
45133965Sjdp   record.  */
45233965Sjdp
453218822Sdimstatic bfd_boolean
454218822Sdimpass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *))
45533965Sjdp{
45633965Sjdp  unsigned int chars_on_line;
457130561Sobrien  bfd_boolean eof = FALSE;
45833965Sjdp
459218822Sdim  /* To the front of the file.  */
46033965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
461218822Sdim    return FALSE;
462104834Sobrien  while (! eof)
46333965Sjdp    {
464218822Sdim      char src[MAXCHUNK];
46533965Sjdp      char type;
46633965Sjdp
467218822Sdim      /* Find first '%'.  */
468130561Sobrien      eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
46933965Sjdp      while (*src != '%' && !eof)
470218822Sdim	eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
471218822Sdim
47233965Sjdp      if (eof)
47333965Sjdp	break;
47433965Sjdp
475218822Sdim      /* Fetch the type and the length and the checksum.  */
47689857Sobrien      if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
477218822Sdim	return FALSE;
47833965Sjdp
47933965Sjdp      type = src[2];
48033965Sjdp
48133965Sjdp      if (!ISHEX (src[0]) || !ISHEX (src[1]))
48233965Sjdp	break;
48333965Sjdp
484218822Sdim      /* Already read five chars.  */
485218822Sdim      chars_on_line = HEX (src) - 5;
48633965Sjdp
487218822Sdim      if (chars_on_line >= MAXCHUNK)
488218822Sdim	return FALSE;
489218822Sdim
49089857Sobrien      if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
491218822Sdim	return FALSE;
49233965Sjdp
493218822Sdim      /* Put a null at the end.  */
494218822Sdim      src[chars_on_line] = 0;
495218822Sdim
496218822Sdim      if (!func (abfd, type, src))
497218822Sdim	return FALSE;
49833965Sjdp    }
49933965Sjdp
500218822Sdim  return TRUE;
50133965Sjdp}
50233965Sjdp
50333965Sjdpstatic long
504218822Sdimtekhex_canonicalize_symtab (bfd *abfd, asymbol **table)
50533965Sjdp{
50633965Sjdp  tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols;
50733965Sjdp  unsigned int c = bfd_get_symcount (abfd);
50833965Sjdp
50933965Sjdp  table[c] = 0;
51033965Sjdp  while (p)
51133965Sjdp    {
51233965Sjdp      table[--c] = &(p->symbol);
51333965Sjdp      p = p->prev;
51433965Sjdp    }
51533965Sjdp
51633965Sjdp  return bfd_get_symcount (abfd);
51733965Sjdp}
51833965Sjdp
51933965Sjdpstatic long
520218822Sdimtekhex_get_symtab_upper_bound (bfd *abfd)
52133965Sjdp{
52233965Sjdp  return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
52333965Sjdp
52433965Sjdp}
52533965Sjdp
526130561Sobrienstatic bfd_boolean
527218822Sdimtekhex_mkobject (bfd *abfd)
52833965Sjdp{
52989857Sobrien  tdata_type *tdata;
53033965Sjdp
531218822Sdim  tdata = bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type));
53233965Sjdp  if (!tdata)
533130561Sobrien    return FALSE;
53433965Sjdp  abfd->tdata.tekhex_data = tdata;
53533965Sjdp  tdata->type = 1;
536218822Sdim  tdata->head =  NULL;
537218822Sdim  tdata->symbols = NULL;
538218822Sdim  tdata->data = NULL;
539130561Sobrien  return TRUE;
54033965Sjdp}
54133965Sjdp
542218822Sdim/* Return TRUE if the file looks like it's in TekHex format. Just look
543218822Sdim   for a percent sign and some hex digits.  */
54433965Sjdp
54533965Sjdpstatic const bfd_target *
546218822Sdimtekhex_object_p (bfd *abfd)
54733965Sjdp{
54833965Sjdp  char b[4];
54933965Sjdp
55033965Sjdp  tekhex_init ();
55133965Sjdp
55233965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
55389857Sobrien      || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
55433965Sjdp    return NULL;
55533965Sjdp
55633965Sjdp  if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
557218822Sdim    return NULL;
55833965Sjdp
55933965Sjdp  tekhex_mkobject (abfd);
56033965Sjdp
561218822Sdim  if (!pass_over (abfd, first_phase))
562218822Sdim    return NULL;
563218822Sdim
56433965Sjdp  return abfd->xvec;
56533965Sjdp}
56633965Sjdp
56733965Sjdpstatic void
568218822Sdimmove_section_contents (bfd *abfd,
569218822Sdim		       asection *section,
570218822Sdim		       const void * locationp,
571218822Sdim		       file_ptr offset,
572218822Sdim		       bfd_size_type count,
573218822Sdim		       bfd_boolean get)
57433965Sjdp{
57533965Sjdp  bfd_vma addr;
57633965Sjdp  char *location = (char *) locationp;
577218822Sdim  bfd_vma prev_number = 1;	/* Nothing can have this as a high bit.  */
578218822Sdim  struct data_struct *d = NULL;
57933965Sjdp
58089857Sobrien  BFD_ASSERT (offset == 0);
58133965Sjdp  for (addr = section->vma; count != 0; count--, addr++)
58233965Sjdp    {
58389857Sobrien      /* Get high bits of address.  */
58489857Sobrien      bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK;
58533965Sjdp      bfd_vma low_bits = addr & CHUNK_MASK;
58633965Sjdp
58733965Sjdp      if (chunk_number != prev_number)
588218822Sdim	/* Different chunk, so move pointer. */
589218822Sdim	d = find_chunk (abfd, chunk_number);
59033965Sjdp
59133965Sjdp      if (get)
59233965Sjdp	{
59333965Sjdp	  if (d->chunk_init[low_bits])
594218822Sdim	    *location = d->chunk_data[low_bits];
59533965Sjdp	  else
596218822Sdim	    *location = 0;
59733965Sjdp	}
59833965Sjdp      else
59933965Sjdp	{
60033965Sjdp	  d->chunk_data[low_bits] = *location;
60133965Sjdp	  d->chunk_init[low_bits] = (*location != 0);
60233965Sjdp	}
60333965Sjdp
60433965Sjdp      location++;
60533965Sjdp    }
60633965Sjdp}
60733965Sjdp
608130561Sobrienstatic bfd_boolean
609218822Sdimtekhex_get_section_contents (bfd *abfd,
610218822Sdim			     asection *section,
611218822Sdim			     void * locationp,
612218822Sdim			     file_ptr offset,
613218822Sdim			     bfd_size_type count)
61433965Sjdp{
61533965Sjdp  if (section->flags & (SEC_LOAD | SEC_ALLOC))
61633965Sjdp    {
617130561Sobrien      move_section_contents (abfd, section, locationp, offset, count, TRUE);
618130561Sobrien      return TRUE;
61933965Sjdp    }
620218822Sdim
621218822Sdim  return FALSE;
62233965Sjdp}
62333965Sjdp
624130561Sobrienstatic bfd_boolean
625218822Sdimtekhex_set_arch_mach (bfd *abfd,
626218822Sdim		      enum bfd_architecture arch,
627218822Sdim		      unsigned long machine)
62833965Sjdp{
62933965Sjdp  return bfd_default_set_arch_mach (abfd, arch, machine);
63033965Sjdp}
63133965Sjdp
632218822Sdim/* We have to save up all the Tekhexords for a splurge before output.  */
63333965Sjdp
634130561Sobrienstatic bfd_boolean
635218822Sdimtekhex_set_section_contents (bfd *abfd,
636218822Sdim			     sec_ptr section,
637218822Sdim			     const void * locationp,
638218822Sdim			     file_ptr offset,
639218822Sdim			     bfd_size_type bytes_to_do)
64033965Sjdp{
641104834Sobrien  if (! abfd->output_has_begun)
64233965Sjdp    {
643218822Sdim      /* The first time around, allocate enough sections to hold all the chunks.  */
64433965Sjdp      asection *s = abfd->sections;
64533965Sjdp      bfd_vma vma;
64633965Sjdp
64733965Sjdp      for (s = abfd->sections; s; s = s->next)
64833965Sjdp	{
64933965Sjdp	  if (s->flags & SEC_LOAD)
65033965Sjdp	    {
65189857Sobrien	      for (vma = s->vma & ~(bfd_vma) CHUNK_MASK;
652218822Sdim		   vma < s->vma + s->size;
65333965Sjdp		   vma += CHUNK_MASK)
65433965Sjdp		find_chunk (abfd, vma);
65533965Sjdp	    }
65633965Sjdp	}
657218822Sdim    }
65833965Sjdp
65933965Sjdp  if (section->flags & (SEC_LOAD | SEC_ALLOC))
66033965Sjdp    {
66189857Sobrien      move_section_contents (abfd, section, locationp, offset, bytes_to_do,
662130561Sobrien			     FALSE);
663130561Sobrien      return TRUE;
66433965Sjdp    }
66533965Sjdp
666218822Sdim  return FALSE;
66733965Sjdp}
66833965Sjdp
66933965Sjdpstatic void
670218822Sdimwritevalue (char **dst, bfd_vma value)
67133965Sjdp{
67233965Sjdp  char *p = *dst;
67333965Sjdp  int len;
67433965Sjdp  int shift;
67533965Sjdp
67633965Sjdp  for (len = 8, shift = 28; shift; shift -= 4, len--)
67733965Sjdp    {
67833965Sjdp      if ((value >> shift) & 0xf)
67933965Sjdp	{
68033965Sjdp	  *p++ = len + '0';
68133965Sjdp	  while (len)
68233965Sjdp	    {
68333965Sjdp	      *p++ = digs[(value >> shift) & 0xf];
68433965Sjdp	      shift -= 4;
68533965Sjdp	      len--;
68633965Sjdp	    }
68733965Sjdp	  *dst = p;
68833965Sjdp	  return;
68933965Sjdp
69033965Sjdp	}
69133965Sjdp    }
69233965Sjdp  *p++ = '1';
69333965Sjdp  *p++ = '0';
69433965Sjdp  *dst = p;
69533965Sjdp}
69633965Sjdp
69733965Sjdpstatic void
698218822Sdimwritesym (char **dst, const char *sym)
69933965Sjdp{
70033965Sjdp  char *p = *dst;
70133965Sjdp  int len = (sym ? strlen (sym) : 0);
70233965Sjdp
70333965Sjdp  if (len >= 16)
70433965Sjdp    {
70533965Sjdp      *p++ = '0';
70633965Sjdp      len = 16;
70733965Sjdp    }
70833965Sjdp  else
70933965Sjdp    {
71033965Sjdp      if (len == 0)
71133965Sjdp	{
71233965Sjdp	  *p++ = '1';
71333965Sjdp	  sym = "$";
71433965Sjdp	  len = 1;
71533965Sjdp	}
71633965Sjdp      else
717218822Sdim	*p++ = digs[len];
71833965Sjdp    }
71933965Sjdp
72033965Sjdp  while (len--)
721218822Sdim    *p++ = *sym++;
722218822Sdim
72333965Sjdp  *dst = p;
72433965Sjdp}
72533965Sjdp
72633965Sjdpstatic void
727218822Sdimout (bfd *abfd, int type, char *start, char *end)
72833965Sjdp{
72933965Sjdp  int sum = 0;
73033965Sjdp  char *s;
73133965Sjdp  char front[6];
73233965Sjdp  bfd_size_type wrlen;
73333965Sjdp
73433965Sjdp  front[0] = '%';
73533965Sjdp  TOHEX (front + 1, end - start + 5);
73633965Sjdp  front[3] = type;
73733965Sjdp
73833965Sjdp  for (s = start; s < end; s++)
739218822Sdim    sum += sum_block[(unsigned char) *s];
74033965Sjdp
741218822Sdim  sum += sum_block[(unsigned char) front[1]];	/* Length.  */
74233965Sjdp  sum += sum_block[(unsigned char) front[2]];
743218822Sdim  sum += sum_block[(unsigned char) front[3]];	/* Type.  */
74433965Sjdp  TOHEX (front + 4, sum);
74589857Sobrien  if (bfd_bwrite (front, (bfd_size_type) 6, abfd) != 6)
74633965Sjdp    abort ();
74733965Sjdp  end[0] = '\n';
74833965Sjdp  wrlen = end - start + 1;
74989857Sobrien  if (bfd_bwrite (start, wrlen, abfd) != wrlen)
75033965Sjdp    abort ();
75133965Sjdp}
75233965Sjdp
753130561Sobrienstatic bfd_boolean
754218822Sdimtekhex_write_object_contents (bfd *abfd)
75533965Sjdp{
75633965Sjdp  char buffer[100];
75733965Sjdp  asymbol **p;
75833965Sjdp  asection *s;
75933965Sjdp  struct data_struct *d;
76033965Sjdp
76138889Sjdp  tekhex_init ();
76238889Sjdp
763218822Sdim  /* And the raw data.  */
76433965Sjdp  for (d = abfd->tdata.tekhex_data->data;
765218822Sdim       d != NULL;
76633965Sjdp       d = d->next)
76733965Sjdp    {
76833965Sjdp      int low;
76933965Sjdp
77089857Sobrien      const int span = 32;
77133965Sjdp      int addr;
77233965Sjdp
773218822Sdim      /* Write it in blocks of 32 bytes.  */
77433965Sjdp      for (addr = 0; addr < CHUNK_MASK + 1; addr += span)
77533965Sjdp	{
77633965Sjdp	  int need = 0;
77733965Sjdp
778218822Sdim	  /* Check to see if necessary.  */
77933965Sjdp	  for (low = 0; !need && low < span; low++)
780218822Sdim	    if (d->chunk_init[addr + low])
781218822Sdim	      need = 1;
782218822Sdim
78333965Sjdp	  if (need)
78433965Sjdp	    {
78533965Sjdp	      char *dst = buffer;
78633965Sjdp
78733965Sjdp	      writevalue (&dst, addr + d->vma);
78833965Sjdp	      for (low = 0; low < span; low++)
78933965Sjdp		{
79033965Sjdp		  TOHEX (dst, d->chunk_data[addr + low]);
79133965Sjdp		  dst += 2;
79233965Sjdp		}
79333965Sjdp	      out (abfd, '6', buffer, dst);
79433965Sjdp	    }
79533965Sjdp	}
79633965Sjdp    }
797218822Sdim
798218822Sdim  /* Write all the section headers for the sections.  */
799218822Sdim  for (s = abfd->sections; s != NULL; s = s->next)
80033965Sjdp    {
80133965Sjdp      char *dst = buffer;
80233965Sjdp
80333965Sjdp      writesym (&dst, s->name);
80433965Sjdp      *dst++ = '1';
80533965Sjdp      writevalue (&dst, s->vma);
806218822Sdim      writevalue (&dst, s->vma + s->size);
80733965Sjdp      out (abfd, '3', buffer, dst);
80833965Sjdp    }
80933965Sjdp
810218822Sdim  /* And the symbols.  */
81138889Sjdp  if (abfd->outsymbols)
81233965Sjdp    {
81338889Sjdp      for (p = abfd->outsymbols; *p; p++)
81438889Sjdp	{
81538889Sjdp	  int section_code = bfd_decode_symclass (*p);
81633965Sjdp
81738889Sjdp	  if (section_code != '?')
818218822Sdim	    {
819218822Sdim	      /* Do not include debug symbols.  */
82089857Sobrien	      asymbol *sym = *p;
82138889Sjdp	      char *dst = buffer;
82233965Sjdp
82389857Sobrien	      writesym (&dst, sym->section->name);
82433965Sjdp
82538889Sjdp	      switch (section_code)
82638889Sjdp		{
82738889Sjdp		case 'A':
82838889Sjdp		  *dst++ = '2';
82938889Sjdp		  break;
83038889Sjdp		case 'a':
83138889Sjdp		  *dst++ = '6';
83238889Sjdp		  break;
83338889Sjdp		case 'D':
83438889Sjdp		case 'B':
83538889Sjdp		case 'O':
83638889Sjdp		  *dst++ = '4';
83738889Sjdp		  break;
83838889Sjdp		case 'd':
83938889Sjdp		case 'b':
84038889Sjdp		case 'o':
84138889Sjdp		  *dst++ = '8';
84238889Sjdp		  break;
84338889Sjdp		case 'T':
84438889Sjdp		  *dst++ = '3';
84538889Sjdp		  break;
84638889Sjdp		case 't':
84738889Sjdp		  *dst++ = '7';
84838889Sjdp		  break;
84938889Sjdp		case 'C':
85038889Sjdp		case 'U':
85138889Sjdp		  bfd_set_error (bfd_error_wrong_format);
852130561Sobrien		  return FALSE;
85338889Sjdp		}
85438889Sjdp
85589857Sobrien	      writesym (&dst, sym->name);
85689857Sobrien	      writevalue (&dst, sym->value + sym->section->vma);
85738889Sjdp	      out (abfd, '3', buffer, dst);
85833965Sjdp	    }
85933965Sjdp	}
86033965Sjdp    }
86133965Sjdp
862218822Sdim  /* And the terminator.  */
86389857Sobrien  if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9)
86433965Sjdp    abort ();
865130561Sobrien  return TRUE;
86633965Sjdp}
86733965Sjdp
86833965Sjdpstatic int
869218822Sdimtekhex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
870218822Sdim		       struct bfd_link_info *info ATTRIBUTE_UNUSED)
87133965Sjdp{
87233965Sjdp  return 0;
87333965Sjdp}
87433965Sjdp
87533965Sjdpstatic asymbol *
876218822Sdimtekhex_make_empty_symbol (bfd *abfd)
87733965Sjdp{
87889857Sobrien  bfd_size_type amt = sizeof (struct tekhex_symbol_struct);
879218822Sdim  tekhex_symbol_type *new = bfd_zalloc (abfd, amt);
88033965Sjdp
88133965Sjdp  if (!new)
88233965Sjdp    return NULL;
88333965Sjdp  new->symbol.the_bfd = abfd;
884218822Sdim  new->prev =  NULL;
88533965Sjdp  return &(new->symbol);
88633965Sjdp}
88733965Sjdp
88833965Sjdpstatic void
889218822Sdimtekhex_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
890218822Sdim			asymbol *symbol,
891218822Sdim			symbol_info *ret)
89233965Sjdp{
89333965Sjdp  bfd_symbol_info (symbol, ret);
89433965Sjdp}
89533965Sjdp
89633965Sjdpstatic void
897218822Sdimtekhex_print_symbol (bfd *abfd,
898218822Sdim		     void * filep,
899218822Sdim		     asymbol *symbol,
900218822Sdim		     bfd_print_symbol_type how)
90133965Sjdp{
90233965Sjdp  FILE *file = (FILE *) filep;
90333965Sjdp
90433965Sjdp  switch (how)
90533965Sjdp    {
90633965Sjdp    case bfd_print_symbol_name:
90733965Sjdp      fprintf (file, "%s", symbol->name);
90833965Sjdp      break;
90933965Sjdp    case bfd_print_symbol_more:
91033965Sjdp      break;
91133965Sjdp
91233965Sjdp    case bfd_print_symbol_all:
91333965Sjdp      {
91489857Sobrien	const char *section_name = symbol->section->name;
91533965Sjdp
916218822Sdim	bfd_print_symbol_vandf (abfd, (void *) file, symbol);
91733965Sjdp
91833965Sjdp	fprintf (file, " %-5s %s",
919218822Sdim		 section_name, symbol->name);
92033965Sjdp      }
92133965Sjdp    }
92233965Sjdp}
92333965Sjdp
924218822Sdim#define	tekhex_close_and_cleanup                    _bfd_generic_close_and_cleanup
925218822Sdim#define tekhex_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
926218822Sdim#define tekhex_new_section_hook                     _bfd_generic_new_section_hook
927218822Sdim#define tekhex_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
928218822Sdim#define tekhex_bfd_is_local_label_name               bfd_generic_is_local_label_name
929218822Sdim#define tekhex_get_lineno                           _bfd_nosymbols_get_lineno
930218822Sdim#define tekhex_find_nearest_line                    _bfd_nosymbols_find_nearest_line
931218822Sdim#define tekhex_find_inliner_info                    _bfd_nosymbols_find_inliner_info
932218822Sdim#define tekhex_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
933218822Sdim#define tekhex_read_minisymbols                     _bfd_generic_read_minisymbols
934218822Sdim#define tekhex_minisymbol_to_symbol                 _bfd_generic_minisymbol_to_symbol
935218822Sdim#define tekhex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
936218822Sdim#define tekhex_bfd_relax_section                    bfd_generic_relax_section
937218822Sdim#define tekhex_bfd_gc_sections                      bfd_generic_gc_sections
938218822Sdim#define tekhex_bfd_merge_sections                   bfd_generic_merge_sections
939218822Sdim#define tekhex_bfd_is_group_section                 bfd_generic_is_group_section
940218822Sdim#define tekhex_bfd_discard_group                    bfd_generic_discard_group
941218822Sdim#define tekhex_section_already_linked               _bfd_generic_section_already_linked
942218822Sdim#define tekhex_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
943218822Sdim#define tekhex_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
944218822Sdim#define tekhex_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
945218822Sdim#define tekhex_bfd_link_just_syms                   _bfd_generic_link_just_syms
946218822Sdim#define tekhex_bfd_final_link                       _bfd_generic_final_link
947218822Sdim#define tekhex_bfd_link_split_section               _bfd_generic_link_split_section
948218822Sdim#define tekhex_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
94933965Sjdp
95033965Sjdpconst bfd_target tekhex_vec =
95133965Sjdp{
952218822Sdim  "tekhex",			/* Name.  */
95333965Sjdp  bfd_target_tekhex_flavour,
954218822Sdim  BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
955218822Sdim  BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
956218822Sdim  (EXEC_P |			/* Object flags.  */
957218822Sdim   HAS_SYMS | HAS_LINENO | HAS_DEBUG |
958218822Sdim   HAS_RELOC | HAS_LOCALS | WP_TEXT | D_PAGED),
95933965Sjdp  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
960218822Sdim   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
961218822Sdim  0,				/* Leading underscore.  */
962218822Sdim  ' ',				/* AR_pad_char.  */
963218822Sdim  16,				/* AR_max_namelen.  */
96433965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
96533965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
966218822Sdim  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
96733965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
96833965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
969218822Sdim  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers.  */
97033965Sjdp
97133965Sjdp  {
97233965Sjdp    _bfd_dummy_target,
973218822Sdim    tekhex_object_p,		/* bfd_check_format.  */
97433965Sjdp    _bfd_dummy_target,
97533965Sjdp    _bfd_dummy_target,
97633965Sjdp  },
97733965Sjdp  {
97833965Sjdp    bfd_false,
97933965Sjdp    tekhex_mkobject,
98033965Sjdp    _bfd_generic_mkarchive,
98133965Sjdp    bfd_false,
98233965Sjdp  },
983218822Sdim  {				/* bfd_write_contents.  */
98433965Sjdp    bfd_false,
98533965Sjdp    tekhex_write_object_contents,
98633965Sjdp    _bfd_write_archive_contents,
98733965Sjdp    bfd_false,
98833965Sjdp  },
98933965Sjdp
99033965Sjdp  BFD_JUMP_TABLE_GENERIC (tekhex),
99133965Sjdp  BFD_JUMP_TABLE_COPY (_bfd_generic),
99233965Sjdp  BFD_JUMP_TABLE_CORE (_bfd_nocore),
99333965Sjdp  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
99433965Sjdp  BFD_JUMP_TABLE_SYMBOLS (tekhex),
99533965Sjdp  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
99633965Sjdp  BFD_JUMP_TABLE_WRITE (tekhex),
99733965Sjdp  BFD_JUMP_TABLE_LINK (tekhex),
99833965Sjdp  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
99933965Sjdp
100060484Sobrien  NULL,
100177298Sobrien
1002218822Sdim  NULL
100333965Sjdp};
1004