1*fae548d3Szrj /* BFD backend for Extended Tektronix Hex Format objects.
2*fae548d3Szrj Copyright (C) 1992-2020 Free Software Foundation, Inc.
3*fae548d3Szrj Written by Steve Chamberlain of Cygnus Support <sac@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 /* SUBSECTION
24*fae548d3Szrj Tektronix Hex Format handling
25*fae548d3Szrj
26*fae548d3Szrj DESCRIPTION
27*fae548d3Szrj
28*fae548d3Szrj Tek Hex records can hold symbols and data, but not
29*fae548d3Szrj relocations. Their main application is communication with
30*fae548d3Szrj devices like PROM programmers and ICE equipment.
31*fae548d3Szrj
32*fae548d3Szrj It seems that the sections are described as being really big,
33*fae548d3Szrj the example I have says that the text section is 0..ffffffff.
34*fae548d3Szrj BFD would barf with this, many apps would try to alloc 4GB to
35*fae548d3Szrj read in the file.
36*fae548d3Szrj
37*fae548d3Szrj Tex Hex may contain many sections, but the data which comes in
38*fae548d3Szrj has no tag saying which section it belongs to, so we create
39*fae548d3Szrj one section for each block of data, called "blknnnn" which we
40*fae548d3Szrj stick all the data into.
41*fae548d3Szrj
42*fae548d3Szrj TekHex may come out of order and there is no header, so an
43*fae548d3Szrj initial scan is required to discover the minimum and maximum
44*fae548d3Szrj addresses used to create the vma and size of the sections we
45*fae548d3Szrj create.
46*fae548d3Szrj We read in the data into pages of CHUNK_MASK+1 size and read
47*fae548d3Szrj them out from that whenever we need to.
48*fae548d3Szrj
49*fae548d3Szrj Any number of sections may be created for output, we save them
50*fae548d3Szrj up and output them when it's time to close the bfd.
51*fae548d3Szrj
52*fae548d3Szrj A TekHex record looks like:
53*fae548d3Szrj EXAMPLE
54*fae548d3Szrj %<block length><type><checksum><stuff><cr>
55*fae548d3Szrj
56*fae548d3Szrj DESCRIPTION
57*fae548d3Szrj Where
58*fae548d3Szrj o length
59*fae548d3Szrj is the number of bytes in the record not including the % sign.
60*fae548d3Szrj o type
61*fae548d3Szrj is one of:
62*fae548d3Szrj 3) symbol record
63*fae548d3Szrj 6) data record
64*fae548d3Szrj 8) termination record
65*fae548d3Szrj
66*fae548d3Szrj The data can come out of order, and may be discontigous. This is a
67*fae548d3Szrj serial protocol, so big files are unlikely, so we keep a list of 8k chunks. */
68*fae548d3Szrj
69*fae548d3Szrj #include "sysdep.h"
70*fae548d3Szrj #include "bfd.h"
71*fae548d3Szrj #include "libbfd.h"
72*fae548d3Szrj #include "libiberty.h"
73*fae548d3Szrj
74*fae548d3Szrj typedef struct
75*fae548d3Szrj {
76*fae548d3Szrj bfd_vma low;
77*fae548d3Szrj bfd_vma high;
78*fae548d3Szrj } addr_range_type;
79*fae548d3Szrj
80*fae548d3Szrj typedef struct tekhex_symbol_struct
81*fae548d3Szrj {
82*fae548d3Szrj asymbol symbol;
83*fae548d3Szrj struct tekhex_symbol_struct *prev;
84*fae548d3Szrj } tekhex_symbol_type;
85*fae548d3Szrj
86*fae548d3Szrj static const char digs[] = "0123456789ABCDEF";
87*fae548d3Szrj
88*fae548d3Szrj static char sum_block[256];
89*fae548d3Szrj
90*fae548d3Szrj #define NOT_HEX 20
91*fae548d3Szrj #define NIBBLE(x) hex_value(x)
92*fae548d3Szrj #define HEX(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
93*fae548d3Szrj #define ISHEX(x) hex_p(x)
94*fae548d3Szrj #define TOHEX(d, x) \
95*fae548d3Szrj (d)[1] = digs[(x) & 0xf]; \
96*fae548d3Szrj (d)[0] = digs[((x)>>4)&0xf];
97*fae548d3Szrj
98*fae548d3Szrj /* Here's an example
99*fae548d3Szrj %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
100*fae548d3Szrj %1B3709T_SEGMENT1108FFFFFFFF
101*fae548d3Szrj %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
102*fae548d3Szrj %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
103*fae548d3Szrj %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
104*fae548d3Szrj %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
105*fae548d3Szrj %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
106*fae548d3Szrj %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
107*fae548d3Szrj %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
108*fae548d3Szrj %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
109*fae548d3Szrj %2734D9T_SEGMENT8Bvoid$t15$151035_main10
110*fae548d3Szrj %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
111*fae548d3Szrj %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
112*fae548d3Szrj %07 8 10 10
113*fae548d3Szrj
114*fae548d3Szrj explanation:
115*fae548d3Szrj %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
116*fae548d3Szrj ^ ^^ ^ ^-data
117*fae548d3Szrj | || +------ 4 char integer 0x8000
118*fae548d3Szrj | |+-------- checksum
119*fae548d3Szrj | +--------- type 6 (data record)
120*fae548d3Szrj +----------- length 3a chars
121*fae548d3Szrj <---------------------- 3a (58 chars) ------------------->
122*fae548d3Szrj
123*fae548d3Szrj %1B3709T_SEGMENT1108FFFFFFFF
124*fae548d3Szrj ^ ^^ ^- 8 character integer 0xffffffff
125*fae548d3Szrj | |+- 1 character integer 0
126*fae548d3Szrj | +-- type 1 symbol (section definition)
127*fae548d3Szrj +------------ 9 char symbol T_SEGMENT
128*fae548d3Szrj
129*fae548d3Szrj %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
130*fae548d3Szrj %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
131*fae548d3Szrj %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
132*fae548d3Szrj %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
133*fae548d3Szrj %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
134*fae548d3Szrj %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
135*fae548d3Szrj %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
136*fae548d3Szrj %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
137*fae548d3Szrj %2734D9T_SEGMENT8Bvoid$t15$151035_main10
138*fae548d3Szrj %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
139*fae548d3Szrj %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
140*fae548d3Szrj %0781010
141*fae548d3Szrj
142*fae548d3Szrj Turns into
143*fae548d3Szrj sac@thepub$ ./objdump -dx -m m68k f
144*fae548d3Szrj
145*fae548d3Szrj f: file format tekhex
146*fae548d3Szrj -----x--- 9/55728 -134219416 Sep 29 15:13 1995 f
147*fae548d3Szrj architecture: UNKNOWN!, flags 0x00000010:
148*fae548d3Szrj HAS_SYMS
149*fae548d3Szrj start address 0x00000000
150*fae548d3Szrj SECTION 0 [D00000000] : size 00020000 vma 00000000 align 2**0
151*fae548d3Szrj ALLOC, LOAD
152*fae548d3Szrj SECTION 1 [D00008000] : size 00002001 vma 00008000 align 2**0
153*fae548d3Szrj
154*fae548d3Szrj SECTION 2 [T_SEGMENT] : size ffffffff vma 00000000 align 2**0
155*fae548d3Szrj
156*fae548d3Szrj SYMBOL TABLE:
157*fae548d3Szrj 00000000 g T_SEGMENT gcc_compiled$
158*fae548d3Szrj 00000000 g T_SEGMENT hello$c
159*fae548d3Szrj 00000000 g T_SEGMENT int$t1$r1$$21474
160*fae548d3Szrj 00000000 g T_SEGMENT char$t2$r2$0$127
161*fae548d3Szrj 00000000 g T_SEGMENT long$int$t3$r1$$
162*fae548d3Szrj 00000000 g T_SEGMENT unsigned$int$t4$
163*fae548d3Szrj 00000000 g T_SEGMENT long$unsigned$in
164*fae548d3Szrj 00000000 g T_SEGMENT short$int$t6$r1$
165*fae548d3Szrj 00000000 g T_SEGMENT long$long$int$t7
166*fae548d3Szrj 00000000 g T_SEGMENT short$unsigned$i
167*fae548d3Szrj 00000000 g T_SEGMENT long$long$unsign
168*fae548d3Szrj 00000000 g T_SEGMENT signed$char$t10$
169*fae548d3Szrj 00000000 g T_SEGMENT unsigned$char$t1
170*fae548d3Szrj 00000000 g T_SEGMENT float$t12$r1$4$0
171*fae548d3Szrj 00000000 g T_SEGMENT double$t13$r1$8$
172*fae548d3Szrj 00000000 g T_SEGMENT long$double$t14$
173*fae548d3Szrj 00000000 g T_SEGMENT void$t15$15
174*fae548d3Szrj 00000000 g T_SEGMENT _main
175*fae548d3Szrj 00000000 g T_SEGMENT $
176*fae548d3Szrj 00000000 g T_SEGMENT $
177*fae548d3Szrj 00000000 g T_SEGMENT $
178*fae548d3Szrj 00000010 g T_SEGMENT $
179*fae548d3Szrj 00000000 g T_SEGMENT main$F1
180*fae548d3Szrj fcffffff g T_SEGMENT i$1
181*fae548d3Szrj 00000000 g T_SEGMENT $
182*fae548d3Szrj 00000010 g T_SEGMENT $
183*fae548d3Szrj
184*fae548d3Szrj RELOCATION RECORDS FOR [D00000000]: (none)
185*fae548d3Szrj
186*fae548d3Szrj RELOCATION RECORDS FOR [D00008000]: (none)
187*fae548d3Szrj
188*fae548d3Szrj RELOCATION RECORDS FOR [T_SEGMENT]: (none)
189*fae548d3Szrj
190*fae548d3Szrj Disassembly of section D00000000:
191*fae548d3Szrj ...
192*fae548d3Szrj 00008000 ($+)7ff0 linkw fp,#-4
193*fae548d3Szrj 00008004 ($+)7ff4 nop
194*fae548d3Szrj 00008006 ($+)7ff6 movel #99,d0
195*fae548d3Szrj 00008008 ($+)7ff8 cmpl fp@(-4),d0
196*fae548d3Szrj 0000800c ($+)7ffc blts 00008014 ($+)8004
197*fae548d3Szrj 0000800e ($+)7ffe addql #1,fp@(-4)
198*fae548d3Szrj 00008012 ($+)8002 bras 00008006 ($+)7ff6
199*fae548d3Szrj 00008014 ($+)8004 unlk fp
200*fae548d3Szrj 00008016 ($+)8006 rts
201*fae548d3Szrj ... */
202*fae548d3Szrj
203*fae548d3Szrj static void
tekhex_init(void)204*fae548d3Szrj tekhex_init (void)
205*fae548d3Szrj {
206*fae548d3Szrj unsigned int i;
207*fae548d3Szrj static bfd_boolean inited = FALSE;
208*fae548d3Szrj int val;
209*fae548d3Szrj
210*fae548d3Szrj if (! inited)
211*fae548d3Szrj {
212*fae548d3Szrj inited = TRUE;
213*fae548d3Szrj hex_init ();
214*fae548d3Szrj val = 0;
215*fae548d3Szrj for (i = 0; i < 10; i++)
216*fae548d3Szrj sum_block[i + '0'] = val++;
217*fae548d3Szrj
218*fae548d3Szrj for (i = 'A'; i <= 'Z'; i++)
219*fae548d3Szrj sum_block[i] = val++;
220*fae548d3Szrj
221*fae548d3Szrj sum_block['$'] = val++;
222*fae548d3Szrj sum_block['%'] = val++;
223*fae548d3Szrj sum_block['.'] = val++;
224*fae548d3Szrj sum_block['_'] = val++;
225*fae548d3Szrj for (i = 'a'; i <= 'z'; i++)
226*fae548d3Szrj sum_block[i] = val++;
227*fae548d3Szrj }
228*fae548d3Szrj }
229*fae548d3Szrj
230*fae548d3Szrj /* The maximum number of bytes on a line is FF. */
231*fae548d3Szrj #define MAXCHUNK 0xff
232*fae548d3Szrj /* The number of bytes we fit onto a line on output. */
233*fae548d3Szrj #define CHUNK 21
234*fae548d3Szrj
235*fae548d3Szrj /* We cannot output our tekhexords as we see them, we have to glue them
236*fae548d3Szrj together, this is done in this structure : */
237*fae548d3Szrj
238*fae548d3Szrj struct tekhex_data_list_struct
239*fae548d3Szrj {
240*fae548d3Szrj unsigned char *data;
241*fae548d3Szrj bfd_vma where;
242*fae548d3Szrj bfd_size_type size;
243*fae548d3Szrj struct tekhex_data_list_struct *next;
244*fae548d3Szrj
245*fae548d3Szrj };
246*fae548d3Szrj typedef struct tekhex_data_list_struct tekhex_data_list_type;
247*fae548d3Szrj
248*fae548d3Szrj #define CHUNK_MASK 0x1fff
249*fae548d3Szrj #define CHUNK_SPAN 32
250*fae548d3Szrj
251*fae548d3Szrj struct data_struct
252*fae548d3Szrj {
253*fae548d3Szrj unsigned char chunk_data[CHUNK_MASK + 1];
254*fae548d3Szrj unsigned char chunk_init[(CHUNK_MASK + 1 + CHUNK_SPAN - 1) / CHUNK_SPAN];
255*fae548d3Szrj bfd_vma vma;
256*fae548d3Szrj struct data_struct *next;
257*fae548d3Szrj };
258*fae548d3Szrj
259*fae548d3Szrj typedef struct tekhex_data_struct
260*fae548d3Szrj {
261*fae548d3Szrj tekhex_data_list_type *head;
262*fae548d3Szrj unsigned int type;
263*fae548d3Szrj struct tekhex_symbol_struct *symbols;
264*fae548d3Szrj struct data_struct *data;
265*fae548d3Szrj } tdata_type;
266*fae548d3Szrj
267*fae548d3Szrj #define enda(x) (x->vma + x->size)
268*fae548d3Szrj
269*fae548d3Szrj static bfd_boolean
getvalue(char ** srcp,bfd_vma * valuep,char * endp)270*fae548d3Szrj getvalue (char **srcp, bfd_vma *valuep, char * endp)
271*fae548d3Szrj {
272*fae548d3Szrj char *src = *srcp;
273*fae548d3Szrj bfd_vma value = 0;
274*fae548d3Szrj unsigned int len;
275*fae548d3Szrj
276*fae548d3Szrj if (src >= endp)
277*fae548d3Szrj return FALSE;
278*fae548d3Szrj
279*fae548d3Szrj if (!ISHEX (*src))
280*fae548d3Szrj return FALSE;
281*fae548d3Szrj
282*fae548d3Szrj len = hex_value (*src++);
283*fae548d3Szrj if (len == 0)
284*fae548d3Szrj len = 16;
285*fae548d3Szrj while (len-- && src < endp)
286*fae548d3Szrj {
287*fae548d3Szrj if (!ISHEX (*src))
288*fae548d3Szrj return FALSE;
289*fae548d3Szrj value = value << 4 | hex_value (*src++);
290*fae548d3Szrj }
291*fae548d3Szrj
292*fae548d3Szrj *srcp = src;
293*fae548d3Szrj *valuep = value;
294*fae548d3Szrj return len == -1U;
295*fae548d3Szrj }
296*fae548d3Szrj
297*fae548d3Szrj static bfd_boolean
getsym(char * dstp,char ** srcp,unsigned int * lenp,char * endp)298*fae548d3Szrj getsym (char *dstp, char **srcp, unsigned int *lenp, char * endp)
299*fae548d3Szrj {
300*fae548d3Szrj char *src = *srcp;
301*fae548d3Szrj unsigned int i;
302*fae548d3Szrj unsigned int len;
303*fae548d3Szrj
304*fae548d3Szrj if (!ISHEX (*src))
305*fae548d3Szrj return FALSE;
306*fae548d3Szrj
307*fae548d3Szrj len = hex_value (*src++);
308*fae548d3Szrj if (len == 0)
309*fae548d3Szrj len = 16;
310*fae548d3Szrj for (i = 0; i < len && (src + i) < endp; i++)
311*fae548d3Szrj dstp[i] = src[i];
312*fae548d3Szrj dstp[i] = 0;
313*fae548d3Szrj *srcp = src + i;
314*fae548d3Szrj *lenp = len;
315*fae548d3Szrj return i == len;
316*fae548d3Szrj }
317*fae548d3Szrj
318*fae548d3Szrj static struct data_struct *
find_chunk(bfd * abfd,bfd_vma vma,bfd_boolean create)319*fae548d3Szrj find_chunk (bfd *abfd, bfd_vma vma, bfd_boolean create)
320*fae548d3Szrj {
321*fae548d3Szrj struct data_struct *d = abfd->tdata.tekhex_data->data;
322*fae548d3Szrj
323*fae548d3Szrj vma &= ~CHUNK_MASK;
324*fae548d3Szrj while (d && (d->vma) != vma)
325*fae548d3Szrj d = d->next;
326*fae548d3Szrj
327*fae548d3Szrj if (!d && create)
328*fae548d3Szrj {
329*fae548d3Szrj /* No chunk for this address, so make one up. */
330*fae548d3Szrj d = (struct data_struct *)
331*fae548d3Szrj bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct));
332*fae548d3Szrj
333*fae548d3Szrj if (!d)
334*fae548d3Szrj return NULL;
335*fae548d3Szrj
336*fae548d3Szrj d->next = abfd->tdata.tekhex_data->data;
337*fae548d3Szrj d->vma = vma;
338*fae548d3Szrj abfd->tdata.tekhex_data->data = d;
339*fae548d3Szrj }
340*fae548d3Szrj return d;
341*fae548d3Szrj }
342*fae548d3Szrj
343*fae548d3Szrj static void
insert_byte(bfd * abfd,int value,bfd_vma addr)344*fae548d3Szrj insert_byte (bfd *abfd, int value, bfd_vma addr)
345*fae548d3Szrj {
346*fae548d3Szrj if (value != 0)
347*fae548d3Szrj {
348*fae548d3Szrj /* Find the chunk that this byte needs and put it in. */
349*fae548d3Szrj struct data_struct *d = find_chunk (abfd, addr, TRUE);
350*fae548d3Szrj
351*fae548d3Szrj d->chunk_data[addr & CHUNK_MASK] = value;
352*fae548d3Szrj d->chunk_init[(addr & CHUNK_MASK) / CHUNK_SPAN] = 1;
353*fae548d3Szrj }
354*fae548d3Szrj }
355*fae548d3Szrj
356*fae548d3Szrj /* The first pass is to find the names of all the sections, and see
357*fae548d3Szrj how big the data is. */
358*fae548d3Szrj
359*fae548d3Szrj static bfd_boolean
first_phase(bfd * abfd,int type,char * src,char * src_end)360*fae548d3Szrj first_phase (bfd *abfd, int type, char *src, char * src_end)
361*fae548d3Szrj {
362*fae548d3Szrj asection *section, *alt_section;
363*fae548d3Szrj unsigned int len;
364*fae548d3Szrj bfd_vma val;
365*fae548d3Szrj char sym[17]; /* A symbol can only be 16chars long. */
366*fae548d3Szrj
367*fae548d3Szrj switch (type)
368*fae548d3Szrj {
369*fae548d3Szrj case '6':
370*fae548d3Szrj /* Data record - read it and store it. */
371*fae548d3Szrj {
372*fae548d3Szrj bfd_vma addr;
373*fae548d3Szrj
374*fae548d3Szrj if (!getvalue (&src, &addr, src_end))
375*fae548d3Szrj return FALSE;
376*fae548d3Szrj
377*fae548d3Szrj while (*src && src < src_end - 1)
378*fae548d3Szrj {
379*fae548d3Szrj insert_byte (abfd, HEX (src), addr);
380*fae548d3Szrj src += 2;
381*fae548d3Szrj addr++;
382*fae548d3Szrj }
383*fae548d3Szrj return TRUE;
384*fae548d3Szrj }
385*fae548d3Szrj
386*fae548d3Szrj case '3':
387*fae548d3Szrj /* Symbol record, read the segment. */
388*fae548d3Szrj if (!getsym (sym, &src, &len, src_end))
389*fae548d3Szrj return FALSE;
390*fae548d3Szrj section = bfd_get_section_by_name (abfd, sym);
391*fae548d3Szrj if (section == NULL)
392*fae548d3Szrj {
393*fae548d3Szrj char *n = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1);
394*fae548d3Szrj
395*fae548d3Szrj if (!n)
396*fae548d3Szrj return FALSE;
397*fae548d3Szrj memcpy (n, sym, len + 1);
398*fae548d3Szrj section = bfd_make_section (abfd, n);
399*fae548d3Szrj if (section == NULL)
400*fae548d3Szrj return FALSE;
401*fae548d3Szrj }
402*fae548d3Szrj alt_section = NULL;
403*fae548d3Szrj while (src < src_end && *src)
404*fae548d3Szrj {
405*fae548d3Szrj switch (*src)
406*fae548d3Szrj {
407*fae548d3Szrj case '1': /* Section range. */
408*fae548d3Szrj src++;
409*fae548d3Szrj if (!getvalue (&src, §ion->vma, src_end))
410*fae548d3Szrj return FALSE;
411*fae548d3Szrj if (!getvalue (&src, &val, src_end))
412*fae548d3Szrj return FALSE;
413*fae548d3Szrj if (val < section->vma)
414*fae548d3Szrj val = section->vma;
415*fae548d3Szrj section->size = val - section->vma;
416*fae548d3Szrj /* PR 17512: file: objdump-s-endless-loop.tekhex.
417*fae548d3Szrj Check for overlarge section sizes. */
418*fae548d3Szrj if (section->size & 0x80000000)
419*fae548d3Szrj return FALSE;
420*fae548d3Szrj section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
421*fae548d3Szrj break;
422*fae548d3Szrj case '0':
423*fae548d3Szrj case '2':
424*fae548d3Szrj case '3':
425*fae548d3Szrj case '4':
426*fae548d3Szrj case '6':
427*fae548d3Szrj case '7':
428*fae548d3Szrj case '8':
429*fae548d3Szrj /* Symbols, add to section. */
430*fae548d3Szrj {
431*fae548d3Szrj bfd_size_type amt = sizeof (tekhex_symbol_type);
432*fae548d3Szrj tekhex_symbol_type *new_symbol = (tekhex_symbol_type *)
433*fae548d3Szrj bfd_alloc (abfd, amt);
434*fae548d3Szrj char stype = (*src);
435*fae548d3Szrj
436*fae548d3Szrj if (!new_symbol)
437*fae548d3Szrj return FALSE;
438*fae548d3Szrj new_symbol->symbol.the_bfd = abfd;
439*fae548d3Szrj src++;
440*fae548d3Szrj abfd->symcount++;
441*fae548d3Szrj abfd->flags |= HAS_SYMS;
442*fae548d3Szrj new_symbol->prev = abfd->tdata.tekhex_data->symbols;
443*fae548d3Szrj abfd->tdata.tekhex_data->symbols = new_symbol;
444*fae548d3Szrj if (!getsym (sym, &src, &len, src_end))
445*fae548d3Szrj return FALSE;
446*fae548d3Szrj new_symbol->symbol.name = (const char *)
447*fae548d3Szrj bfd_alloc (abfd, (bfd_size_type) len + 1);
448*fae548d3Szrj if (!new_symbol->symbol.name)
449*fae548d3Szrj return FALSE;
450*fae548d3Szrj memcpy ((char *) (new_symbol->symbol.name), sym, len + 1);
451*fae548d3Szrj new_symbol->symbol.section = section;
452*fae548d3Szrj if (stype <= '4')
453*fae548d3Szrj new_symbol->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
454*fae548d3Szrj else
455*fae548d3Szrj new_symbol->symbol.flags = BSF_LOCAL;
456*fae548d3Szrj if (stype == '2' || stype == '6')
457*fae548d3Szrj new_symbol->symbol.section = bfd_abs_section_ptr;
458*fae548d3Szrj else if (stype == '3' || stype == '7')
459*fae548d3Szrj {
460*fae548d3Szrj if ((section->flags & SEC_DATA) == 0)
461*fae548d3Szrj section->flags |= SEC_CODE;
462*fae548d3Szrj else
463*fae548d3Szrj {
464*fae548d3Szrj if (alt_section == NULL)
465*fae548d3Szrj alt_section
466*fae548d3Szrj = bfd_get_next_section_by_name (NULL, section);
467*fae548d3Szrj if (alt_section == NULL)
468*fae548d3Szrj alt_section = bfd_make_section_anyway_with_flags
469*fae548d3Szrj (abfd, section->name,
470*fae548d3Szrj (section->flags & ~SEC_DATA) | SEC_CODE);
471*fae548d3Szrj if (alt_section == NULL)
472*fae548d3Szrj return FALSE;
473*fae548d3Szrj new_symbol->symbol.section = alt_section;
474*fae548d3Szrj }
475*fae548d3Szrj }
476*fae548d3Szrj else if (stype == '4' || stype == '8')
477*fae548d3Szrj {
478*fae548d3Szrj if ((section->flags & SEC_CODE) == 0)
479*fae548d3Szrj section->flags |= SEC_DATA;
480*fae548d3Szrj else
481*fae548d3Szrj {
482*fae548d3Szrj if (alt_section == NULL)
483*fae548d3Szrj alt_section
484*fae548d3Szrj = bfd_get_next_section_by_name (NULL, section);
485*fae548d3Szrj if (alt_section == NULL)
486*fae548d3Szrj alt_section = bfd_make_section_anyway_with_flags
487*fae548d3Szrj (abfd, section->name,
488*fae548d3Szrj (section->flags & ~SEC_CODE) | SEC_DATA);
489*fae548d3Szrj if (alt_section == NULL)
490*fae548d3Szrj return FALSE;
491*fae548d3Szrj new_symbol->symbol.section = alt_section;
492*fae548d3Szrj }
493*fae548d3Szrj }
494*fae548d3Szrj if (!getvalue (&src, &val, src_end))
495*fae548d3Szrj return FALSE;
496*fae548d3Szrj new_symbol->symbol.value = val - section->vma;
497*fae548d3Szrj break;
498*fae548d3Szrj }
499*fae548d3Szrj default:
500*fae548d3Szrj return FALSE;
501*fae548d3Szrj }
502*fae548d3Szrj }
503*fae548d3Szrj }
504*fae548d3Szrj
505*fae548d3Szrj return TRUE;
506*fae548d3Szrj }
507*fae548d3Szrj
508*fae548d3Szrj /* Pass over a tekhex, calling one of the above functions on each
509*fae548d3Szrj record. */
510*fae548d3Szrj
511*fae548d3Szrj static bfd_boolean
pass_over(bfd * abfd,bfd_boolean (* func)(bfd *,int,char *,char *))512*fae548d3Szrj pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *, char *))
513*fae548d3Szrj {
514*fae548d3Szrj unsigned int chars_on_line;
515*fae548d3Szrj bfd_boolean is_eof = FALSE;
516*fae548d3Szrj
517*fae548d3Szrj /* To the front of the file. */
518*fae548d3Szrj if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
519*fae548d3Szrj return FALSE;
520*fae548d3Szrj
521*fae548d3Szrj while (! is_eof)
522*fae548d3Szrj {
523*fae548d3Szrj char src[MAXCHUNK];
524*fae548d3Szrj char type;
525*fae548d3Szrj
526*fae548d3Szrj /* Find first '%'. */
527*fae548d3Szrj is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
528*fae548d3Szrj while (*src != '%' && !is_eof)
529*fae548d3Szrj is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
530*fae548d3Szrj
531*fae548d3Szrj if (is_eof)
532*fae548d3Szrj break;
533*fae548d3Szrj
534*fae548d3Szrj /* Fetch the type and the length and the checksum. */
535*fae548d3Szrj if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
536*fae548d3Szrj return FALSE;
537*fae548d3Szrj
538*fae548d3Szrj type = src[2];
539*fae548d3Szrj
540*fae548d3Szrj if (!ISHEX (src[0]) || !ISHEX (src[1]))
541*fae548d3Szrj break;
542*fae548d3Szrj
543*fae548d3Szrj /* Already read five chars. */
544*fae548d3Szrj chars_on_line = HEX (src) - 5;
545*fae548d3Szrj
546*fae548d3Szrj if (chars_on_line >= MAXCHUNK)
547*fae548d3Szrj return FALSE;
548*fae548d3Szrj
549*fae548d3Szrj if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
550*fae548d3Szrj return FALSE;
551*fae548d3Szrj
552*fae548d3Szrj /* Put a null at the end. */
553*fae548d3Szrj src[chars_on_line] = 0;
554*fae548d3Szrj if (!func (abfd, type, src, src + chars_on_line))
555*fae548d3Szrj return FALSE;
556*fae548d3Szrj }
557*fae548d3Szrj
558*fae548d3Szrj return TRUE;
559*fae548d3Szrj }
560*fae548d3Szrj
561*fae548d3Szrj static long
tekhex_canonicalize_symtab(bfd * abfd,asymbol ** table)562*fae548d3Szrj tekhex_canonicalize_symtab (bfd *abfd, asymbol **table)
563*fae548d3Szrj {
564*fae548d3Szrj tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols;
565*fae548d3Szrj unsigned int c = bfd_get_symcount (abfd);
566*fae548d3Szrj
567*fae548d3Szrj table[c] = 0;
568*fae548d3Szrj while (p)
569*fae548d3Szrj {
570*fae548d3Szrj table[--c] = &(p->symbol);
571*fae548d3Szrj p = p->prev;
572*fae548d3Szrj }
573*fae548d3Szrj
574*fae548d3Szrj return bfd_get_symcount (abfd);
575*fae548d3Szrj }
576*fae548d3Szrj
577*fae548d3Szrj static long
tekhex_get_symtab_upper_bound(bfd * abfd)578*fae548d3Szrj tekhex_get_symtab_upper_bound (bfd *abfd)
579*fae548d3Szrj {
580*fae548d3Szrj return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
581*fae548d3Szrj
582*fae548d3Szrj }
583*fae548d3Szrj
584*fae548d3Szrj static bfd_boolean
tekhex_mkobject(bfd * abfd)585*fae548d3Szrj tekhex_mkobject (bfd *abfd)
586*fae548d3Szrj {
587*fae548d3Szrj tdata_type *tdata;
588*fae548d3Szrj
589*fae548d3Szrj tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type));
590*fae548d3Szrj if (!tdata)
591*fae548d3Szrj return FALSE;
592*fae548d3Szrj abfd->tdata.tekhex_data = tdata;
593*fae548d3Szrj tdata->type = 1;
594*fae548d3Szrj tdata->head = NULL;
595*fae548d3Szrj tdata->symbols = NULL;
596*fae548d3Szrj tdata->data = NULL;
597*fae548d3Szrj return TRUE;
598*fae548d3Szrj }
599*fae548d3Szrj
600*fae548d3Szrj /* Return TRUE if the file looks like it's in TekHex format. Just look
601*fae548d3Szrj for a percent sign and some hex digits. */
602*fae548d3Szrj
603*fae548d3Szrj static const bfd_target *
tekhex_object_p(bfd * abfd)604*fae548d3Szrj tekhex_object_p (bfd *abfd)
605*fae548d3Szrj {
606*fae548d3Szrj char b[4];
607*fae548d3Szrj
608*fae548d3Szrj tekhex_init ();
609*fae548d3Szrj
610*fae548d3Szrj if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
611*fae548d3Szrj || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
612*fae548d3Szrj return NULL;
613*fae548d3Szrj
614*fae548d3Szrj if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
615*fae548d3Szrj return NULL;
616*fae548d3Szrj
617*fae548d3Szrj tekhex_mkobject (abfd);
618*fae548d3Szrj
619*fae548d3Szrj if (!pass_over (abfd, first_phase))
620*fae548d3Szrj return NULL;
621*fae548d3Szrj
622*fae548d3Szrj return abfd->xvec;
623*fae548d3Szrj }
624*fae548d3Szrj
625*fae548d3Szrj static void
move_section_contents(bfd * abfd,asection * section,const void * locationp,file_ptr offset,bfd_size_type count,bfd_boolean get)626*fae548d3Szrj move_section_contents (bfd *abfd,
627*fae548d3Szrj asection *section,
628*fae548d3Szrj const void * locationp,
629*fae548d3Szrj file_ptr offset,
630*fae548d3Szrj bfd_size_type count,
631*fae548d3Szrj bfd_boolean get)
632*fae548d3Szrj {
633*fae548d3Szrj bfd_vma addr;
634*fae548d3Szrj char *location = (char *) locationp;
635*fae548d3Szrj bfd_vma prev_number = 1; /* Nothing can have this as a high bit. */
636*fae548d3Szrj struct data_struct *d = NULL;
637*fae548d3Szrj
638*fae548d3Szrj BFD_ASSERT (offset == 0);
639*fae548d3Szrj for (addr = section->vma; count != 0; count--, addr++)
640*fae548d3Szrj {
641*fae548d3Szrj /* Get high bits of address. */
642*fae548d3Szrj bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK;
643*fae548d3Szrj bfd_vma low_bits = addr & CHUNK_MASK;
644*fae548d3Szrj bfd_boolean must_write = !get && *location != 0;
645*fae548d3Szrj
646*fae548d3Szrj if (chunk_number != prev_number || (!d && must_write))
647*fae548d3Szrj {
648*fae548d3Szrj /* Different chunk, so move pointer. */
649*fae548d3Szrj d = find_chunk (abfd, chunk_number, must_write);
650*fae548d3Szrj prev_number = chunk_number;
651*fae548d3Szrj }
652*fae548d3Szrj
653*fae548d3Szrj if (get)
654*fae548d3Szrj {
655*fae548d3Szrj if (d)
656*fae548d3Szrj *location = d->chunk_data[low_bits];
657*fae548d3Szrj else
658*fae548d3Szrj *location = 0;
659*fae548d3Szrj }
660*fae548d3Szrj else if (must_write)
661*fae548d3Szrj {
662*fae548d3Szrj d->chunk_data[low_bits] = *location;
663*fae548d3Szrj d->chunk_init[low_bits / CHUNK_SPAN] = 1;
664*fae548d3Szrj }
665*fae548d3Szrj
666*fae548d3Szrj location++;
667*fae548d3Szrj }
668*fae548d3Szrj }
669*fae548d3Szrj
670*fae548d3Szrj static bfd_boolean
tekhex_get_section_contents(bfd * abfd,asection * section,void * locationp,file_ptr offset,bfd_size_type count)671*fae548d3Szrj tekhex_get_section_contents (bfd *abfd,
672*fae548d3Szrj asection *section,
673*fae548d3Szrj void * locationp,
674*fae548d3Szrj file_ptr offset,
675*fae548d3Szrj bfd_size_type count)
676*fae548d3Szrj {
677*fae548d3Szrj if (section->flags & (SEC_LOAD | SEC_ALLOC))
678*fae548d3Szrj {
679*fae548d3Szrj move_section_contents (abfd, section, locationp, offset, count, TRUE);
680*fae548d3Szrj return TRUE;
681*fae548d3Szrj }
682*fae548d3Szrj
683*fae548d3Szrj return FALSE;
684*fae548d3Szrj }
685*fae548d3Szrj
686*fae548d3Szrj static bfd_boolean
tekhex_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long machine)687*fae548d3Szrj tekhex_set_arch_mach (bfd *abfd,
688*fae548d3Szrj enum bfd_architecture arch,
689*fae548d3Szrj unsigned long machine)
690*fae548d3Szrj {
691*fae548d3Szrj /* Ignore errors about unknown architecture. */
692*fae548d3Szrj return (bfd_default_set_arch_mach (abfd, arch, machine)
693*fae548d3Szrj || arch == bfd_arch_unknown);
694*fae548d3Szrj }
695*fae548d3Szrj
696*fae548d3Szrj /* We have to save up all the Tekhexords for a splurge before output. */
697*fae548d3Szrj
698*fae548d3Szrj static bfd_boolean
tekhex_set_section_contents(bfd * abfd,sec_ptr section,const void * locationp,file_ptr offset,bfd_size_type bytes_to_do)699*fae548d3Szrj tekhex_set_section_contents (bfd *abfd,
700*fae548d3Szrj sec_ptr section,
701*fae548d3Szrj const void * locationp,
702*fae548d3Szrj file_ptr offset,
703*fae548d3Szrj bfd_size_type bytes_to_do)
704*fae548d3Szrj {
705*fae548d3Szrj if (section->flags & (SEC_LOAD | SEC_ALLOC))
706*fae548d3Szrj {
707*fae548d3Szrj move_section_contents (abfd, section, locationp, offset, bytes_to_do,
708*fae548d3Szrj FALSE);
709*fae548d3Szrj return TRUE;
710*fae548d3Szrj }
711*fae548d3Szrj
712*fae548d3Szrj return FALSE;
713*fae548d3Szrj }
714*fae548d3Szrj
715*fae548d3Szrj static void
writevalue(char ** dst,bfd_vma value)716*fae548d3Szrj writevalue (char **dst, bfd_vma value)
717*fae548d3Szrj {
718*fae548d3Szrj char *p = *dst;
719*fae548d3Szrj int len;
720*fae548d3Szrj int shift;
721*fae548d3Szrj
722*fae548d3Szrj for (len = 8, shift = 28; shift; shift -= 4, len--)
723*fae548d3Szrj {
724*fae548d3Szrj if ((value >> shift) & 0xf)
725*fae548d3Szrj {
726*fae548d3Szrj *p++ = len + '0';
727*fae548d3Szrj while (len)
728*fae548d3Szrj {
729*fae548d3Szrj *p++ = digs[(value >> shift) & 0xf];
730*fae548d3Szrj shift -= 4;
731*fae548d3Szrj len--;
732*fae548d3Szrj }
733*fae548d3Szrj *dst = p;
734*fae548d3Szrj return;
735*fae548d3Szrj
736*fae548d3Szrj }
737*fae548d3Szrj }
738*fae548d3Szrj *p++ = '1';
739*fae548d3Szrj *p++ = '0';
740*fae548d3Szrj *dst = p;
741*fae548d3Szrj }
742*fae548d3Szrj
743*fae548d3Szrj static void
writesym(char ** dst,const char * sym)744*fae548d3Szrj writesym (char **dst, const char *sym)
745*fae548d3Szrj {
746*fae548d3Szrj char *p = *dst;
747*fae548d3Szrj int len = (sym ? strlen (sym) : 0);
748*fae548d3Szrj
749*fae548d3Szrj if (len >= 16)
750*fae548d3Szrj {
751*fae548d3Szrj *p++ = '0';
752*fae548d3Szrj len = 16;
753*fae548d3Szrj }
754*fae548d3Szrj else
755*fae548d3Szrj {
756*fae548d3Szrj if (len == 0)
757*fae548d3Szrj {
758*fae548d3Szrj *p++ = '1';
759*fae548d3Szrj sym = "$";
760*fae548d3Szrj len = 1;
761*fae548d3Szrj }
762*fae548d3Szrj else
763*fae548d3Szrj *p++ = digs[len];
764*fae548d3Szrj }
765*fae548d3Szrj
766*fae548d3Szrj while (len--)
767*fae548d3Szrj *p++ = *sym++;
768*fae548d3Szrj
769*fae548d3Szrj *dst = p;
770*fae548d3Szrj }
771*fae548d3Szrj
772*fae548d3Szrj static void
out(bfd * abfd,int type,char * start,char * end)773*fae548d3Szrj out (bfd *abfd, int type, char *start, char *end)
774*fae548d3Szrj {
775*fae548d3Szrj int sum = 0;
776*fae548d3Szrj char *s;
777*fae548d3Szrj char front[6];
778*fae548d3Szrj bfd_size_type wrlen;
779*fae548d3Szrj
780*fae548d3Szrj front[0] = '%';
781*fae548d3Szrj TOHEX (front + 1, end - start + 5);
782*fae548d3Szrj front[3] = type;
783*fae548d3Szrj
784*fae548d3Szrj for (s = start; s < end; s++)
785*fae548d3Szrj sum += sum_block[(unsigned char) *s];
786*fae548d3Szrj
787*fae548d3Szrj sum += sum_block[(unsigned char) front[1]]; /* Length. */
788*fae548d3Szrj sum += sum_block[(unsigned char) front[2]];
789*fae548d3Szrj sum += sum_block[(unsigned char) front[3]]; /* Type. */
790*fae548d3Szrj TOHEX (front + 4, sum);
791*fae548d3Szrj if (bfd_bwrite (front, (bfd_size_type) 6, abfd) != 6)
792*fae548d3Szrj abort ();
793*fae548d3Szrj end[0] = '\n';
794*fae548d3Szrj wrlen = end - start + 1;
795*fae548d3Szrj if (bfd_bwrite (start, wrlen, abfd) != wrlen)
796*fae548d3Szrj abort ();
797*fae548d3Szrj }
798*fae548d3Szrj
799*fae548d3Szrj static bfd_boolean
tekhex_write_object_contents(bfd * abfd)800*fae548d3Szrj tekhex_write_object_contents (bfd *abfd)
801*fae548d3Szrj {
802*fae548d3Szrj char buffer[100];
803*fae548d3Szrj asymbol **p;
804*fae548d3Szrj asection *s;
805*fae548d3Szrj struct data_struct *d;
806*fae548d3Szrj
807*fae548d3Szrj tekhex_init ();
808*fae548d3Szrj
809*fae548d3Szrj /* And the raw data. */
810*fae548d3Szrj for (d = abfd->tdata.tekhex_data->data;
811*fae548d3Szrj d != NULL;
812*fae548d3Szrj d = d->next)
813*fae548d3Szrj {
814*fae548d3Szrj int low;
815*fae548d3Szrj int addr;
816*fae548d3Szrj
817*fae548d3Szrj /* Write it in blocks of 32 bytes. */
818*fae548d3Szrj for (addr = 0; addr < CHUNK_MASK + 1; addr += CHUNK_SPAN)
819*fae548d3Szrj {
820*fae548d3Szrj if (d->chunk_init[addr / CHUNK_SPAN])
821*fae548d3Szrj {
822*fae548d3Szrj char *dst = buffer;
823*fae548d3Szrj
824*fae548d3Szrj writevalue (&dst, addr + d->vma);
825*fae548d3Szrj for (low = 0; low < CHUNK_SPAN; low++)
826*fae548d3Szrj {
827*fae548d3Szrj TOHEX (dst, d->chunk_data[addr + low]);
828*fae548d3Szrj dst += 2;
829*fae548d3Szrj }
830*fae548d3Szrj out (abfd, '6', buffer, dst);
831*fae548d3Szrj }
832*fae548d3Szrj }
833*fae548d3Szrj }
834*fae548d3Szrj
835*fae548d3Szrj /* Write all the section headers for the sections. */
836*fae548d3Szrj for (s = abfd->sections; s != NULL; s = s->next)
837*fae548d3Szrj {
838*fae548d3Szrj char *dst = buffer;
839*fae548d3Szrj
840*fae548d3Szrj writesym (&dst, s->name);
841*fae548d3Szrj *dst++ = '1';
842*fae548d3Szrj writevalue (&dst, s->vma);
843*fae548d3Szrj writevalue (&dst, s->vma + s->size);
844*fae548d3Szrj out (abfd, '3', buffer, dst);
845*fae548d3Szrj }
846*fae548d3Szrj
847*fae548d3Szrj /* And the symbols. */
848*fae548d3Szrj if (abfd->outsymbols)
849*fae548d3Szrj {
850*fae548d3Szrj for (p = abfd->outsymbols; *p; p++)
851*fae548d3Szrj {
852*fae548d3Szrj int section_code = bfd_decode_symclass (*p);
853*fae548d3Szrj
854*fae548d3Szrj if (section_code != '?')
855*fae548d3Szrj {
856*fae548d3Szrj /* Do not include debug symbols. */
857*fae548d3Szrj asymbol *sym = *p;
858*fae548d3Szrj char *dst = buffer;
859*fae548d3Szrj
860*fae548d3Szrj writesym (&dst, sym->section->name);
861*fae548d3Szrj
862*fae548d3Szrj switch (section_code)
863*fae548d3Szrj {
864*fae548d3Szrj case 'A':
865*fae548d3Szrj *dst++ = '2';
866*fae548d3Szrj break;
867*fae548d3Szrj case 'a':
868*fae548d3Szrj *dst++ = '6';
869*fae548d3Szrj break;
870*fae548d3Szrj case 'D':
871*fae548d3Szrj case 'B':
872*fae548d3Szrj case 'O':
873*fae548d3Szrj *dst++ = '4';
874*fae548d3Szrj break;
875*fae548d3Szrj case 'd':
876*fae548d3Szrj case 'b':
877*fae548d3Szrj case 'o':
878*fae548d3Szrj *dst++ = '8';
879*fae548d3Szrj break;
880*fae548d3Szrj case 'T':
881*fae548d3Szrj *dst++ = '3';
882*fae548d3Szrj break;
883*fae548d3Szrj case 't':
884*fae548d3Szrj *dst++ = '7';
885*fae548d3Szrj break;
886*fae548d3Szrj case 'C':
887*fae548d3Szrj case 'U':
888*fae548d3Szrj bfd_set_error (bfd_error_wrong_format);
889*fae548d3Szrj return FALSE;
890*fae548d3Szrj }
891*fae548d3Szrj
892*fae548d3Szrj writesym (&dst, sym->name);
893*fae548d3Szrj writevalue (&dst, sym->value + sym->section->vma);
894*fae548d3Szrj out (abfd, '3', buffer, dst);
895*fae548d3Szrj }
896*fae548d3Szrj }
897*fae548d3Szrj }
898*fae548d3Szrj
899*fae548d3Szrj /* And the terminator. */
900*fae548d3Szrj if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9)
901*fae548d3Szrj abort ();
902*fae548d3Szrj return TRUE;
903*fae548d3Szrj }
904*fae548d3Szrj
905*fae548d3Szrj static int
tekhex_sizeof_headers(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info ATTRIBUTE_UNUSED)906*fae548d3Szrj tekhex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
907*fae548d3Szrj struct bfd_link_info *info ATTRIBUTE_UNUSED)
908*fae548d3Szrj {
909*fae548d3Szrj return 0;
910*fae548d3Szrj }
911*fae548d3Szrj
912*fae548d3Szrj static asymbol *
tekhex_make_empty_symbol(bfd * abfd)913*fae548d3Szrj tekhex_make_empty_symbol (bfd *abfd)
914*fae548d3Szrj {
915*fae548d3Szrj bfd_size_type amt = sizeof (struct tekhex_symbol_struct);
916*fae548d3Szrj tekhex_symbol_type *new_symbol = (tekhex_symbol_type *) bfd_zalloc (abfd,
917*fae548d3Szrj amt);
918*fae548d3Szrj
919*fae548d3Szrj if (!new_symbol)
920*fae548d3Szrj return NULL;
921*fae548d3Szrj new_symbol->symbol.the_bfd = abfd;
922*fae548d3Szrj new_symbol->prev = NULL;
923*fae548d3Szrj return &(new_symbol->symbol);
924*fae548d3Szrj }
925*fae548d3Szrj
926*fae548d3Szrj static void
tekhex_get_symbol_info(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol,symbol_info * ret)927*fae548d3Szrj tekhex_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
928*fae548d3Szrj asymbol *symbol,
929*fae548d3Szrj symbol_info *ret)
930*fae548d3Szrj {
931*fae548d3Szrj bfd_symbol_info (symbol, ret);
932*fae548d3Szrj }
933*fae548d3Szrj
934*fae548d3Szrj static void
tekhex_print_symbol(bfd * abfd,void * filep,asymbol * symbol,bfd_print_symbol_type how)935*fae548d3Szrj tekhex_print_symbol (bfd *abfd,
936*fae548d3Szrj void * filep,
937*fae548d3Szrj asymbol *symbol,
938*fae548d3Szrj bfd_print_symbol_type how)
939*fae548d3Szrj {
940*fae548d3Szrj FILE *file = (FILE *) filep;
941*fae548d3Szrj
942*fae548d3Szrj switch (how)
943*fae548d3Szrj {
944*fae548d3Szrj case bfd_print_symbol_name:
945*fae548d3Szrj fprintf (file, "%s", symbol->name);
946*fae548d3Szrj break;
947*fae548d3Szrj case bfd_print_symbol_more:
948*fae548d3Szrj break;
949*fae548d3Szrj
950*fae548d3Szrj case bfd_print_symbol_all:
951*fae548d3Szrj {
952*fae548d3Szrj const char *section_name = symbol->section->name;
953*fae548d3Szrj
954*fae548d3Szrj bfd_print_symbol_vandf (abfd, (void *) file, symbol);
955*fae548d3Szrj
956*fae548d3Szrj fprintf (file, " %-5s %s",
957*fae548d3Szrj section_name, symbol->name);
958*fae548d3Szrj }
959*fae548d3Szrj }
960*fae548d3Szrj }
961*fae548d3Szrj
962*fae548d3Szrj #define tekhex_close_and_cleanup _bfd_generic_close_and_cleanup
963*fae548d3Szrj #define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
964*fae548d3Szrj #define tekhex_new_section_hook _bfd_generic_new_section_hook
965*fae548d3Szrj #define tekhex_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
966*fae548d3Szrj #define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name
967*fae548d3Szrj #define tekhex_get_lineno _bfd_nosymbols_get_lineno
968*fae548d3Szrj #define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line
969*fae548d3Szrj #define tekhex_find_line _bfd_nosymbols_find_line
970*fae548d3Szrj #define tekhex_find_inliner_info _bfd_nosymbols_find_inliner_info
971*fae548d3Szrj #define tekhex_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string
972*fae548d3Szrj #define tekhex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
973*fae548d3Szrj #define tekhex_read_minisymbols _bfd_generic_read_minisymbols
974*fae548d3Szrj #define tekhex_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
975*fae548d3Szrj #define tekhex_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
976*fae548d3Szrj #define tekhex_bfd_relax_section bfd_generic_relax_section
977*fae548d3Szrj #define tekhex_bfd_gc_sections bfd_generic_gc_sections
978*fae548d3Szrj #define tekhex_bfd_lookup_section_flags bfd_generic_lookup_section_flags
979*fae548d3Szrj #define tekhex_bfd_merge_sections bfd_generic_merge_sections
980*fae548d3Szrj #define tekhex_bfd_is_group_section bfd_generic_is_group_section
981*fae548d3Szrj #define tekhex_bfd_group_name bfd_generic_group_name
982*fae548d3Szrj #define tekhex_bfd_discard_group bfd_generic_discard_group
983*fae548d3Szrj #define tekhex_section_already_linked _bfd_generic_section_already_linked
984*fae548d3Szrj #define tekhex_bfd_define_common_symbol bfd_generic_define_common_symbol
985*fae548d3Szrj #define tekhex_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
986*fae548d3Szrj #define tekhex_bfd_define_start_stop bfd_generic_define_start_stop
987*fae548d3Szrj #define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
988*fae548d3Szrj #define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols
989*fae548d3Szrj #define tekhex_bfd_link_just_syms _bfd_generic_link_just_syms
990*fae548d3Szrj #define tekhex_bfd_copy_link_hash_symbol_type _bfd_generic_copy_link_hash_symbol_type
991*fae548d3Szrj #define tekhex_bfd_final_link _bfd_generic_final_link
992*fae548d3Szrj #define tekhex_bfd_link_split_section _bfd_generic_link_split_section
993*fae548d3Szrj #define tekhex_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
994*fae548d3Szrj #define tekhex_bfd_link_check_relocs _bfd_generic_link_check_relocs
995*fae548d3Szrj
996*fae548d3Szrj const bfd_target tekhex_vec =
997*fae548d3Szrj {
998*fae548d3Szrj "tekhex", /* Name. */
999*fae548d3Szrj bfd_target_tekhex_flavour,
1000*fae548d3Szrj BFD_ENDIAN_UNKNOWN, /* Target byte order. */
1001*fae548d3Szrj BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
1002*fae548d3Szrj (EXEC_P | /* Object flags. */
1003*fae548d3Szrj HAS_SYMS | HAS_LINENO | HAS_DEBUG |
1004*fae548d3Szrj HAS_RELOC | HAS_LOCALS | WP_TEXT | D_PAGED),
1005*fae548d3Szrj (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1006*fae548d3Szrj | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
1007*fae548d3Szrj 0, /* Leading underscore. */
1008*fae548d3Szrj ' ', /* AR_pad_char. */
1009*fae548d3Szrj 16, /* AR_max_namelen. */
1010*fae548d3Szrj 0, /* match priority. */
1011*fae548d3Szrj bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1012*fae548d3Szrj bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1013*fae548d3Szrj bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
1014*fae548d3Szrj bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1015*fae548d3Szrj bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1016*fae548d3Szrj bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
1017*fae548d3Szrj
1018*fae548d3Szrj {
1019*fae548d3Szrj _bfd_dummy_target,
1020*fae548d3Szrj tekhex_object_p, /* bfd_check_format. */
1021*fae548d3Szrj _bfd_dummy_target,
1022*fae548d3Szrj _bfd_dummy_target,
1023*fae548d3Szrj },
1024*fae548d3Szrj {
1025*fae548d3Szrj _bfd_bool_bfd_false_error,
1026*fae548d3Szrj tekhex_mkobject,
1027*fae548d3Szrj _bfd_generic_mkarchive,
1028*fae548d3Szrj _bfd_bool_bfd_false_error,
1029*fae548d3Szrj },
1030*fae548d3Szrj { /* bfd_write_contents. */
1031*fae548d3Szrj _bfd_bool_bfd_false_error,
1032*fae548d3Szrj tekhex_write_object_contents,
1033*fae548d3Szrj _bfd_write_archive_contents,
1034*fae548d3Szrj _bfd_bool_bfd_false_error,
1035*fae548d3Szrj },
1036*fae548d3Szrj
1037*fae548d3Szrj BFD_JUMP_TABLE_GENERIC (tekhex),
1038*fae548d3Szrj BFD_JUMP_TABLE_COPY (_bfd_generic),
1039*fae548d3Szrj BFD_JUMP_TABLE_CORE (_bfd_nocore),
1040*fae548d3Szrj BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1041*fae548d3Szrj BFD_JUMP_TABLE_SYMBOLS (tekhex),
1042*fae548d3Szrj BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1043*fae548d3Szrj BFD_JUMP_TABLE_WRITE (tekhex),
1044*fae548d3Szrj BFD_JUMP_TABLE_LINK (tekhex),
1045*fae548d3Szrj BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1046*fae548d3Szrj
1047*fae548d3Szrj NULL,
1048*fae548d3Szrj
1049*fae548d3Szrj NULL
1050*fae548d3Szrj };
1051