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