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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [ihex.c] - Blame information for rev 38

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

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

powered by: WebSVN 2.1.0

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