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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [tekhex.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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