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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [ihex.c] - Blame information for rev 1783

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

Line No. Rev Author Line
1 104 markom
/* BFD back-end for Intel Hex objects.
2
   Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
   Written by Ian Lance Taylor of Cygnus Support <ian@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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
/* This is what Intel Hex files look like:
22
 
23
1. INTEL FORMATS
24
 
25
A. Intel 1
26
 
27
   16-bit address-field format, for files 64k bytes in length or less.
28
 
29
   DATA RECORD
30
   Byte 1       Header = colon(:)
31
   2..3         The number of data bytes in hex notation
32
   4..5         High byte of the record load address
33
   6..7         Low byte of the record load address
34
   8..9         Record type, must be "00"
35
   10..x        Data bytes in hex notation:
36
        x = (number of bytes - 1) * 2 + 11
37
   x+1..x+2     Checksum in hex notation
38
   x+3..x+4     Carriage return, line feed
39
 
40
   END RECORD
41
   Byte 1       Header = colon (:)
42
   2..3         The byte count, must be "00"
43
   4..7         Transfer-address (usually "0000")
44
                the jump-to address, execution start address
45
   8..9         Record type, must be "01"
46
   10..11       Checksum, in hex notation
47
   12..13       Carriage return, line feed
48
 
49
B. INTEL 2
50
 
51
   MCS-86 format, using a 20-bit address for files larger than 64K bytes.
52
 
53
   DATA RECORD
54
   Byte 1       Header = colon (:)
55
   2..3         The byte count of this record, hex notation
56
   4..5         High byte of the record load address
57
   6..7         Low byte of the record load address
58
   8..9         Record type, must be "00"
59
   10..x        The data bytes in hex notation:
60
        x = (number of data bytes - 1) * 2 + 11
61
   x+1..x+2     Checksum in hex notation
62
   x+3..x+4     Carriage return, line feed
63
 
64
   EXTENDED ADDRESS RECORD
65
   Byte 1       Header = colon(:)
66
   2..3         The byte count, must be "02"
67
   4..7         Load address, must be "0000"
68
   8..9         Record type, must be "02"
69
   10..11       High byte of the offset address
70
   12..13       Low byte of the offset address
71
   14..15       Checksum in hex notation
72
   16..17       Carriage return, line feed
73
 
74
   The checksums are the two's complement of the 8-bit sum
75
   without carry of the byte count, offset address, and the
76
   record type.
77
 
78
   START ADDRESS RECORD
79
   Byte 1       Header = colon (:)
80
   2..3         The byte count, must be "04"
81
   4..7         Load address, must be "0000"
82
   8..9         Record type, must be "03"
83
   10..13       8086 CS value
84
   14..17       8086 IP value
85
   18..19       Checksum in hex notation
86
   20..21       Carriage return, line feed
87
 
88
Another document reports these additional types:
89
 
90
   EXTENDED LINEAR ADDRESS RECORD
91
   Byte 1       Header = colon (:)
92
   2..3         The byte count, must be "02"
93
   4..7         Load address, must be "0000"
94
   8..9         Record type, must be "04"
95
   10..13       Upper 16 bits of address of subsequent records
96
   14..15       Checksum in hex notation
97
   16..17       Carriage return, line feed
98
 
99
   START LINEAR ADDRESS RECORD
100
   Byte 1       Header = colon (:)
101
   2..3         The byte count, must be "02"
102
   4..7         Load address, must be "0000"
103
   8..9         Record type, must be "05"
104
   10..13       Upper 16 bits of start address
105
   14..15       Checksum in hex notation
106
   16..17       Carriage return, line feed
107
 
108
The MRI compiler uses this, which is a repeat of type 5:
109
 
110
  EXTENDED START RECORD
111
   Byte 1       Header = colon (:)
112
   2..3         The byte count, must be "04"
113
   4..7         Load address, must be "0000"
114
   8..9         Record type, must be "05"
115
   10..13       Upper 16 bits of start address
116
   14..17       Lower 16 bits of start address
117
   18..19       Checksum in hex notation
118
   20..21       Carriage return, line feed
119
*/
120
 
121
#include "bfd.h"
122
#include "sysdep.h"
123
#include "libbfd.h"
124
#include "libiberty.h"
125
 
126
#include <ctype.h>
127
 
128
static void ihex_init PARAMS ((void));
129
static boolean ihex_mkobject PARAMS ((bfd *));
130
static INLINE int ihex_get_byte PARAMS ((bfd *, boolean *));
131
static void ihex_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
132
static boolean ihex_scan PARAMS ((bfd *));
133
static const bfd_target *ihex_object_p PARAMS ((bfd *));
134
static boolean ihex_read_section PARAMS ((bfd *, asection *, bfd_byte *));
135
static boolean ihex_get_section_contents
136
  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
137
static boolean ihex_set_section_contents
138
  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
139
static boolean ihex_write_record
140
  PARAMS ((bfd *, bfd_size_type, bfd_vma, unsigned int, bfd_byte *));
141
static boolean ihex_write_object_contents PARAMS ((bfd *));
142
static asymbol *ihex_make_empty_symbol PARAMS ((bfd *));
143
static boolean ihex_set_arch_mach
144
  PARAMS ((bfd *, enum bfd_architecture, unsigned long));
145
static int ihex_sizeof_headers PARAMS ((bfd *, boolean));
146
 
147
/* The number of bytes we put on one line during output.  */
148
 
149
#define CHUNK 16
150
 
151
/* Macros for converting between hex and binary. */
152
 
153
#define NIBBLE(x) (hex_value (x))
154
#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
155
#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
156
#define ISHEX(x) (hex_p (x))
157
 
158
/* When we write out an ihex value, the values can not be output as
159
   they are seen.  Instead, we hold them in memory in this structure.  */
160
 
161
struct ihex_data_list
162
{
163
  struct ihex_data_list *next;
164
  bfd_byte *data;
165
  bfd_vma where;
166
  bfd_size_type size;
167
};
168
 
169
/* The ihex tdata information.  */
170
 
171
struct ihex_data_struct
172
{
173
  struct ihex_data_list *head;
174
  struct ihex_data_list *tail;
175
};
176
 
177
/* Initialize by filling in the hex conversion array.  */
178
 
179
static void
180
ihex_init ()
181
{
182
  static boolean inited;
183
 
184
  if (! inited)
185
    {
186
      inited = true;
187
      hex_init ();
188
    }
189
}
190
 
191
/* Create an ihex object.  */
192
 
193
static boolean
194
ihex_mkobject (abfd)
195
     bfd *abfd;
196
{
197
  if (abfd->tdata.ihex_data == NULL)
198
    {
199
      struct ihex_data_struct *tdata;
200
 
201
      tdata = ((struct ihex_data_struct *)
202
               bfd_alloc (abfd, sizeof (struct ihex_data_struct)));
203
      if (tdata == NULL)
204
        return false;
205
      abfd->tdata.ihex_data = tdata;
206
      tdata->head = NULL;
207
      tdata->tail = NULL;
208
    }
209
 
210
  return true;
211
}
212
 
213
/* Read a byte from a BFD.  Set *ERRORPTR if an error occurred.
214
   Return EOF on error or end of file.  */
215
 
216
static INLINE int
217
ihex_get_byte (abfd, errorptr)
218
     bfd *abfd;
219
     boolean *errorptr;
220
{
221
  bfd_byte c;
222
 
223
  if (bfd_read (&c, 1, 1, abfd) != 1)
224
    {
225
      if (bfd_get_error () != bfd_error_file_truncated)
226
        *errorptr = true;
227
      return EOF;
228
    }
229
 
230
  return (int) (c & 0xff);
231
}
232
 
233
/* Report a problem in an Intel Hex file.  */
234
 
235
static void
236
ihex_bad_byte (abfd, lineno, c, error)
237
     bfd *abfd;
238
     unsigned int lineno;
239
     int c;
240
     boolean error;
241
{
242
  if (c == EOF)
243
    {
244
      if (! error)
245
        bfd_set_error (bfd_error_file_truncated);
246
    }
247
  else
248
    {
249
      char buf[10];
250
 
251
      if (! isprint (c))
252
        sprintf (buf, "\\%03o", (unsigned int) c);
253
      else
254
        {
255
          buf[0] = c;
256
          buf[1] = '\0';
257
        }
258
      (*_bfd_error_handler)
259
        (_("%s:%d: unexpected character `%s' in Intel Hex file\n"),
260
         bfd_get_filename (abfd), lineno, buf);
261
      bfd_set_error (bfd_error_bad_value);
262
    }
263
}
264
 
265
/* Read an Intel hex file and turn it into sections.  We create a new
266
   section for each contiguous set of bytes.  */
267
 
268
static boolean
269
ihex_scan (abfd)
270
     bfd *abfd;
271
{
272
  bfd_vma segbase;
273
  bfd_vma extbase;
274
  asection *sec;
275
  int lineno;
276
  boolean error;
277
  bfd_byte *buf = NULL;
278
  size_t bufsize;
279
  int c;
280
 
281
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
282
    goto error_return;
283
 
284
  abfd->start_address = 0;
285
 
286
  segbase = 0;
287
  extbase = 0;
288
  sec = NULL;
289
  lineno = 1;
290
  error = false;
291
  bufsize = 0;
292
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
293
    {
294
      if (c == '\r')
295
        continue;
296
      else if (c == '\n')
297
        {
298
          ++lineno;
299
          continue;
300
        }
301
      else if (c != ':')
302
        {
303
          ihex_bad_byte (abfd, lineno, c, error);
304
          goto error_return;
305
        }
306
      else
307
        {
308
          file_ptr pos;
309
          char hdr[8];
310
          unsigned int i;
311
          unsigned int len;
312
          bfd_vma addr;
313
          unsigned int type;
314
          unsigned int chars;
315
          unsigned int chksum;
316
 
317
          /* This is a data record.  */
318
 
319
          pos = bfd_tell (abfd) - 1;
320
 
321
          /* Read the header bytes.  */
322
 
323
          if (bfd_read (hdr, 1, 8, abfd) != 8)
324
            goto error_return;
325
 
326
          for (i = 0; i < 8; i++)
327
            {
328
              if (! ISHEX (hdr[i]))
329
                {
330
                  ihex_bad_byte (abfd, lineno, hdr[i], error);
331
                  goto error_return;
332
                }
333
            }
334
 
335
          len = HEX2 (hdr);
336
          addr = HEX4 (hdr + 2);
337
          type = HEX2 (hdr + 6);
338
 
339
          /* Read the data bytes.  */
340
 
341
          chars = len * 2 + 2;
342
          if (chars >= bufsize)
343
            {
344
              buf = (bfd_byte *) bfd_realloc (buf, chars);
345
              if (buf == NULL)
346
                goto error_return;
347
              bufsize = chars;
348
            }
349
 
350
          if (bfd_read (buf, 1, chars, abfd) != chars)
351
            goto error_return;
352
 
353
          for (i = 0; i < chars; i++)
354
            {
355
              if (! ISHEX (buf[i]))
356
                {
357
                  ihex_bad_byte (abfd, lineno, hdr[i], error);
358
                  goto error_return;
359
                }
360
            }
361
 
362
          /* Check the checksum.  */
363
          chksum = len + addr + (addr >> 8) + type;
364
          for (i = 0; i < len; i++)
365
            chksum += HEX2 (buf + 2 * i);
366
          if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
367
            {
368
              (*_bfd_error_handler)
369
                (_("%s:%d: bad checksum in Intel Hex file (expected %u, found %u)"),
370
                 bfd_get_filename (abfd), lineno,
371
                 (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
372
              bfd_set_error (bfd_error_bad_value);
373
              goto error_return;
374
            }
375
 
376
          switch (type)
377
            {
378
            case 0:
379
              /* This is a data record.  */
380
              if (sec != NULL
381
                  && sec->vma + sec->_raw_size == extbase + segbase + addr)
382
                {
383
                  /* This data goes at the end of the section we are
384
                     currently building.  */
385
                  sec->_raw_size += len;
386
                }
387
              else if (len > 0)
388
                {
389
                  char secbuf[20];
390
                  char *secname;
391
 
392
                  sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
393
                  secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);
394
                  if (secname == NULL)
395
                    goto error_return;
396
                  strcpy (secname, secbuf);
397
                  sec = bfd_make_section (abfd, secname);
398
                  if (sec == NULL)
399
                    goto error_return;
400
                  sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
401
                  sec->vma = extbase + segbase + addr;
402
                  sec->lma = extbase + segbase + addr;
403
                  sec->_raw_size = len;
404
                  sec->filepos = pos;
405
                }
406
              break;
407
 
408
            case 1:
409
              /* An end record.  */
410
              if (abfd->start_address == 0)
411
                abfd->start_address = addr;
412
              if (buf != NULL)
413
                free (buf);
414
              return true;
415
 
416
            case 2:
417
              /* An extended address record.  */
418
              if (len != 2)
419
                {
420
                  (*_bfd_error_handler)
421
                    (_("%s:%d: bad extended address record length in Intel Hex file"),
422
                     bfd_get_filename (abfd), lineno);
423
                  bfd_set_error (bfd_error_bad_value);
424
                  goto error_return;
425
                }
426
 
427
              segbase = HEX4 (buf) << 4;
428
 
429
              sec = NULL;
430
 
431
              break;
432
 
433
            case 3:
434
              /* An extended start address record.  */
435
              if (len != 4)
436
                {
437
                  (*_bfd_error_handler)
438
                    (_("%s:%d: bad extended start address length in Intel Hex file"),
439
                     bfd_get_filename (abfd), lineno);
440
                  bfd_set_error (bfd_error_bad_value);
441
                  goto error_return;
442
                }
443
 
444
              abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
445
 
446
              sec = NULL;
447
 
448
              break;
449
 
450
            case 4:
451
              /* An extended linear address record.  */
452
              if (len != 2)
453
                {
454
                  (*_bfd_error_handler)
455
                    (_("%s:%d: bad extended linear address record length in Intel Hex file"),
456
                     bfd_get_filename (abfd), lineno);
457
                  bfd_set_error (bfd_error_bad_value);
458
                  goto error_return;
459
                }
460
 
461
              extbase = HEX4 (buf) << 16;
462
 
463
              sec = NULL;
464
 
465
              break;
466
 
467
            case 5:
468
              /* An extended linear start address record.  */
469
              if (len != 2 && len != 4)
470
                {
471
                  (*_bfd_error_handler)
472
                    (_("%s:%d: bad extended linear start address length in Intel Hex file"),
473
                     bfd_get_filename (abfd), lineno);
474
                  bfd_set_error (bfd_error_bad_value);
475
                  goto error_return;
476
                }
477
 
478
              if (len == 2)
479
                abfd->start_address += HEX4 (buf) << 16;
480
              else
481
                abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
482
 
483
              sec = NULL;
484
 
485
              break;
486
 
487
            default:
488
              (*_bfd_error_handler)
489
                (_("%s:%d: unrecognized ihex type %u in Intel Hex file\n"),
490
                 bfd_get_filename (abfd), lineno, type);
491
              bfd_set_error (bfd_error_bad_value);
492
              goto error_return;
493
            }
494
        }
495
    }
496
 
497
  if (error)
498
    goto error_return;
499
 
500
  if (buf != NULL)
501
    free (buf);
502
 
503
  return true;
504
 
505
 error_return:
506
  if (buf != NULL)
507
    free (buf);
508
  return false;
509
}
510
 
511
/* Try to recognize an Intel Hex file.  */
512
 
513
static const bfd_target *
514
ihex_object_p (abfd)
515
     bfd *abfd;
516
{
517
  bfd_byte b[9];
518
  unsigned int i;
519
  unsigned int type;
520
 
521
  ihex_init ();
522
 
523
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
524
    return NULL;
525
  if (bfd_read (b, 1, 9, abfd) != 9)
526
    {
527
      if (bfd_get_error () == bfd_error_file_truncated)
528
        bfd_set_error (bfd_error_wrong_format);
529
      return NULL;
530
    }
531
 
532
  if (b[0] != ':')
533
    {
534
      bfd_set_error (bfd_error_wrong_format);
535
      return NULL;
536
    }
537
 
538
  for (i = 1; i < 9; i++)
539
    {
540
      if (! ISHEX (b[i]))
541
        {
542
          bfd_set_error (bfd_error_wrong_format);
543
          return NULL;
544
        }
545
    }
546
 
547
  type = HEX2 (b + 7);
548
  if (type > 5)
549
    {
550
      bfd_set_error (bfd_error_wrong_format);
551
      return NULL;
552
    }
553
 
554
  /* OK, it looks like it really is an Intel Hex file.  */
555
 
556
  if (! ihex_mkobject (abfd)
557
      || ! ihex_scan (abfd))
558
    return NULL;
559
 
560
  return abfd->xvec;
561
}
562
 
563
/* Read the contents of a section in an Intel Hex file.  */
564
 
565
static boolean
566
ihex_read_section (abfd, section, contents)
567
     bfd *abfd;
568
     asection *section;
569
     bfd_byte *contents;
570
{
571
  int c;
572
  bfd_byte *p;
573
  bfd_byte *buf = NULL;
574
  size_t bufsize;
575
  boolean error;
576
 
577
  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
578
    goto error_return;
579
 
580
  p = contents;
581
  bufsize = 0;
582
  error = false;
583
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
584
    {
585
      char hdr[8];
586
      unsigned int len;
587
      bfd_vma addr;
588
      unsigned int type;
589
      unsigned int i;
590
 
591
      if (c == '\r' || c == '\n')
592
        continue;
593
 
594
      /* This is called after ihex_scan has succeeded, so we ought to
595
         know the exact format.  */
596
      BFD_ASSERT (c == ':');
597
 
598
      if (bfd_read (hdr, 1, 8, abfd) != 8)
599
        goto error_return;
600
 
601
      len = HEX2 (hdr);
602
      addr = HEX4 (hdr + 2);
603
      type = HEX2 (hdr + 6);
604
 
605
      /* We should only see type 0 records here.  */
606
      if (type != 0)
607
        {
608
          (*_bfd_error_handler)
609
            (_("%s: internal error in ihex_read_section"),
610
             bfd_get_filename (abfd));
611
          bfd_set_error (bfd_error_bad_value);
612
          goto error_return;
613
        }
614
 
615
      if (len * 2 > bufsize)
616
        {
617
          buf = (bfd_byte *) bfd_realloc (buf, len * 2);
618
          if (buf == NULL)
619
            goto error_return;
620
          bufsize = len * 2;
621
        }
622
 
623
      if (bfd_read (buf, 1, len * 2, abfd) != len * 2)
624
        goto error_return;
625
 
626
      for (i = 0; i < len; i++)
627
        *p++ = HEX2 (buf + 2 * i);
628
      if ((bfd_size_type) (p - contents) >= section->_raw_size)
629
        {
630
          /* We've read everything in the section.  */
631
          if (buf != NULL)
632
            free (buf);
633
          return true;
634
        }
635
 
636
      /* Skip the checksum.  */
637
      if (bfd_read (buf, 1, 2, abfd) != 2)
638
        goto error_return;
639
    }
640
 
641
  if ((bfd_size_type) (p - contents) < section->_raw_size)
642
    {
643
      (*_bfd_error_handler)
644
        (_("%s: bad section length in ihex_read_section"),
645
         bfd_get_filename (abfd));
646
      bfd_set_error (bfd_error_bad_value);
647
      goto error_return;
648
    }
649
 
650
  if (buf != NULL)
651
    free (buf);
652
 
653
  return true;
654
 
655
 error_return:
656
  if (buf != NULL)
657
    free (buf);
658
  return false;
659
}
660
 
661
/* Get the contents of a section in an Intel Hex file.  */
662
 
663
static boolean
664
ihex_get_section_contents (abfd, section, location, offset, count)
665
     bfd *abfd;
666
     asection *section;
667
     PTR location;
668
     file_ptr offset;
669
     bfd_size_type count;
670
{
671
  if (section->used_by_bfd == NULL)
672
    {
673
      section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
674
      if (section->used_by_bfd == NULL)
675
        return false;
676
      if (! ihex_read_section (abfd, section, section->used_by_bfd))
677
        return false;
678
    }
679
 
680
  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
681
          (size_t) count);
682
 
683
  return true;
684
}
685
 
686
/* Set the contents of a section in an Intel Hex file.  */
687
 
688
static boolean
689
ihex_set_section_contents (abfd, section, location, offset, count)
690
     bfd *abfd;
691
     asection *section;
692
     PTR location;
693
     file_ptr offset;
694
     bfd_size_type count;
695
{
696
  struct ihex_data_list *n;
697
  bfd_byte *data;
698
  struct ihex_data_struct *tdata;
699
 
700
  if (count == 0
701
      || (section->flags & SEC_ALLOC) == 0
702
      || (section->flags & SEC_LOAD) == 0)
703
    return true;
704
 
705
  n = ((struct ihex_data_list *)
706
       bfd_alloc (abfd, sizeof (struct ihex_data_list)));
707
  if (n == NULL)
708
    return false;
709
 
710
  data = (bfd_byte *) bfd_alloc (abfd, count);
711
  if (data == NULL)
712
    return false;
713
  memcpy (data, location, (size_t) count);
714
 
715
  n->data = data;
716
  n->where = section->lma + offset;
717
  n->size = count;
718
 
719
  /* Sort the records by address.  Optimize for the common case of
720
     adding a record to the end of the list.  */
721
  tdata = abfd->tdata.ihex_data;
722
  if (tdata->tail != NULL
723
      && n->where >= tdata->tail->where)
724
    {
725
      tdata->tail->next = n;
726
      n->next = NULL;
727
      tdata->tail = n;
728
    }
729
  else
730
    {
731
      register struct ihex_data_list **pp;
732
 
733
      for (pp = &tdata->head;
734
           *pp != NULL && (*pp)->where < n->where;
735
           pp = &(*pp)->next)
736
        ;
737
      n->next = *pp;
738
      *pp = n;
739
      if (n->next == NULL)
740
        tdata->tail = n;
741
    }
742
 
743
  return true;
744
}
745
 
746
/* Write a record out to an Intel Hex file.  */
747
 
748
static boolean
749
ihex_write_record (abfd, count, addr, type, data)
750
     bfd *abfd;
751
     bfd_size_type count;
752
     bfd_vma addr;
753
     unsigned int type;
754
     bfd_byte *data;
755
{
756
  static const char digs[] = "0123456789ABCDEF";
757
  char buf[9 + CHUNK * 2 + 4];
758
  char *p;
759
  unsigned int chksum;
760
  unsigned int i;
761
 
762
#define TOHEX(buf, v) \
763
  ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
764
 
765
  buf[0] = ':';
766
  TOHEX (buf + 1, count);
767
  TOHEX (buf + 3, (addr >> 8) & 0xff);
768
  TOHEX (buf + 5, addr & 0xff);
769
  TOHEX (buf + 7, type);
770
 
771
  chksum = count + addr + (addr >> 8) + type;
772
 
773
  for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
774
    {
775
      TOHEX (p, *data);
776
      chksum += *data;
777
    }
778
 
779
  TOHEX (p, (- chksum) & 0xff);
780
  p[2] = '\r';
781
  p[3] = '\n';
782
 
783
  if (bfd_write (buf, 1, 9 + count * 2 + 4, abfd) != 9 + count * 2 + 4)
784
    return false;
785
 
786
  return true;
787
}
788
 
789
/* Write out an Intel Hex file.  */
790
 
791
static boolean
792
ihex_write_object_contents (abfd)
793
     bfd *abfd;
794
{
795
  bfd_vma segbase;
796
  bfd_vma extbase;
797
  struct ihex_data_list *l;
798
 
799
  segbase = 0;
800
  extbase = 0;
801
  for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
802
    {
803
      bfd_vma where;
804
      bfd_byte *p;
805
      bfd_size_type count;
806
 
807
      where = l->where;
808
      p = l->data;
809
      count = l->size;
810
      while (count > 0)
811
        {
812
          bfd_size_type now;
813
 
814
          now = count;
815
          if (now > CHUNK)
816
            now = CHUNK;
817
 
818
          if (where > segbase + extbase + 0xffff)
819
            {
820
              bfd_byte addr[2];
821
 
822
              /* We need a new base address.  */
823
              if (where <= 0xfffff)
824
                {
825
                  /* The addresses should be sorted.  */
826
                  BFD_ASSERT (extbase == 0);
827
 
828
                  segbase = where & 0xf0000;
829
                  addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
830
                  addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
831
                  if (! ihex_write_record (abfd, 2, 0, 2, addr))
832
                    return false;
833
                }
834
              else
835
                {
836
                  /* The extended address record and the extended
837
                     linear address record are combined, at least by
838
                     some readers.  We need an extended linear address
839
                     record here, so if we've already written out an
840
                     extended address record, zero it out to avoid
841
                     confusion.  */
842
                  if (segbase != 0)
843
                    {
844
                      addr[0] = 0;
845
                      addr[1] = 0;
846
                      if (! ihex_write_record (abfd, 2, 0, 2, addr))
847
                        return false;
848
                      segbase = 0;
849
                    }
850
 
851
                  extbase = where & 0xffff0000;
852
                  if (where > extbase + 0xffff)
853
                    {
854
                      char buf[20];
855
 
856
                      sprintf_vma (buf, where);
857
                      (*_bfd_error_handler)
858
                        (_("%s: address 0x%s out of range for Intex Hex file"),
859
                         bfd_get_filename (abfd), buf);
860
                      bfd_set_error (bfd_error_bad_value);
861
                      return false;
862
                    }
863
                  addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
864
                  addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
865
                  if (! ihex_write_record (abfd, 2, 0, 4, addr))
866
                    return false;
867
                }
868
            }
869
 
870
          if (! ihex_write_record (abfd, now, where - (extbase + segbase),
871
                                   0, p))
872
            return false;
873
 
874
          where += now;
875
          p += now;
876
          count -= now;
877
        }
878
    }
879
 
880
  if (abfd->start_address != 0)
881
    {
882
      bfd_vma start;
883
      bfd_byte startbuf[4];
884
 
885
      start = abfd->start_address;
886
 
887
      if (start <= 0xfffff)
888
        {
889
          startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
890
          startbuf[1] = 0;
891
          startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
892
          startbuf[3] = (bfd_byte)start & 0xff;
893
          if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
894
            return false;
895
        }
896
      else
897
        {
898
          startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
899
          startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
900
          startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
901
          startbuf[3] = (bfd_byte)start & 0xff;
902
          if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
903
            return false;
904
        }
905
    }
906
 
907
  if (! ihex_write_record (abfd, 0, 0, 1, NULL))
908
    return false;
909
 
910
  return true;
911
}
912
 
913
/* Make an empty symbol.  This is required only because
914
   bfd_make_section_anyway wants to create a symbol for the section.  */
915
 
916
static asymbol *
917
ihex_make_empty_symbol (abfd)
918
     bfd *abfd;
919
{
920
  asymbol *new;
921
 
922
  new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
923
  if (new != NULL)
924
    new->the_bfd = abfd;
925
  return new;
926
}
927
 
928
/* Set the architecture for the output file.  The architecture is
929
   irrelevant, so we ignore errors about unknown architectures.  */
930
 
931
static boolean
932
ihex_set_arch_mach (abfd, arch, mach)
933
     bfd *abfd;
934
     enum bfd_architecture arch;
935
     unsigned long mach;
936
{
937
  if (! bfd_default_set_arch_mach (abfd, arch, mach))
938
    {
939
      if (arch != bfd_arch_unknown)
940
        return false;
941
    }
942
  return true;
943
}
944
 
945
/* Get the size of the headers, for the linker.  */
946
 
947
/*ARGSUSED*/
948
static int
949
ihex_sizeof_headers (abfd, exec)
950
     bfd *abfd ATTRIBUTE_UNUSED;
951
     boolean exec ATTRIBUTE_UNUSED;
952
{
953
  return 0;
954
}
955
 
956
/* Some random definitions for the target vector.  */
957
 
958
#define ihex_close_and_cleanup _bfd_generic_close_and_cleanup
959
#define ihex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
960
#define ihex_new_section_hook _bfd_generic_new_section_hook
961
#define ihex_get_section_contents_in_window \
962
  _bfd_generic_get_section_contents_in_window
963
 
964
#define ihex_get_symtab_upper_bound bfd_0l
965
#define ihex_get_symtab \
966
  ((long (*) PARAMS ((bfd *, asymbol **))) bfd_0l)
967
#define ihex_print_symbol _bfd_nosymbols_print_symbol
968
#define ihex_get_symbol_info _bfd_nosymbols_get_symbol_info
969
#define ihex_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
970
#define ihex_get_lineno _bfd_nosymbols_get_lineno
971
#define ihex_find_nearest_line _bfd_nosymbols_find_nearest_line
972
#define ihex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
973
#define ihex_read_minisymbols _bfd_nosymbols_read_minisymbols
974
#define ihex_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
975
 
976
#define ihex_get_reloc_upper_bound \
977
  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
978
#define ihex_canonicalize_reloc \
979
  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
980
#define ihex_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
981
 
982
#define ihex_bfd_get_relocated_section_contents \
983
  bfd_generic_get_relocated_section_contents
984
#define ihex_bfd_relax_section bfd_generic_relax_section
985
#define ihex_bfd_gc_sections bfd_generic_gc_sections
986
#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
987
#define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols
988
#define ihex_bfd_final_link _bfd_generic_final_link
989
#define ihex_bfd_link_split_section _bfd_generic_link_split_section
990
 
991
/* The Intel Hex target vector.  */
992
 
993
const bfd_target ihex_vec =
994
{
995
  "ihex",                       /* name */
996
  bfd_target_ihex_flavour,
997
  BFD_ENDIAN_UNKNOWN,           /* target byte order */
998
  BFD_ENDIAN_UNKNOWN,           /* target headers byte order */
999
  0,                             /* object flags */
1000
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD),    /* section flags */
1001
  0,                             /* leading underscore */
1002
  ' ',                          /* ar_pad_char */
1003
  16,                           /* ar_max_namelen */
1004
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1005
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1006
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
1007
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1008
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1009
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
1010
 
1011
  {
1012
    _bfd_dummy_target,
1013
    ihex_object_p,              /* bfd_check_format */
1014
    _bfd_dummy_target,
1015
    _bfd_dummy_target,
1016
  },
1017
  {
1018
    bfd_false,
1019
    ihex_mkobject,
1020
    _bfd_generic_mkarchive,
1021
    bfd_false,
1022
  },
1023
  {                             /* bfd_write_contents */
1024
    bfd_false,
1025
    ihex_write_object_contents,
1026
    _bfd_write_archive_contents,
1027
    bfd_false,
1028
  },
1029
 
1030
  BFD_JUMP_TABLE_GENERIC (ihex),
1031
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1032
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1033
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1034
  BFD_JUMP_TABLE_SYMBOLS (ihex),
1035
  BFD_JUMP_TABLE_RELOCS (ihex),
1036
  BFD_JUMP_TABLE_WRITE (ihex),
1037
  BFD_JUMP_TABLE_LINK (ihex),
1038
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1039
 
1040
  NULL,
1041
 
1042
  (PTR) 0
1043
};

powered by: WebSVN 2.1.0

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