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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [ihex.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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