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