Coverage Report

Created: 2026-09-14 08:07

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