Coverage Report

Created: 2023-06-29 07:13

/src/binutils-gdb/bfd/tekhex.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD backend for Extended Tektronix Hex Format  objects.
2
   Copyright (C) 1992-2023 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
631k
#define NIBBLE(x)    hex_value(x)
92
315k
#define HEX(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
93
2.38M
#define ISHEX(x)    hex_p(x)
94
#define TOHEX(d, x) \
95
9.28k
  (d)[1] = digs[(x) & 0xf]; \
96
9.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
1.80M
{
206
1.80M
  unsigned int i;
207
1.80M
  static bool inited = false;
208
1.80M
  int val;
209
210
1.80M
  if (! inited)
211
10
    {
212
10
      inited = true;
213
10
      hex_init ();
214
10
      val = 0;
215
110
      for (i = 0; i < 10; i++)
216
100
  sum_block[i + '0'] = val++;
217
218
270
      for (i = 'A'; i <= 'Z'; i++)
219
260
  sum_block[i] = val++;
220
221
10
      sum_block['$'] = val++;
222
10
      sum_block['%'] = val++;
223
10
      sum_block['.'] = val++;
224
10
      sum_block['_'] = val++;
225
270
      for (i = 'a'; i <= 'z'; i++)
226
260
  sum_block[i] = val++;
227
10
    }
228
1.80M
}
229
230
/* The maximum number of bytes on a line is FF.  */
231
140k
#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
485k
#define CHUNK_MASK 0x1fff
249
156k
#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
330k
{
272
330k
  char *src = *srcp;
273
330k
  bfd_vma value = 0;
274
330k
  unsigned int len;
275
276
330k
  if (src >= endp)
277
377
    return false;
278
279
329k
  if (!ISHEX (*src))
280
1.10k
    return false;
281
282
328k
  len = hex_value (*src++);
283
328k
  if (len == 0)
284
20.5k
    len = 16;
285
1.67M
  while (len-- && src < endp)
286
1.34M
    {
287
1.34M
      if (!ISHEX (*src))
288
2.22k
  return false;
289
1.34M
      value = value << 4 | hex_value (*src++);
290
1.34M
    }
291
292
326k
  *srcp = src;
293
326k
  *valuep = value;
294
326k
  return len == -1U;
295
328k
}
296
297
static bool
298
getsym (char *dstp, char **srcp, unsigned int *lenp, char * endp)
299
327k
{
300
327k
  char *src = *srcp;
301
327k
  unsigned int i;
302
327k
  unsigned int len;
303
304
327k
  if (!ISHEX (*src))
305
890
    return false;
306
307
327k
  len = hex_value (*src++);
308
327k
  if (len == 0)
309
40.9k
    len = 16;
310
2.02M
  for (i = 0; i < len && (src + i) < endp; i++)
311
1.69M
    dstp[i] = src[i];
312
327k
  dstp[i] = 0;
313
327k
  *srcp = src + i;
314
327k
  *lenp = len;
315
327k
  return i == len;
316
327k
}
317
318
static struct data_struct *
319
find_chunk (bfd *abfd, bfd_vma vma, bool create)
320
156k
{
321
156k
  struct data_struct *d = abfd->tdata.tekhex_data->data;
322
323
156k
  vma &= ~CHUNK_MASK;
324
228k
  while (d && (d->vma) != vma)
325
71.4k
    d = d->next;
326
327
156k
  if (!d && create)
328
13.9k
    {
329
      /* No chunk for this address, so make one up.  */
330
13.9k
      d = (struct data_struct *)
331
13.9k
    bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct));
332
333
13.9k
      if (!d)
334
0
  return NULL;
335
336
13.9k
      d->next = abfd->tdata.tekhex_data->data;
337
13.9k
      d->vma = vma;
338
13.9k
      abfd->tdata.tekhex_data->data = d;
339
13.9k
    }
340
156k
  return d;
341
156k
}
342
343
static void
344
insert_byte (bfd *abfd, int value, bfd_vma addr)
345
174k
{
346
174k
  if (value != 0)
347
156k
    {
348
      /* Find the chunk that this byte needs and put it in.  */
349
156k
      struct data_struct *d = find_chunk (abfd, addr, true);
350
351
156k
      d->chunk_data[addr & CHUNK_MASK] = value;
352
156k
      d->chunk_init[(addr & CHUNK_MASK) / CHUNK_SPAN] = 1;
353
156k
    }
354
174k
}
355
356
/* The first pass is to find the names of all the sections, and see
357
  how big the data is.  */
358
359
static bool
360
first_phase (bfd *abfd, int type, char *src, char * src_end)
361
139k
{
362
139k
  asection *section, *alt_section;
363
139k
  unsigned int len;
364
139k
  bfd_vma val;
365
139k
  char sym[17];     /* A symbol can only be 16chars long.  */
366
367
139k
  switch (type)
368
139k
    {
369
24.1k
    case '6':
370
      /* Data record - read it and store it.  */
371
24.1k
      {
372
24.1k
  bfd_vma addr;
373
374
24.1k
  if (!getvalue (&src, &addr, src_end))
375
617
    return false;
376
377
198k
  while (*src && src < src_end - 1)
378
174k
    {
379
174k
      insert_byte (abfd, HEX (src), addr);
380
174k
      src += 2;
381
174k
      addr++;
382
174k
    }
383
23.5k
  return true;
384
24.1k
      }
385
386
82.4k
    case '3':
387
      /* Symbol record, read the segment.  */
388
82.4k
      if (!getsym (sym, &src, &len, src_end))
389
339
  return false;
390
82.1k
      section = bfd_get_section_by_name (abfd, sym);
391
82.1k
      if (section == NULL)
392
36.6k
  {
393
36.6k
    char *n = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1);
394
395
36.6k
    if (!n)
396
0
      return false;
397
36.6k
    memcpy (n, sym, len + 1);
398
36.6k
    section = bfd_make_section (abfd, n);
399
36.6k
    if (section == NULL)
400
121
      return false;
401
36.6k
  }
402
82.0k
      alt_section = NULL;
403
354k
      while (src < src_end && *src)
404
277k
  {
405
277k
    switch (*src)
406
277k
      {
407
31.1k
      case '1':   /* Section range.  */
408
31.1k
        src++;
409
31.1k
        if (!getvalue (&src, &section->vma, src_end))
410
718
    return false;
411
30.4k
        if (!getvalue (&src, &val, src_end))
412
505
    return false;
413
29.9k
        if (val < section->vma)
414
14.3k
    val = section->vma;
415
29.9k
        section->size = val - section->vma;
416
        /* PR 17512: file: objdump-s-endless-loop.tekhex.
417
     Check for overlarge section sizes.  */
418
29.9k
        if (section->size & 0x80000000)
419
231
    return false;
420
29.7k
        section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
421
29.7k
        break;
422
20.1k
      case '0':
423
29.7k
      case '2':
424
68.3k
      case '3':
425
139k
      case '4':
426
150k
      case '6':
427
188k
      case '7':
428
245k
      case '8':
429
        /* Symbols, add to section.  */
430
245k
        {
431
245k
    size_t amt = sizeof (tekhex_symbol_type);
432
245k
    tekhex_symbol_type *new_symbol = (tekhex_symbol_type *)
433
245k
        bfd_alloc (abfd, amt);
434
245k
    char stype = (*src);
435
436
245k
    if (!new_symbol)
437
0
      return false;
438
245k
    new_symbol->symbol.the_bfd = abfd;
439
245k
    src++;
440
245k
    abfd->symcount++;
441
245k
    abfd->flags |= HAS_SYMS;
442
245k
    new_symbol->prev = abfd->tdata.tekhex_data->symbols;
443
245k
    abfd->tdata.tekhex_data->symbols = new_symbol;
444
245k
    if (!getsym (sym, &src, &len, src_end))
445
828
      return false;
446
244k
    new_symbol->symbol.name = (const char *)
447
244k
        bfd_alloc (abfd, (bfd_size_type) len + 1);
448
244k
    if (!new_symbol->symbol.name)
449
0
      return false;
450
244k
    memcpy ((char *) (new_symbol->symbol.name), sym, len + 1);
451
244k
    new_symbol->symbol.section = section;
452
244k
    if (stype <= '4')
453
139k
      new_symbol->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
454
105k
    else
455
105k
      new_symbol->symbol.flags = BSF_LOCAL;
456
244k
    if (stype == '2' || stype == '6')
457
20.0k
      new_symbol->symbol.section = bfd_abs_section_ptr;
458
224k
    else if (stype == '3' || stype == '7')
459
76.5k
      {
460
76.5k
        if ((section->flags & SEC_DATA) == 0)
461
44.5k
          section->flags |= SEC_CODE;
462
32.0k
        else
463
32.0k
          {
464
32.0k
      if (alt_section == NULL)
465
28.0k
        alt_section
466
28.0k
          = bfd_get_next_section_by_name (NULL, section);
467
32.0k
      if (alt_section == NULL)
468
11.6k
        alt_section = bfd_make_section_anyway_with_flags
469
11.6k
          (abfd, section->name,
470
11.6k
           (section->flags & ~SEC_DATA) | SEC_CODE);
471
32.0k
      if (alt_section == NULL)
472
0
        return false;
473
32.0k
      new_symbol->symbol.section = alt_section;
474
32.0k
          }
475
76.5k
      }
476
147k
    else if (stype == '4' || stype == '8')
477
127k
      {
478
127k
        if ((section->flags & SEC_CODE) == 0)
479
71.7k
          section->flags |= SEC_DATA;
480
56.1k
        else
481
56.1k
          {
482
56.1k
      if (alt_section == NULL)
483
30.6k
        alt_section
484
30.6k
          = bfd_get_next_section_by_name (NULL, section);
485
56.1k
      if (alt_section == NULL)
486
12.0k
        alt_section = bfd_make_section_anyway_with_flags
487
12.0k
          (abfd, section->name,
488
12.0k
           (section->flags & ~SEC_CODE) | SEC_DATA);
489
56.1k
      if (alt_section == NULL)
490
0
        return false;
491
56.1k
      new_symbol->symbol.section = alt_section;
492
56.1k
          }
493
127k
      }
494
244k
    if (!getvalue (&src, &val, src_end))
495
2.07k
      return false;
496
242k
    new_symbol->symbol.value = val - section->vma;
497
242k
    break;
498
244k
        }
499
410
      default:
500
410
        return false;
501
277k
      }
502
277k
  }
503
139k
    }
504
505
110k
  return true;
506
139k
}
507
508
/* Pass over a tekhex, calling one of the above functions on each
509
   record.  */
510
511
static bool
512
pass_over (bfd *abfd, bool (*func) (bfd *, int, char *, char *))
513
32.8k
{
514
32.8k
  unsigned int chars_on_line;
515
32.8k
  bool is_eof = false;
516
517
  /* To the front of the file.  */
518
32.8k
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
519
0
    return false;
520
521
166k
  while (! is_eof)
522
166k
    {
523
166k
      char src[MAXCHUNK];
524
166k
      char type;
525
526
      /* Find first '%'.  */
527
166k
      is_eof = (bool) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
528
12.6M
      while (!is_eof && *src != '%')
529
12.4M
  is_eof = (bool) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
530
531
166k
      if (is_eof)
532
21.7k
  break;
533
534
      /* Fetch the type and the length and the checksum.  */
535
145k
      if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
536
368
  return false;
537
538
144k
      type = src[2];
539
540
144k
      if (!ISHEX (src[0]) || !ISHEX (src[1]))
541
4.07k
  break;
542
543
      /* Already read five chars.  */
544
140k
      chars_on_line = HEX (src) - 5;
545
546
140k
      if (chars_on_line >= MAXCHUNK)
547
129
  return false;
548
549
140k
      if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
550
696
  return false;
551
552
      /* Put a null at the end.  */
553
139k
      src[chars_on_line] = 0;
554
139k
      if (!func (abfd, type, src, src + chars_on_line))
555
5.84k
  return false;
556
139k
    }
557
558
25.8k
  return true;
559
32.8k
}
560
561
static long
562
tekhex_canonicalize_symtab (bfd *abfd, asymbol **table)
563
168
{
564
168
  tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols;
565
168
  unsigned int c = bfd_get_symcount (abfd);
566
567
168
  table[c] = 0;
568
11.0k
  while (p)
569
10.9k
    {
570
10.9k
      table[--c] = &(p->symbol);
571
10.9k
      p = p->prev;
572
10.9k
    }
573
574
168
  return bfd_get_symcount (abfd);
575
168
}
576
577
static long
578
tekhex_get_symtab_upper_bound (bfd *abfd)
579
168
{
580
168
  return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
581
582
168
}
583
584
static bool
585
tekhex_mkobject (bfd *abfd)
586
32.8k
{
587
32.8k
  tdata_type *tdata;
588
589
32.8k
  tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type));
590
32.8k
  if (!tdata)
591
0
    return false;
592
32.8k
  abfd->tdata.tekhex_data = tdata;
593
32.8k
  tdata->type = 1;
594
32.8k
  tdata->head =  NULL;
595
32.8k
  tdata->symbols = NULL;
596
32.8k
  tdata->data = NULL;
597
32.8k
  return true;
598
32.8k
}
599
600
/* Return TRUE if the file looks like it's in TekHex format. Just look
601
   for a percent sign and some hex digits.  */
602
603
static bfd_cleanup
604
tekhex_object_p (bfd *abfd)
605
1.80M
{
606
1.80M
  char b[4];
607
608
1.80M
  tekhex_init ();
609
610
1.80M
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
611
1.80M
      || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
612
3.65k
    return NULL;
613
614
1.79M
  if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
615
1.76M
    return NULL;
616
617
32.8k
  tekhex_mkobject (abfd);
618
619
32.8k
  if (!pass_over (abfd, first_phase))
620
7.03k
    return NULL;
621
622
25.8k
  return _bfd_no_cleanup;
623
32.8k
}
624
625
static void
626
move_section_contents (bfd *abfd,
627
           asection *section,
628
           const void * locationp,
629
           file_ptr offset,
630
           bfd_size_type count,
631
           bool get)
632
52
{
633
52
  bfd_vma addr;
634
52
  char *location = (char *) locationp;
635
52
  bfd_vma prev_number = 1;  /* Nothing can have this as a high bit.  */
636
52
  struct data_struct *d = NULL;
637
638
52
  BFD_ASSERT (offset == 0);
639
7.59k
  for (addr = section->vma; count != 0; count--, addr++)
640
7.54k
    {
641
      /* Get high bits of address.  */
642
7.54k
      bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK;
643
7.54k
      bfd_vma low_bits = addr & CHUNK_MASK;
644
7.54k
      bool must_write = !get && *location != 0;
645
646
7.54k
      if (chunk_number != prev_number || (!d && must_write))
647
52
  {
648
    /* Different chunk, so move pointer. */
649
52
    d = find_chunk (abfd, chunk_number, must_write);
650
52
    prev_number = chunk_number;
651
52
  }
652
653
7.54k
      if (get)
654
5.94k
  {
655
5.94k
    if (d)
656
3.49k
      *location = d->chunk_data[low_bits];
657
2.44k
    else
658
2.44k
      *location = 0;
659
5.94k
  }
660
1.60k
      else if (must_write)
661
0
  {
662
0
    d->chunk_data[low_bits] = *location;
663
0
    d->chunk_init[low_bits / CHUNK_SPAN] = 1;
664
0
  }
665
666
7.54k
      location++;
667
7.54k
    }
668
52
}
669
670
static bool
671
tekhex_get_section_contents (bfd *abfd,
672
           asection *section,
673
           void * locationp,
674
           file_ptr offset,
675
           bfd_size_type count)
676
50
{
677
50
  if (section->flags & (SEC_LOAD | SEC_ALLOC))
678
50
    {
679
50
      move_section_contents (abfd, section, locationp, offset, count, true);
680
50
      return true;
681
50
    }
682
683
0
  return false;
684
50
}
685
686
static bool
687
tekhex_set_arch_mach (bfd *abfd,
688
          enum bfd_architecture arch,
689
          unsigned long machine)
690
7
{
691
  /* Ignore errors about unknown architecture.  */
692
7
  return (bfd_default_set_arch_mach (abfd, arch, machine)
693
7
    || arch == bfd_arch_unknown);
694
7
}
695
696
/* We have to save up all the Tekhexords for a splurge before output.  */
697
698
static bool
699
tekhex_set_section_contents (bfd *abfd,
700
           sec_ptr section,
701
           const void * locationp,
702
           file_ptr offset,
703
           bfd_size_type bytes_to_do)
704
2
{
705
2
  if (section->flags & (SEC_LOAD | SEC_ALLOC))
706
2
    {
707
2
      move_section_contents (abfd, section, locationp, offset, bytes_to_do,
708
2
           false);
709
2
      return true;
710
2
    }
711
712
0
  return false;
713
2
}
714
715
static void
716
writevalue (char **dst, bfd_vma value)
717
4.67k
{
718
4.67k
  char *p = *dst;
719
4.67k
  int len;
720
4.67k
  int shift;
721
722
22.7k
  for (len = 8, shift = 28; shift; shift -= 4, len--)
723
22.6k
    {
724
22.6k
      if ((value >> shift) & 0xf)
725
4.62k
  {
726
4.62k
    *p++ = len + '0';
727
23.9k
    while (len)
728
19.2k
      {
729
19.2k
        *p++ = digs[(value >> shift) & 0xf];
730
19.2k
        shift -= 4;
731
19.2k
        len--;
732
19.2k
      }
733
4.62k
    *dst = p;
734
4.62k
    return;
735
736
4.62k
  }
737
22.6k
    }
738
54
  *p++ = '1';
739
54
  *p++ = '0';
740
54
  *dst = p;
741
54
}
742
743
static void
744
writesym (char **dst, const char *sym)
745
9.25k
{
746
9.25k
  char *p = *dst;
747
9.25k
  int len = (sym ? strlen (sym) : 0);
748
749
9.25k
  if (len >= 16)
750
623
    {
751
623
      *p++ = '0';
752
623
      len = 16;
753
623
    }
754
8.63k
  else
755
8.63k
    {
756
8.63k
      if (len == 0)
757
43
  {
758
43
    *p++ = '1';
759
43
    sym = "$";
760
43
    len = 1;
761
43
  }
762
8.59k
      else
763
8.59k
  *p++ = digs[len];
764
8.63k
    }
765
766
62.3k
  while (len--)
767
53.1k
    *p++ = *sym++;
768
769
9.25k
  *dst = p;
770
9.25k
}
771
772
static void
773
out (bfd *abfd, int type, char *start, char *end)
774
4.64k
{
775
4.64k
  int sum = 0;
776
4.64k
  char *s;
777
4.64k
  char front[6];
778
4.64k
  bfd_size_type wrlen;
779
780
4.64k
  front[0] = '%';
781
4.64k
  TOHEX (front + 1, end - start + 5);
782
4.64k
  front[3] = type;
783
784
95.4k
  for (s = start; s < end; s++)
785
90.8k
    sum += sum_block[(unsigned char) *s];
786
787
4.64k
  sum += sum_block[(unsigned char) front[1]]; /* Length.  */
788
4.64k
  sum += sum_block[(unsigned char) front[2]];
789
4.64k
  sum += sum_block[(unsigned char) front[3]]; /* Type.  */
790
4.64k
  TOHEX (front + 4, sum);
791
4.64k
  if (bfd_bwrite (front, (bfd_size_type) 6, abfd) != 6)
792
0
    abort ();
793
4.64k
  end[0] = '\n';
794
4.64k
  wrlen = end - start + 1;
795
4.64k
  if (bfd_bwrite (start, wrlen, abfd) != wrlen)
796
0
    abort ();
797
4.64k
}
798
799
static bool
800
tekhex_write_object_contents (bfd *abfd)
801
7
{
802
7
  char buffer[100];
803
7
  asymbol **p;
804
7
  asection *s;
805
7
  struct data_struct *d;
806
807
7
  tekhex_init ();
808
809
  /* And the raw data.  */
810
7
  for (d = abfd->tdata.tekhex_data->data;
811
7
       d != NULL;
812
7
       d = d->next)
813
0
    {
814
0
      int low;
815
0
      int addr;
816
817
      /* Write it in blocks of 32 bytes.  */
818
0
      for (addr = 0; addr < CHUNK_MASK + 1; addr += CHUNK_SPAN)
819
0
  {
820
0
    if (d->chunk_init[addr / CHUNK_SPAN])
821
0
      {
822
0
        char *dst = buffer;
823
824
0
        writevalue (&dst, addr + d->vma);
825
0
        for (low = 0; low < CHUNK_SPAN; low++)
826
0
    {
827
0
      TOHEX (dst, d->chunk_data[addr + low]);
828
0
      dst += 2;
829
0
    }
830
0
        out (abfd, '6', buffer, dst);
831
0
      }
832
0
  }
833
0
    }
834
835
  /* Write all the section headers for the sections.  */
836
39
  for (s = abfd->sections; s != NULL; s = s->next)
837
32
    {
838
32
      char *dst = buffer;
839
840
32
      writesym (&dst, s->name);
841
32
      *dst++ = '1';
842
32
      writevalue (&dst, s->vma);
843
32
      writevalue (&dst, s->vma + s->size);
844
32
      out (abfd, '3', buffer, dst);
845
32
    }
846
847
  /* And the symbols.  */
848
7
  if (abfd->outsymbols)
849
7
    {
850
4.61k
      for (p = abfd->outsymbols; *p; p++)
851
4.61k
  {
852
4.61k
    int section_code = bfd_decode_symclass (*p);
853
854
4.61k
    if (section_code != '?')
855
4.61k
      {
856
        /* Do not include debug symbols.  */
857
4.61k
        asymbol *sym = *p;
858
4.61k
        char *dst = buffer;
859
860
4.61k
        writesym (&dst, sym->section->name);
861
862
4.61k
        switch (section_code)
863
4.61k
    {
864
0
    case 'A':
865
0
      *dst++ = '2';
866
0
      break;
867
861
    case 'a':
868
861
      *dst++ = '6';
869
861
      break;
870
590
    case 'D':
871
877
    case 'B':
872
877
    case 'O':
873
877
      *dst++ = '4';
874
877
      break;
875
288
    case 'd':
876
288
    case 'b':
877
288
    case 'o':
878
288
      *dst++ = '8';
879
288
      break;
880
2.39k
    case 'T':
881
2.39k
      *dst++ = '3';
882
2.39k
      break;
883
0
    case 't':
884
0
      *dst++ = '7';
885
0
      break;
886
0
    case 'C':
887
0
    case 'U':
888
0
      bfd_set_error (bfd_error_wrong_format);
889
0
      return false;
890
4.61k
    }
891
892
4.61k
        writesym (&dst, sym->name);
893
4.61k
        writevalue (&dst, sym->value + sym->section->vma);
894
4.61k
        out (abfd, '3', buffer, dst);
895
4.61k
      }
896
4.61k
  }
897
7
    }
898
899
  /* And the terminator.  */
900
7
  if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9)
901
0
    abort ();
902
7
  return true;
903
7
}
904
905
static int
906
tekhex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
907
           struct bfd_link_info *info ATTRIBUTE_UNUSED)
908
0
{
909
0
  return 0;
910
0
}
911
912
static asymbol *
913
tekhex_make_empty_symbol (bfd *abfd)
914
60.4k
{
915
60.4k
  size_t amt = sizeof (struct tekhex_symbol_struct);
916
60.4k
  tekhex_symbol_type *new_symbol = (tekhex_symbol_type *) bfd_zalloc (abfd,
917
60.4k
                      amt);
918
919
60.4k
  if (!new_symbol)
920
0
    return NULL;
921
60.4k
  new_symbol->symbol.the_bfd = abfd;
922
60.4k
  new_symbol->prev =  NULL;
923
60.4k
  return &(new_symbol->symbol);
924
60.4k
}
925
926
static void
927
tekhex_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
928
      asymbol *symbol,
929
      symbol_info *ret)
930
1.44k
{
931
1.44k
  bfd_symbol_info (symbol, ret);
932
1.44k
}
933
934
static void
935
tekhex_print_symbol (bfd *abfd,
936
         void * filep,
937
         asymbol *symbol,
938
         bfd_print_symbol_type how)
939
0
{
940
0
  FILE *file = (FILE *) filep;
941
942
0
  switch (how)
943
0
    {
944
0
    case bfd_print_symbol_name:
945
0
      fprintf (file, "%s", symbol->name);
946
0
      break;
947
0
    case bfd_print_symbol_more:
948
0
      break;
949
950
0
    case bfd_print_symbol_all:
951
0
      {
952
0
  const char *section_name = symbol->section->name;
953
954
0
  bfd_print_symbol_vandf (abfd, (void *) file, symbol);
955
956
0
  fprintf (file, " %-5s %s",
957
0
     section_name, symbol->name);
958
0
      }
959
0
    }
960
0
}
961
962
#define tekhex_close_and_cleanup        _bfd_generic_close_and_cleanup
963
#define tekhex_bfd_free_cached_info       _bfd_generic_bfd_free_cached_info
964
#define tekhex_new_section_hook         _bfd_generic_new_section_hook
965
#define tekhex_bfd_is_target_special_symbol     _bfd_bool_bfd_asymbol_false
966
#define tekhex_bfd_is_local_label_name         bfd_generic_is_local_label_name
967
#define tekhex_get_lineno         _bfd_nosymbols_get_lineno
968
#define tekhex_find_nearest_line        _bfd_nosymbols_find_nearest_line
969
#define tekhex_find_nearest_line_with_alt     _bfd_nosymbols_find_nearest_line_with_alt
970
#define tekhex_find_line          _bfd_nosymbols_find_line
971
#define tekhex_find_inliner_info        _bfd_nosymbols_find_inliner_info
972
#define tekhex_get_symbol_version_string      _bfd_nosymbols_get_symbol_version_string
973
#define tekhex_bfd_make_debug_symbol        _bfd_nosymbols_bfd_make_debug_symbol
974
#define tekhex_read_minisymbols         _bfd_generic_read_minisymbols
975
#define tekhex_minisymbol_to_symbol       _bfd_generic_minisymbol_to_symbol
976
#define tekhex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
977
#define tekhex_bfd_relax_section        bfd_generic_relax_section
978
#define tekhex_bfd_gc_sections          bfd_generic_gc_sections
979
#define tekhex_bfd_lookup_section_flags       bfd_generic_lookup_section_flags
980
#define tekhex_bfd_merge_sections       bfd_generic_merge_sections
981
#define tekhex_bfd_is_group_section       bfd_generic_is_group_section
982
#define tekhex_bfd_group_name         bfd_generic_group_name
983
#define tekhex_bfd_discard_group        bfd_generic_discard_group
984
#define tekhex_section_already_linked       _bfd_generic_section_already_linked
985
#define tekhex_bfd_define_common_symbol       bfd_generic_define_common_symbol
986
#define tekhex_bfd_link_hide_symbol       _bfd_generic_link_hide_symbol
987
#define tekhex_bfd_define_start_stop        bfd_generic_define_start_stop
988
#define tekhex_bfd_link_hash_table_create     _bfd_generic_link_hash_table_create
989
#define tekhex_bfd_link_add_symbols       _bfd_generic_link_add_symbols
990
#define tekhex_bfd_link_just_syms       _bfd_generic_link_just_syms
991
#define tekhex_bfd_copy_link_hash_symbol_type     _bfd_generic_copy_link_hash_symbol_type
992
#define tekhex_bfd_final_link         _bfd_generic_final_link
993
#define tekhex_bfd_link_split_section       _bfd_generic_link_split_section
994
#define tekhex_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
995
#define tekhex_bfd_link_check_relocs        _bfd_generic_link_check_relocs
996
997
const bfd_target tekhex_vec =
998
{
999
  "tekhex",     /* Name.  */
1000
  bfd_target_tekhex_flavour,
1001
  BFD_ENDIAN_UNKNOWN,   /* Target byte order.  */
1002
  BFD_ENDIAN_UNKNOWN,   /* Target headers byte order.  */
1003
  (EXEC_P |     /* Object flags.  */
1004
   HAS_SYMS | HAS_LINENO | HAS_DEBUG |
1005
   HAS_RELOC | HAS_LOCALS | WP_TEXT | D_PAGED),
1006
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1007
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags.  */
1008
  0,        /* Leading underscore.  */
1009
  ' ',        /* AR_pad_char.  */
1010
  16,       /* AR_max_namelen.  */
1011
  0,        /* match priority.  */
1012
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1013
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1014
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1015
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
1016
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1017
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1018
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1019
1020
  {
1021
    _bfd_dummy_target,
1022
    tekhex_object_p,    /* bfd_check_format.  */
1023
    _bfd_dummy_target,
1024
    _bfd_dummy_target,
1025
  },
1026
  {
1027
    _bfd_bool_bfd_false_error,
1028
    tekhex_mkobject,
1029
    _bfd_generic_mkarchive,
1030
    _bfd_bool_bfd_false_error,
1031
  },
1032
  {       /* bfd_write_contents.  */
1033
    _bfd_bool_bfd_false_error,
1034
    tekhex_write_object_contents,
1035
    _bfd_write_archive_contents,
1036
    _bfd_bool_bfd_false_error,
1037
  },
1038
1039
  BFD_JUMP_TABLE_GENERIC (tekhex),
1040
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1041
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1042
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1043
  BFD_JUMP_TABLE_SYMBOLS (tekhex),
1044
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1045
  BFD_JUMP_TABLE_WRITE (tekhex),
1046
  BFD_JUMP_TABLE_LINK (tekhex),
1047
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1048
1049
  NULL,
1050
1051
  NULL
1052
};