OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [tekhex.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.