12159047fSniklas /* BFD backend for Extended Tektronix Hex Format objects.
2007c2a45Smiod Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003
3b305b0f1Sespie Free Software Foundation, Inc.
42159047fSniklas Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
52159047fSniklas
62159047fSniklas This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
212159047fSniklas
222159047fSniklas /*
232159047fSniklas SUBSECTION
242159047fSniklas Tektronix Hex Format handling
252159047fSniklas
262159047fSniklas DESCRIPTION
272159047fSniklas
282159047fSniklas Tek Hex records can hold symbols and data, but not
292159047fSniklas relocations. Their main application is communication with
302159047fSniklas devices like PROM programmers and ICE equipment.
312159047fSniklas
32007c2a45Smiod It seems that the sections are described as being really big,
332159047fSniklas the example I have says that the text section is 0..ffffffff.
342159047fSniklas BFD would barf with this, many apps would try to alloc 4GB to
352159047fSniklas read in the file.
362159047fSniklas
372159047fSniklas Tex Hex may contain many sections, but the data which comes in
382159047fSniklas has no tag saying which section it belongs to, so we create
392159047fSniklas one section for each block of data, called "blknnnn" which we
402159047fSniklas stick all the data into.
412159047fSniklas
422159047fSniklas TekHex may come out of order and there is no header, so an
432159047fSniklas initial scan is required to discover the minimum and maximum
442159047fSniklas addresses used to create the vma and size of the sections we
452159047fSniklas create.
462159047fSniklas We read in the data into pages of CHUNK_MASK+1 size and read
472159047fSniklas them out from that whenever we need to.
482159047fSniklas
492159047fSniklas Any number of sections may be created for output, we save them
502159047fSniklas up and output them when it's time to close the bfd.
512159047fSniklas
522159047fSniklas A TekHex record looks like:
532159047fSniklas EXAMPLE
542159047fSniklas %<block length><type><checksum><stuff><cr>
552159047fSniklas
562159047fSniklas DESCRIPTION
572159047fSniklas Where
582159047fSniklas o length
592159047fSniklas is the number of bytes in the record not including the % sign.
602159047fSniklas o type
612159047fSniklas is one of:
622159047fSniklas 3) symbol record
632159047fSniklas 6) data record
642159047fSniklas 8) termination record
652159047fSniklas
662159047fSniklas The data can come out of order, and may be discontigous. This is a
672159047fSniklas serial protocol, so big files are unlikely, so we keep a list of 8k chunks
682159047fSniklas */
692159047fSniklas
702159047fSniklas #include "bfd.h"
712159047fSniklas #include "sysdep.h"
722159047fSniklas #include "libbfd.h"
732159047fSniklas #include "libiberty.h"
742159047fSniklas
752159047fSniklas typedef struct
762159047fSniklas {
772159047fSniklas bfd_vma low;
782159047fSniklas bfd_vma high;
792159047fSniklas } addr_range_type;
802159047fSniklas
812159047fSniklas typedef struct tekhex_symbol_struct
822159047fSniklas {
832159047fSniklas
842159047fSniklas asymbol symbol;
852159047fSniklas struct tekhex_symbol_struct *prev;
862159047fSniklas
872159047fSniklas } tekhex_symbol_type;
882159047fSniklas
892159047fSniklas static const char digs[] = "0123456789ABCDEF";
902159047fSniklas
912159047fSniklas static char sum_block[256];
922159047fSniklas
932159047fSniklas #define NOT_HEX 20
942159047fSniklas #define NIBBLE(x) hex_value(x)
952159047fSniklas #define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
962159047fSniklas #define TOHEX(d,x) \
972159047fSniklas (d)[1] = digs[(x) & 0xf]; \
982159047fSniklas (d)[0] = digs[((x)>>4)&0xf];
992159047fSniklas #define ISHEX(x) hex_p(x)
1002159047fSniklas
101b305b0f1Sespie static void tekhex_init PARAMS ((void));
102*68302bafSotto static bfd_boolean getvalue PARAMS ((char **, bfd_vma *));
103e93f7393Sniklas static void tekhex_print_symbol
104e93f7393Sniklas PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
105e93f7393Sniklas static void tekhex_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
106e93f7393Sniklas static asymbol *tekhex_make_empty_symbol PARAMS ((bfd *));
107c074d1c9Sdrahn static int tekhex_sizeof_headers PARAMS ((bfd *, bfd_boolean));
108c074d1c9Sdrahn static bfd_boolean tekhex_write_object_contents PARAMS ((bfd *));
109e93f7393Sniklas static void out PARAMS ((bfd *, int, char *, char *));
110c074d1c9Sdrahn static void writesym PARAMS ((char **, const char *));
111e93f7393Sniklas static void writevalue PARAMS ((char **, bfd_vma));
112c074d1c9Sdrahn static bfd_boolean tekhex_set_section_contents
113007c2a45Smiod PARAMS ((bfd*, sec_ptr, const PTR, file_ptr, bfd_size_type));
114c074d1c9Sdrahn static bfd_boolean tekhex_set_arch_mach
115e93f7393Sniklas PARAMS ((bfd *, enum bfd_architecture, unsigned long));
116c074d1c9Sdrahn static bfd_boolean tekhex_get_section_contents
117e93f7393Sniklas PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
118e93f7393Sniklas static void move_section_contents
119007c2a45Smiod PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type, bfd_boolean));
120e93f7393Sniklas static const bfd_target *tekhex_object_p PARAMS ((bfd *));
121c074d1c9Sdrahn static bfd_boolean tekhex_mkobject PARAMS ((bfd *));
122e93f7393Sniklas static long tekhex_get_symtab_upper_bound PARAMS ((bfd *));
123007c2a45Smiod static long tekhex_canonicalize_symtab PARAMS ((bfd *, asymbol **));
124*68302bafSotto static bfd_boolean pass_over PARAMS ((bfd *, bfd_boolean (*) (bfd*, int, char *)));
125*68302bafSotto static bfd_boolean first_phase PARAMS ((bfd *, int, char *));
126e93f7393Sniklas static void insert_byte PARAMS ((bfd *, int, bfd_vma));
127e93f7393Sniklas static struct data_struct *find_chunk PARAMS ((bfd *, bfd_vma));
128*68302bafSotto static bfd_boolean getsym PARAMS ((char *, char **, unsigned int *));
129e93f7393Sniklas
1302159047fSniklas /*
1312159047fSniklas Here's an example
1322159047fSniklas %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
1332159047fSniklas %1B3709T_SEGMENT1108FFFFFFFF
1342159047fSniklas %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
1352159047fSniklas %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
1362159047fSniklas %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
1372159047fSniklas %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
1382159047fSniklas %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
1392159047fSniklas %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
1402159047fSniklas %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
1412159047fSniklas %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
1422159047fSniklas %2734D9T_SEGMENT8Bvoid$t15$151035_main10
1432159047fSniklas %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
1442159047fSniklas %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
1452159047fSniklas %07 8 10 10
1462159047fSniklas
1472159047fSniklas explanation:
1482159047fSniklas %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
1492159047fSniklas ^ ^^ ^ ^-data
1502159047fSniklas | || +------ 4 char integer 0x8000
1512159047fSniklas | |+-------- checksum
1522159047fSniklas | +--------- type 6 (data record)
1532159047fSniklas +----------- length 3a chars
1542159047fSniklas <---------------------- 3a (58 chars) ------------------->
1552159047fSniklas
1562159047fSniklas %1B3709T_SEGMENT1108FFFFFFFF
1572159047fSniklas ^ ^^ ^- 8 character integer 0xffffffff
1582159047fSniklas | |+- 1 character integer 0
1592159047fSniklas | +-- type 1 symbol (section definition)
1602159047fSniklas +------------ 9 char symbol T_SEGMENT
1612159047fSniklas
1622159047fSniklas %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
1632159047fSniklas %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
1642159047fSniklas %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
1652159047fSniklas %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
1662159047fSniklas %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
1672159047fSniklas %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
1682159047fSniklas %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
1692159047fSniklas %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
1702159047fSniklas %2734D9T_SEGMENT8Bvoid$t15$151035_main10
1712159047fSniklas %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
1722159047fSniklas %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
1732159047fSniklas %0781010
1742159047fSniklas
1752159047fSniklas Turns into
1762159047fSniklas sac@thepub$ ./objdump -dx -m m68k f
1772159047fSniklas
1782159047fSniklas f: file format tekhex
1792159047fSniklas -----x--- 9/55728 -134219416 Sep 29 15:13 1995 f
1802159047fSniklas architecture: UNKNOWN!, flags 0x00000010:
1812159047fSniklas HAS_SYMS
1822159047fSniklas start address 0x00000000
1832159047fSniklas SECTION 0 [D00000000] : size 00020000 vma 00000000 align 2**0
1842159047fSniklas ALLOC, LOAD
1852159047fSniklas SECTION 1 [D00008000] : size 00002001 vma 00008000 align 2**0
1862159047fSniklas
1872159047fSniklas SECTION 2 [T_SEGMENT] : size ffffffff vma 00000000 align 2**0
1882159047fSniklas
1892159047fSniklas SYMBOL TABLE:
1902159047fSniklas 00000000 g T_SEGMENT gcc_compiled$
1912159047fSniklas 00000000 g T_SEGMENT hello$c
1922159047fSniklas 00000000 g T_SEGMENT int$t1$r1$$21474
1932159047fSniklas 00000000 g T_SEGMENT char$t2$r2$0$127
1942159047fSniklas 00000000 g T_SEGMENT long$int$t3$r1$$
1952159047fSniklas 00000000 g T_SEGMENT unsigned$int$t4$
1962159047fSniklas 00000000 g T_SEGMENT long$unsigned$in
1972159047fSniklas 00000000 g T_SEGMENT short$int$t6$r1$
1982159047fSniklas 00000000 g T_SEGMENT long$long$int$t7
1992159047fSniklas 00000000 g T_SEGMENT short$unsigned$i
2002159047fSniklas 00000000 g T_SEGMENT long$long$unsign
2012159047fSniklas 00000000 g T_SEGMENT signed$char$t10$
2022159047fSniklas 00000000 g T_SEGMENT unsigned$char$t1
2032159047fSniklas 00000000 g T_SEGMENT float$t12$r1$4$0
2042159047fSniklas 00000000 g T_SEGMENT double$t13$r1$8$
2052159047fSniklas 00000000 g T_SEGMENT long$double$t14$
2062159047fSniklas 00000000 g T_SEGMENT void$t15$15
2072159047fSniklas 00000000 g T_SEGMENT _main
2082159047fSniklas 00000000 g T_SEGMENT $
2092159047fSniklas 00000000 g T_SEGMENT $
2102159047fSniklas 00000000 g T_SEGMENT $
2112159047fSniklas 00000010 g T_SEGMENT $
2122159047fSniklas 00000000 g T_SEGMENT main$F1
2132159047fSniklas fcffffff g T_SEGMENT i$1
2142159047fSniklas 00000000 g T_SEGMENT $
2152159047fSniklas 00000010 g T_SEGMENT $
2162159047fSniklas
2172159047fSniklas RELOCATION RECORDS FOR [D00000000]: (none)
2182159047fSniklas
2192159047fSniklas RELOCATION RECORDS FOR [D00008000]: (none)
2202159047fSniklas
2212159047fSniklas RELOCATION RECORDS FOR [T_SEGMENT]: (none)
2222159047fSniklas
2232159047fSniklas Disassembly of section D00000000:
2242159047fSniklas ...
2252159047fSniklas 00008000 ($+)7ff0 linkw fp,#-4
2262159047fSniklas 00008004 ($+)7ff4 nop
2272159047fSniklas 00008006 ($+)7ff6 movel #99,d0
2282159047fSniklas 00008008 ($+)7ff8 cmpl fp@(-4),d0
2292159047fSniklas 0000800c ($+)7ffc blts 00008014 ($+)8004
2302159047fSniklas 0000800e ($+)7ffe addql #1,fp@(-4)
2312159047fSniklas 00008012 ($+)8002 bras 00008006 ($+)7ff6
2322159047fSniklas 00008014 ($+)8004 unlk fp
2332159047fSniklas 00008016 ($+)8006 rts
2342159047fSniklas ...
2352159047fSniklas
2362159047fSniklas */
2372159047fSniklas
2382159047fSniklas static void
tekhex_init()2392159047fSniklas tekhex_init ()
2402159047fSniklas {
2412159047fSniklas unsigned int i;
242c074d1c9Sdrahn static bfd_boolean inited = FALSE;
2432159047fSniklas int val;
2442159047fSniklas
245c074d1c9Sdrahn if (! inited)
2462159047fSniklas {
247c074d1c9Sdrahn inited = TRUE;
2482159047fSniklas hex_init ();
2492159047fSniklas val = 0;
2502159047fSniklas for (i = 0; i < 10; i++)
2512159047fSniklas {
2522159047fSniklas sum_block[i + '0'] = val++;
2532159047fSniklas }
2542159047fSniklas for (i = 'A'; i <= 'Z'; i++)
2552159047fSniklas {
2562159047fSniklas sum_block[i] = val++;
2572159047fSniklas }
2582159047fSniklas sum_block['$'] = val++;
2592159047fSniklas sum_block['%'] = val++;
2602159047fSniklas sum_block['.'] = val++;
2612159047fSniklas sum_block['_'] = val++;
2622159047fSniklas for (i = 'a'; i <= 'z'; i++)
2632159047fSniklas {
2642159047fSniklas sum_block[i] = val++;
2652159047fSniklas }
2662159047fSniklas }
2672159047fSniklas }
2682159047fSniklas
2692159047fSniklas /* The maximum number of bytes on a line is FF */
2702159047fSniklas #define MAXCHUNK 0xff
2712159047fSniklas /* The number of bytes we fit onto a line on output */
2722159047fSniklas #define CHUNK 21
2732159047fSniklas
2742159047fSniklas /* We cannot output our tekhexords as we see them, we have to glue them
2752159047fSniklas together, this is done in this structure : */
2762159047fSniklas
2772159047fSniklas struct tekhex_data_list_struct
2782159047fSniklas {
2792159047fSniklas unsigned char *data;
2802159047fSniklas bfd_vma where;
2812159047fSniklas bfd_size_type size;
2822159047fSniklas struct tekhex_data_list_struct *next;
2832159047fSniklas
2842159047fSniklas };
2852159047fSniklas typedef struct tekhex_data_list_struct tekhex_data_list_type;
2862159047fSniklas
2872159047fSniklas #define CHUNK_MASK 0x1fff
2882159047fSniklas
2892159047fSniklas struct data_struct
2902159047fSniklas {
2912159047fSniklas char chunk_data[CHUNK_MASK + 1];
2922159047fSniklas char chunk_init[CHUNK_MASK + 1];
2932159047fSniklas bfd_vma vma;
2942159047fSniklas struct data_struct *next;
2952159047fSniklas };
2962159047fSniklas
2972159047fSniklas typedef struct tekhex_data_struct
2982159047fSniklas {
2992159047fSniklas tekhex_data_list_type *head;
3002159047fSniklas unsigned int type;
3012159047fSniklas struct tekhex_symbol_struct *symbols;
3022159047fSniklas struct data_struct *data;
3032159047fSniklas } tdata_type;
3042159047fSniklas
3052159047fSniklas #define enda(x) (x->vma + x->size)
3062159047fSniklas
307*68302bafSotto static bfd_boolean
getvalue(char ** srcp,bfd_vma * valuep)308*68302bafSotto getvalue (char **srcp, bfd_vma *valuep)
3092159047fSniklas {
3102159047fSniklas char *src = *srcp;
3112159047fSniklas bfd_vma value = 0;
312*68302bafSotto unsigned int len;
313*68302bafSotto
314*68302bafSotto if (!ISHEX (*src))
315*68302bafSotto return FALSE;
316*68302bafSotto
317*68302bafSotto len = hex_value(*src++);
3182159047fSniklas
3192159047fSniklas if (len == 0)
3202159047fSniklas len = 16;
3212159047fSniklas while (len--)
3222159047fSniklas {
323*68302bafSotto if (!ISHEX (*src))
324*68302bafSotto return FALSE;
3252159047fSniklas value = value << 4 | hex_value(*src++);
3262159047fSniklas }
3272159047fSniklas *srcp = src;
328*68302bafSotto *valuep = value;
329*68302bafSotto return TRUE;
3302159047fSniklas }
3312159047fSniklas
332*68302bafSotto static bfd_boolean
getsym(char * dstp,char ** srcp,unsigned int * lenp)333*68302bafSotto getsym (char *dstp, char **srcp, unsigned int *lenp)
3342159047fSniklas {
3352159047fSniklas char *src = *srcp;
3362159047fSniklas unsigned int i;
337*68302bafSotto unsigned int len;
3382159047fSniklas
339*68302bafSotto if (!ISHEX (*src))
340*68302bafSotto return FALSE;
341*68302bafSotto
342*68302bafSotto len = hex_value(*src++);
3432159047fSniklas if (len == 0)
3442159047fSniklas len = 16;
3452159047fSniklas for (i = 0; i < len; i++)
3462159047fSniklas dstp[i] = src[i];
3472159047fSniklas dstp[i] = 0;
3482159047fSniklas *srcp = src + i;
349*68302bafSotto *lenp = len;
350*68302bafSotto return TRUE;
3512159047fSniklas }
3522159047fSniklas
353e93f7393Sniklas static struct data_struct *
find_chunk(abfd,vma)3542159047fSniklas find_chunk (abfd, vma)
3552159047fSniklas bfd *abfd;
3562159047fSniklas bfd_vma vma;
3572159047fSniklas {
3582159047fSniklas struct data_struct *d = abfd->tdata.tekhex_data->data;
3592159047fSniklas
3602159047fSniklas vma &= ~CHUNK_MASK;
3612159047fSniklas while (d && (d->vma) != vma)
3622159047fSniklas {
3632159047fSniklas d = d->next;
3642159047fSniklas }
3652159047fSniklas if (!d)
3662159047fSniklas {
3672159047fSniklas /* No chunk for this address, so make one up */
368c074d1c9Sdrahn d = ((struct data_struct *)
369c074d1c9Sdrahn bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct)));
3702159047fSniklas
371c074d1c9Sdrahn if (!d)
3722159047fSniklas return NULL;
3732159047fSniklas
3742159047fSniklas d->next = abfd->tdata.tekhex_data->data;
3752159047fSniklas d->vma = vma;
3762159047fSniklas abfd->tdata.tekhex_data->data = d;
3772159047fSniklas }
3782159047fSniklas return d;
3792159047fSniklas }
3802159047fSniklas
3812159047fSniklas static void
insert_byte(abfd,value,addr)3822159047fSniklas insert_byte (abfd, value, addr)
3832159047fSniklas bfd *abfd;
3842159047fSniklas int value;
3852159047fSniklas bfd_vma addr;
3862159047fSniklas {
3872159047fSniklas /* Find the chunk that this byte needs and put it in */
3882159047fSniklas struct data_struct *d = find_chunk (abfd, addr);
3892159047fSniklas
3902159047fSniklas d->chunk_data[addr & CHUNK_MASK] = value;
3912159047fSniklas d->chunk_init[addr & CHUNK_MASK] = 1;
3922159047fSniklas }
3932159047fSniklas
3942159047fSniklas /* The first pass is to find the names of all the sections, and see
3952159047fSniklas how big the data is */
396*68302bafSotto static bfd_boolean
first_phase(abfd,type,src)3972159047fSniklas first_phase (abfd, type, src)
3982159047fSniklas bfd *abfd;
399e93f7393Sniklas int type;
4002159047fSniklas char *src;
4012159047fSniklas {
4022159047fSniklas asection *section = bfd_abs_section_ptr;
403c074d1c9Sdrahn unsigned int len;
404*68302bafSotto bfd_vma val;
4052159047fSniklas char sym[17]; /* A symbol can only be 16chars long */
4062159047fSniklas
4072159047fSniklas switch (type)
4082159047fSniklas {
4092159047fSniklas case '6':
4102159047fSniklas /* Data record - read it and store it */
4112159047fSniklas {
412*68302bafSotto bfd_vma addr;
413*68302bafSotto
414*68302bafSotto if (!getvalue (&src, &addr))
415*68302bafSotto return FALSE;
4162159047fSniklas
4172159047fSniklas while (*src)
4182159047fSniklas {
4192159047fSniklas insert_byte (abfd, HEX (src), addr);
4202159047fSniklas src += 2;
4212159047fSniklas addr++;
4222159047fSniklas }
4232159047fSniklas }
4242159047fSniklas
425*68302bafSotto return TRUE;
4262159047fSniklas case '3':
4272159047fSniklas /* Symbol record, read the segment */
428*68302bafSotto if (!getsym (sym, &src, &len))
429*68302bafSotto return FALSE;
4302159047fSniklas section = bfd_get_section_by_name (abfd, sym);
4312159047fSniklas if (section == (asection *) NULL)
4322159047fSniklas {
433c074d1c9Sdrahn char *n = bfd_alloc (abfd, (bfd_size_type) len + 1);
4342159047fSniklas
4352159047fSniklas if (!n)
436*68302bafSotto return FALSE;
4372159047fSniklas memcpy (n, sym, len + 1);
4382159047fSniklas section = bfd_make_section (abfd, n);
4392159047fSniklas }
4402159047fSniklas while (*src)
4412159047fSniklas {
4422159047fSniklas switch (*src)
4432159047fSniklas {
4442159047fSniklas case '1': /* section range */
4452159047fSniklas src++;
446*68302bafSotto if (!getvalue (&src, §ion->vma))
447*68302bafSotto return FALSE;
448*68302bafSotto if (!getvalue (&src, &val))
449*68302bafSotto return FALSE;
450*68302bafSotto section->_raw_size = val - section->vma;
4512159047fSniklas section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
4522159047fSniklas break;
4532159047fSniklas case '0':
4542159047fSniklas case '2':
4552159047fSniklas case '3':
4562159047fSniklas case '4':
4572159047fSniklas case '6':
4582159047fSniklas case '7':
4592159047fSniklas case '8':
4602159047fSniklas /* Symbols, add to section */
4612159047fSniklas {
462c074d1c9Sdrahn bfd_size_type amt = sizeof (tekhex_symbol_type);
4632159047fSniklas tekhex_symbol_type *new =
464c074d1c9Sdrahn (tekhex_symbol_type *) bfd_alloc (abfd, amt);
465c074d1c9Sdrahn char stype = (*src);
4662159047fSniklas
4672159047fSniklas if (!new)
468*68302bafSotto return FALSE;
4692159047fSniklas new->symbol.the_bfd = abfd;
4702159047fSniklas src++;
4712159047fSniklas abfd->symcount++;
4722159047fSniklas abfd->flags |= HAS_SYMS;
4732159047fSniklas new->prev = abfd->tdata.tekhex_data->symbols;
4742159047fSniklas abfd->tdata.tekhex_data->symbols = new;
475*68302bafSotto if (!getsym (sym, &src, &len))
476*68302bafSotto return FALSE;
477c074d1c9Sdrahn new->symbol.name = bfd_alloc (abfd, (bfd_size_type) len + 1);
4782159047fSniklas if (!new->symbol.name)
479*68302bafSotto return FALSE;
4802159047fSniklas memcpy ((char *) (new->symbol.name), sym, len + 1);
4812159047fSniklas new->symbol.section = section;
482c074d1c9Sdrahn if (stype <= '4')
4832159047fSniklas new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
4842159047fSniklas else
4852159047fSniklas new->symbol.flags = BSF_LOCAL;
486*68302bafSotto if (!getvalue (&src, &val))
487*68302bafSotto return FALSE;
488*68302bafSotto new->symbol.value = val - section->vma;
489*68302bafSotto }
490*68302bafSotto default:
491*68302bafSotto return FALSE;
4922159047fSniklas }
4932159047fSniklas }
4942159047fSniklas }
495*68302bafSotto
496*68302bafSotto return TRUE;
4972159047fSniklas }
4982159047fSniklas
499c074d1c9Sdrahn /* Pass over a tekhex, calling one of the above functions on each
5002159047fSniklas record. */
5012159047fSniklas
502*68302bafSotto static bfd_boolean
pass_over(abfd,func)5032159047fSniklas pass_over (abfd, func)
5042159047fSniklas bfd *abfd;
505*68302bafSotto bfd_boolean (*func) PARAMS ((bfd *, int, char *));
5062159047fSniklas {
5072159047fSniklas unsigned int chars_on_line;
508c074d1c9Sdrahn bfd_boolean eof = FALSE;
5092159047fSniklas
5102159047fSniklas /* To the front of the file */
5112159047fSniklas if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
5122159047fSniklas abort ();
513c074d1c9Sdrahn while (! eof)
5142159047fSniklas {
5152159047fSniklas char buffer[MAXCHUNK];
5162159047fSniklas char *src = buffer;
5172159047fSniklas char type;
5182159047fSniklas
5192159047fSniklas /* Find first '%' */
520c074d1c9Sdrahn eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
5212159047fSniklas while (*src != '%' && !eof)
5222159047fSniklas {
523c074d1c9Sdrahn eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
5242159047fSniklas }
5252159047fSniklas if (eof)
5262159047fSniklas break;
5272159047fSniklas src++;
5282159047fSniklas
5292159047fSniklas /* Fetch the type and the length and the checksum */
530c074d1c9Sdrahn if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
5312159047fSniklas abort (); /* FIXME */
5322159047fSniklas
5332159047fSniklas type = src[2];
5342159047fSniklas
5352159047fSniklas if (!ISHEX (src[0]) || !ISHEX (src[1]))
5362159047fSniklas break;
5372159047fSniklas
5382159047fSniklas chars_on_line = HEX (src) - 5; /* Already read five char */
5392159047fSniklas
540c074d1c9Sdrahn if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
5412159047fSniklas abort (); /* FIXME */
5422159047fSniklas src[chars_on_line] = 0; /* put a null at the end */
5432159047fSniklas
544*68302bafSotto if (!func (abfd, type, src))
545*68302bafSotto return FALSE;
5462159047fSniklas }
5472159047fSniklas
548*68302bafSotto return TRUE;
5492159047fSniklas }
5502159047fSniklas
551e93f7393Sniklas static long
tekhex_canonicalize_symtab(abfd,table)552007c2a45Smiod tekhex_canonicalize_symtab (abfd, table)
5532159047fSniklas bfd *abfd;
5542159047fSniklas asymbol **table;
5552159047fSniklas {
5562159047fSniklas tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols;
5572159047fSniklas unsigned int c = bfd_get_symcount (abfd);
5582159047fSniklas
5592159047fSniklas table[c] = 0;
5602159047fSniklas while (p)
5612159047fSniklas {
5622159047fSniklas table[--c] = &(p->symbol);
5632159047fSniklas p = p->prev;
5642159047fSniklas }
5652159047fSniklas
5662159047fSniklas return bfd_get_symcount (abfd);
5672159047fSniklas }
5682159047fSniklas
569e93f7393Sniklas static long
tekhex_get_symtab_upper_bound(abfd)5702159047fSniklas tekhex_get_symtab_upper_bound (abfd)
5712159047fSniklas bfd *abfd;
5722159047fSniklas {
5732159047fSniklas return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
5742159047fSniklas
5752159047fSniklas }
5762159047fSniklas
577c074d1c9Sdrahn static bfd_boolean
tekhex_mkobject(abfd)5782159047fSniklas tekhex_mkobject (abfd)
5792159047fSniklas bfd *abfd;
5802159047fSniklas {
581c074d1c9Sdrahn tdata_type *tdata;
5822159047fSniklas
583c074d1c9Sdrahn tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type));
5842159047fSniklas if (!tdata)
585c074d1c9Sdrahn return FALSE;
5862159047fSniklas abfd->tdata.tekhex_data = tdata;
5872159047fSniklas tdata->type = 1;
5882159047fSniklas tdata->head = (tekhex_data_list_type *) NULL;
5892159047fSniklas tdata->symbols = (struct tekhex_symbol_struct *) NULL;
5902159047fSniklas tdata->data = (struct data_struct *) NULL;
591c074d1c9Sdrahn return TRUE;
5922159047fSniklas }
5932159047fSniklas
5942159047fSniklas /*
595c074d1c9Sdrahn Return TRUE if the file looks like it's in TekHex format. Just look
5962159047fSniklas for a percent sign and some hex digits */
5972159047fSniklas
5982159047fSniklas static const bfd_target *
tekhex_object_p(abfd)5992159047fSniklas tekhex_object_p (abfd)
6002159047fSniklas bfd *abfd;
6012159047fSniklas {
6022159047fSniklas char b[4];
6032159047fSniklas
6042159047fSniklas tekhex_init ();
6052159047fSniklas
6062159047fSniklas if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
607c074d1c9Sdrahn || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
6082159047fSniklas return NULL;
6092159047fSniklas
6102159047fSniklas if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
6112159047fSniklas return (const bfd_target *) NULL;
6122159047fSniklas
6132159047fSniklas tekhex_mkobject (abfd);
6142159047fSniklas
615*68302bafSotto if (!pass_over (abfd, first_phase))
616*68302bafSotto return NULL;
617*68302bafSotto
6182159047fSniklas return abfd->xvec;
6192159047fSniklas }
6202159047fSniklas
6212159047fSniklas static void
move_section_contents(abfd,section,locationp,offset,count,get)6222159047fSniklas move_section_contents (abfd, section, locationp, offset, count, get)
6232159047fSniklas bfd *abfd;
6242159047fSniklas asection *section;
625007c2a45Smiod const PTR locationp;
626c074d1c9Sdrahn file_ptr offset;
6272159047fSniklas bfd_size_type count;
628c074d1c9Sdrahn bfd_boolean get;
6292159047fSniklas {
6302159047fSniklas bfd_vma addr;
6312159047fSniklas char *location = (char *) locationp;
6322159047fSniklas bfd_vma prev_number = 1; /* Nothing can have this as a high bit*/
6332159047fSniklas struct data_struct *d = (struct data_struct *) NULL;
6342159047fSniklas
635c074d1c9Sdrahn BFD_ASSERT (offset == 0);
6362159047fSniklas for (addr = section->vma; count != 0; count--, addr++)
6372159047fSniklas {
638c074d1c9Sdrahn /* Get high bits of address. */
639c074d1c9Sdrahn bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK;
6402159047fSniklas bfd_vma low_bits = addr & CHUNK_MASK;
6412159047fSniklas
6422159047fSniklas if (chunk_number != prev_number)
6432159047fSniklas {
6442159047fSniklas /* Different chunk, so move pointer */
6452159047fSniklas d = find_chunk (abfd, chunk_number);
6462159047fSniklas }
6472159047fSniklas
6482159047fSniklas if (get)
6492159047fSniklas {
6502159047fSniklas if (d->chunk_init[low_bits])
6512159047fSniklas {
6522159047fSniklas *location = d->chunk_data[low_bits];
6532159047fSniklas }
6542159047fSniklas else
6552159047fSniklas {
6562159047fSniklas *location = 0;
6572159047fSniklas }
6582159047fSniklas }
6592159047fSniklas else
6602159047fSniklas {
6612159047fSniklas d->chunk_data[low_bits] = *location;
6622159047fSniklas d->chunk_init[low_bits] = (*location != 0);
6632159047fSniklas }
6642159047fSniklas
6652159047fSniklas location++;
6662159047fSniklas
6672159047fSniklas }
6682159047fSniklas
6692159047fSniklas }
670e93f7393Sniklas
671c074d1c9Sdrahn static bfd_boolean
tekhex_get_section_contents(abfd,section,locationp,offset,count)6722159047fSniklas tekhex_get_section_contents (abfd, section, locationp, offset, count)
6732159047fSniklas bfd *abfd;
6742159047fSniklas asection *section;
6752159047fSniklas PTR locationp;
6762159047fSniklas file_ptr offset;
6772159047fSniklas bfd_size_type count;
6782159047fSniklas {
6792159047fSniklas if (section->flags & (SEC_LOAD | SEC_ALLOC))
6802159047fSniklas {
681c074d1c9Sdrahn move_section_contents (abfd, section, locationp, offset, count, TRUE);
682c074d1c9Sdrahn return TRUE;
6832159047fSniklas }
6842159047fSniklas else
685c074d1c9Sdrahn return FALSE;
6862159047fSniklas }
6872159047fSniklas
688c074d1c9Sdrahn static bfd_boolean
tekhex_set_arch_mach(abfd,arch,machine)6892159047fSniklas tekhex_set_arch_mach (abfd, arch, machine)
6902159047fSniklas bfd *abfd;
6912159047fSniklas enum bfd_architecture arch;
6922159047fSniklas unsigned long machine;
6932159047fSniklas {
6942159047fSniklas return bfd_default_set_arch_mach (abfd, arch, machine);
6952159047fSniklas }
6962159047fSniklas
6972159047fSniklas /* we have to save up all the Tekhexords for a splurge before output,
6982159047fSniklas */
6992159047fSniklas
700c074d1c9Sdrahn static bfd_boolean
tekhex_set_section_contents(abfd,section,locationp,offset,bytes_to_do)7012159047fSniklas tekhex_set_section_contents (abfd, section, locationp, offset, bytes_to_do)
7022159047fSniklas bfd *abfd;
7032159047fSniklas sec_ptr section;
704007c2a45Smiod const PTR locationp;
7052159047fSniklas file_ptr offset;
7062159047fSniklas bfd_size_type bytes_to_do;
7072159047fSniklas {
7082159047fSniklas
709c074d1c9Sdrahn if (! abfd->output_has_begun)
7102159047fSniklas {
7112159047fSniklas /* The first time around, allocate enough sections to hold all the chunks */
7122159047fSniklas asection *s = abfd->sections;
7132159047fSniklas bfd_vma vma;
7142159047fSniklas
7152159047fSniklas for (s = abfd->sections; s; s = s->next)
7162159047fSniklas {
7172159047fSniklas if (s->flags & SEC_LOAD)
7182159047fSniklas {
719c074d1c9Sdrahn for (vma = s->vma & ~(bfd_vma) CHUNK_MASK;
7202159047fSniklas vma < s->vma + s->_raw_size;
7212159047fSniklas vma += CHUNK_MASK)
7222159047fSniklas find_chunk (abfd, vma);
7232159047fSniklas }
7242159047fSniklas }
7252159047fSniklas
7262159047fSniklas }
7272159047fSniklas if (section->flags & (SEC_LOAD | SEC_ALLOC))
7282159047fSniklas {
729c074d1c9Sdrahn move_section_contents (abfd, section, locationp, offset, bytes_to_do,
730c074d1c9Sdrahn FALSE);
731c074d1c9Sdrahn return TRUE;
7322159047fSniklas }
7332159047fSniklas else
734c074d1c9Sdrahn return FALSE;
7352159047fSniklas
7362159047fSniklas }
7372159047fSniklas
7382159047fSniklas static void
writevalue(dst,value)7392159047fSniklas writevalue (dst, value)
7402159047fSniklas char **dst;
7412159047fSniklas bfd_vma value;
7422159047fSniklas {
7432159047fSniklas char *p = *dst;
7442159047fSniklas int len;
7452159047fSniklas int shift;
7462159047fSniklas
7472159047fSniklas for (len = 8, shift = 28; shift; shift -= 4, len--)
7482159047fSniklas {
7492159047fSniklas if ((value >> shift) & 0xf)
7502159047fSniklas {
7512159047fSniklas *p++ = len + '0';
7522159047fSniklas while (len)
7532159047fSniklas {
7542159047fSniklas *p++ = digs[(value >> shift) & 0xf];
7552159047fSniklas shift -= 4;
7562159047fSniklas len--;
7572159047fSniklas }
7582159047fSniklas *dst = p;
7592159047fSniklas return;
7602159047fSniklas
7612159047fSniklas }
7622159047fSniklas }
7632159047fSniklas *p++ = '1';
7642159047fSniklas *p++ = '0';
7652159047fSniklas *dst = p;
7662159047fSniklas }
7672159047fSniklas
7682159047fSniklas static void
writesym(dst,sym)7692159047fSniklas writesym (dst, sym)
7702159047fSniklas char **dst;
771c074d1c9Sdrahn const char *sym;
7722159047fSniklas {
7732159047fSniklas char *p = *dst;
7742159047fSniklas int len = (sym ? strlen (sym) : 0);
7752159047fSniklas
7762159047fSniklas if (len >= 16)
7772159047fSniklas {
7782159047fSniklas *p++ = '0';
7792159047fSniklas len = 16;
7802159047fSniklas }
7812159047fSniklas
7822159047fSniklas else
7832159047fSniklas {
7842159047fSniklas if (len == 0)
7852159047fSniklas {
7862159047fSniklas *p++ = '1';
7872159047fSniklas sym = "$";
7882159047fSniklas len = 1;
7892159047fSniklas }
7902159047fSniklas else
7912159047fSniklas {
7922159047fSniklas *p++ = digs[len];
7932159047fSniklas }
7942159047fSniklas }
7952159047fSniklas
7962159047fSniklas while (len--)
7972159047fSniklas {
7982159047fSniklas *p++ = *sym++;
7992159047fSniklas }
8002159047fSniklas *dst = p;
8012159047fSniklas }
8022159047fSniklas
8032159047fSniklas static void
out(abfd,type,start,end)8042159047fSniklas out (abfd, type, start, end)
8052159047fSniklas bfd *abfd;
806e93f7393Sniklas int type;
8072159047fSniklas char *start;
8082159047fSniklas char *end;
8092159047fSniklas {
8102159047fSniklas int sum = 0;
8112159047fSniklas char *s;
8122159047fSniklas char front[6];
8132159047fSniklas bfd_size_type wrlen;
8142159047fSniklas
8152159047fSniklas front[0] = '%';
8162159047fSniklas TOHEX (front + 1, end - start + 5);
8172159047fSniklas front[3] = type;
8182159047fSniklas
8192159047fSniklas for (s = start; s < end; s++)
8202159047fSniklas {
8212159047fSniklas sum += sum_block[(unsigned char) *s];
8222159047fSniklas }
8232159047fSniklas
8242159047fSniklas sum += sum_block[(unsigned char) front[1]]; /* length */
8252159047fSniklas sum += sum_block[(unsigned char) front[2]];
8262159047fSniklas sum += sum_block[(unsigned char) front[3]]; /* type */
8272159047fSniklas TOHEX (front + 4, sum);
828c074d1c9Sdrahn if (bfd_bwrite (front, (bfd_size_type) 6, abfd) != 6)
8292159047fSniklas abort ();
8302159047fSniklas end[0] = '\n';
8312159047fSniklas wrlen = end - start + 1;
832c074d1c9Sdrahn if (bfd_bwrite (start, wrlen, abfd) != wrlen)
8332159047fSniklas abort ();
8342159047fSniklas }
8352159047fSniklas
836c074d1c9Sdrahn static bfd_boolean
tekhex_write_object_contents(abfd)8372159047fSniklas tekhex_write_object_contents (abfd)
8382159047fSniklas bfd *abfd;
8392159047fSniklas {
8402159047fSniklas int bytes_written;
8412159047fSniklas char buffer[100];
8422159047fSniklas asymbol **p;
8432159047fSniklas asection *s;
8442159047fSniklas struct data_struct *d;
8452159047fSniklas
846b305b0f1Sespie tekhex_init ();
847b305b0f1Sespie
8482159047fSniklas bytes_written = 0;
8492159047fSniklas
8502159047fSniklas /* And the raw data */
8512159047fSniklas for (d = abfd->tdata.tekhex_data->data;
8522159047fSniklas d != (struct data_struct *) NULL;
8532159047fSniklas d = d->next)
8542159047fSniklas {
8552159047fSniklas int low;
8562159047fSniklas
857c074d1c9Sdrahn const int span = 32;
8582159047fSniklas int addr;
8592159047fSniklas
8602159047fSniklas /* Write it in blocks of 32 bytes */
8612159047fSniklas
8622159047fSniklas for (addr = 0; addr < CHUNK_MASK + 1; addr += span)
8632159047fSniklas {
8642159047fSniklas int need = 0;
8652159047fSniklas
8662159047fSniklas /* Check to see if necessary */
8672159047fSniklas for (low = 0; !need && low < span; low++)
8682159047fSniklas {
8692159047fSniklas if (d->chunk_init[addr + low])
8702159047fSniklas need = 1;
8712159047fSniklas }
8722159047fSniklas if (need)
8732159047fSniklas {
8742159047fSniklas char *dst = buffer;
8752159047fSniklas
8762159047fSniklas writevalue (&dst, addr + d->vma);
8772159047fSniklas for (low = 0; low < span; low++)
8782159047fSniklas {
8792159047fSniklas TOHEX (dst, d->chunk_data[addr + low]);
8802159047fSniklas dst += 2;
8812159047fSniklas }
8822159047fSniklas out (abfd, '6', buffer, dst);
8832159047fSniklas }
8842159047fSniklas }
8852159047fSniklas }
8862159047fSniklas /* write all the section headers for the sections */
8872159047fSniklas for (s = abfd->sections; s != (asection *) NULL; s = s->next)
8882159047fSniklas {
8892159047fSniklas char *dst = buffer;
8902159047fSniklas
8912159047fSniklas writesym (&dst, s->name);
8922159047fSniklas *dst++ = '1';
8932159047fSniklas writevalue (&dst, s->vma);
8942159047fSniklas writevalue (&dst, s->vma + s->_raw_size);
8952159047fSniklas out (abfd, '3', buffer, dst);
8962159047fSniklas }
8972159047fSniklas
8982159047fSniklas /* And the symbols */
899b305b0f1Sespie if (abfd->outsymbols)
900b305b0f1Sespie {
9012159047fSniklas for (p = abfd->outsymbols; *p; p++)
9022159047fSniklas {
9032159047fSniklas int section_code = bfd_decode_symclass (*p);
9042159047fSniklas
9052159047fSniklas if (section_code != '?')
9062159047fSniklas { /* do not include debug symbols */
907c074d1c9Sdrahn asymbol *sym = *p;
9082159047fSniklas char *dst = buffer;
9092159047fSniklas
910c074d1c9Sdrahn writesym (&dst, sym->section->name);
9112159047fSniklas
9122159047fSniklas switch (section_code)
9132159047fSniklas {
9142159047fSniklas case 'A':
9152159047fSniklas *dst++ = '2';
9162159047fSniklas break;
9172159047fSniklas case 'a':
9182159047fSniklas *dst++ = '6';
9192159047fSniklas break;
9202159047fSniklas case 'D':
9212159047fSniklas case 'B':
9222159047fSniklas case 'O':
9232159047fSniklas *dst++ = '4';
9242159047fSniklas break;
9252159047fSniklas case 'd':
9262159047fSniklas case 'b':
9272159047fSniklas case 'o':
9282159047fSniklas *dst++ = '8';
9292159047fSniklas break;
9302159047fSniklas case 'T':
9312159047fSniklas *dst++ = '3';
9322159047fSniklas break;
9332159047fSniklas case 't':
9342159047fSniklas *dst++ = '7';
9352159047fSniklas break;
9362159047fSniklas case 'C':
9372159047fSniklas case 'U':
9382159047fSniklas bfd_set_error (bfd_error_wrong_format);
939c074d1c9Sdrahn return FALSE;
9402159047fSniklas }
9412159047fSniklas
942c074d1c9Sdrahn writesym (&dst, sym->name);
943c074d1c9Sdrahn writevalue (&dst, sym->value + sym->section->vma);
9442159047fSniklas out (abfd, '3', buffer, dst);
9452159047fSniklas }
9462159047fSniklas }
947b305b0f1Sespie }
9482159047fSniklas
9492159047fSniklas /* And the terminator */
950c074d1c9Sdrahn if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9)
9512159047fSniklas abort ();
952c074d1c9Sdrahn return TRUE;
9532159047fSniklas }
9542159047fSniklas
9552159047fSniklas static int
tekhex_sizeof_headers(abfd,exec)9562159047fSniklas tekhex_sizeof_headers (abfd, exec)
957b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
958c074d1c9Sdrahn bfd_boolean exec ATTRIBUTE_UNUSED;
9592159047fSniklas
9602159047fSniklas {
9612159047fSniklas return 0;
9622159047fSniklas }
9632159047fSniklas
9642159047fSniklas static asymbol *
tekhex_make_empty_symbol(abfd)9652159047fSniklas tekhex_make_empty_symbol (abfd)
9662159047fSniklas bfd *abfd;
9672159047fSniklas {
968c074d1c9Sdrahn bfd_size_type amt = sizeof (struct tekhex_symbol_struct);
969c074d1c9Sdrahn tekhex_symbol_type *new = (tekhex_symbol_type *) bfd_zalloc (abfd, amt);
9702159047fSniklas
9712159047fSniklas if (!new)
9722159047fSniklas return NULL;
9732159047fSniklas new->symbol.the_bfd = abfd;
9742159047fSniklas new->prev = (struct tekhex_symbol_struct *) NULL;
9752159047fSniklas return &(new->symbol);
9762159047fSniklas }
9772159047fSniklas
9782159047fSniklas static void
tekhex_get_symbol_info(ignore_abfd,symbol,ret)9792159047fSniklas tekhex_get_symbol_info (ignore_abfd, symbol, ret)
980b305b0f1Sespie bfd *ignore_abfd ATTRIBUTE_UNUSED;
9812159047fSniklas asymbol *symbol;
9822159047fSniklas symbol_info *ret;
9832159047fSniklas {
9842159047fSniklas bfd_symbol_info (symbol, ret);
9852159047fSniklas }
9862159047fSniklas
9872159047fSniklas static void
tekhex_print_symbol(abfd,filep,symbol,how)988c074d1c9Sdrahn tekhex_print_symbol (abfd, filep, symbol, how)
989c074d1c9Sdrahn bfd *abfd;
9902159047fSniklas PTR filep;
9912159047fSniklas asymbol *symbol;
9922159047fSniklas bfd_print_symbol_type how;
9932159047fSniklas {
9942159047fSniklas FILE *file = (FILE *) filep;
9952159047fSniklas
9962159047fSniklas switch (how)
9972159047fSniklas {
9982159047fSniklas case bfd_print_symbol_name:
9992159047fSniklas fprintf (file, "%s", symbol->name);
10002159047fSniklas break;
10012159047fSniklas case bfd_print_symbol_more:
10022159047fSniklas break;
10032159047fSniklas
10042159047fSniklas case bfd_print_symbol_all:
10052159047fSniklas {
1006c074d1c9Sdrahn const char *section_name = symbol->section->name;
10072159047fSniklas
1008c074d1c9Sdrahn bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
10092159047fSniklas
10102159047fSniklas fprintf (file, " %-5s %s",
10112159047fSniklas section_name,
10122159047fSniklas symbol->name);
10132159047fSniklas }
10142159047fSniklas }
10152159047fSniklas }
10162159047fSniklas
10172159047fSniklas #define tekhex_close_and_cleanup _bfd_generic_close_and_cleanup
10182159047fSniklas #define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
10192159047fSniklas #define tekhex_new_section_hook _bfd_generic_new_section_hook
10202159047fSniklas
1021b305b0f1Sespie #define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name
10222159047fSniklas #define tekhex_get_lineno _bfd_nosymbols_get_lineno
10232159047fSniklas #define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line
10242159047fSniklas #define tekhex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
10252159047fSniklas #define tekhex_read_minisymbols _bfd_generic_read_minisymbols
10262159047fSniklas #define tekhex_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
10272159047fSniklas
10282159047fSniklas #define tekhex_bfd_get_relocated_section_contents \
10292159047fSniklas bfd_generic_get_relocated_section_contents
10302159047fSniklas #define tekhex_bfd_relax_section bfd_generic_relax_section
1031b305b0f1Sespie #define tekhex_bfd_gc_sections bfd_generic_gc_sections
1032c074d1c9Sdrahn #define tekhex_bfd_merge_sections bfd_generic_merge_sections
1033c074d1c9Sdrahn #define tekhex_bfd_discard_group bfd_generic_discard_group
10342159047fSniklas #define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1035c074d1c9Sdrahn #define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
10362159047fSniklas #define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols
1037c074d1c9Sdrahn #define tekhex_bfd_link_just_syms _bfd_generic_link_just_syms
10382159047fSniklas #define tekhex_bfd_final_link _bfd_generic_final_link
10392159047fSniklas #define tekhex_bfd_link_split_section _bfd_generic_link_split_section
10402159047fSniklas
10412159047fSniklas #define tekhex_get_section_contents_in_window \
10422159047fSniklas _bfd_generic_get_section_contents_in_window
10432159047fSniklas
10442159047fSniklas const bfd_target tekhex_vec =
10452159047fSniklas {
10462159047fSniklas "tekhex", /* name */
10472159047fSniklas bfd_target_tekhex_flavour,
1048c88b1d6cSniklas BFD_ENDIAN_UNKNOWN, /* target byte order */
1049c88b1d6cSniklas BFD_ENDIAN_UNKNOWN, /* target headers byte order */
10502159047fSniklas (EXEC_P | /* object flags */
10512159047fSniklas HAS_SYMS | HAS_LINENO | HAS_DEBUG | HAS_RELOC | HAS_LOCALS |
10522159047fSniklas WP_TEXT | D_PAGED),
10532159047fSniklas (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
10542159047fSniklas | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
10552159047fSniklas 0, /* leading underscore */
10562159047fSniklas ' ', /* ar_pad_char */
10572159047fSniklas 16, /* ar_max_namelen */
10582159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
10592159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
10602159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
10612159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
10622159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
10632159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
10642159047fSniklas
10652159047fSniklas {
10662159047fSniklas _bfd_dummy_target,
10672159047fSniklas tekhex_object_p, /* bfd_check_format */
10682159047fSniklas _bfd_dummy_target,
10692159047fSniklas _bfd_dummy_target,
10702159047fSniklas },
10712159047fSniklas {
10722159047fSniklas bfd_false,
10732159047fSniklas tekhex_mkobject,
10742159047fSniklas _bfd_generic_mkarchive,
10752159047fSniklas bfd_false,
10762159047fSniklas },
10772159047fSniklas { /* bfd_write_contents */
10782159047fSniklas bfd_false,
10792159047fSniklas tekhex_write_object_contents,
10802159047fSniklas _bfd_write_archive_contents,
10812159047fSniklas bfd_false,
10822159047fSniklas },
10832159047fSniklas
10842159047fSniklas BFD_JUMP_TABLE_GENERIC (tekhex),
10852159047fSniklas BFD_JUMP_TABLE_COPY (_bfd_generic),
10862159047fSniklas BFD_JUMP_TABLE_CORE (_bfd_nocore),
10872159047fSniklas BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
10882159047fSniklas BFD_JUMP_TABLE_SYMBOLS (tekhex),
10892159047fSniklas BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
10902159047fSniklas BFD_JUMP_TABLE_WRITE (tekhex),
10912159047fSniklas BFD_JUMP_TABLE_LINK (tekhex),
10922159047fSniklas BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
10932159047fSniklas
1094b305b0f1Sespie NULL,
1095b305b0f1Sespie
10962159047fSniklas (PTR) 0
10972159047fSniklas };
1098