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