* opncls.c (bfd_alloc_by_size_t): Set bfd_error_no_memory if
[deliverable/binutils-gdb.git] / bfd / srec.c
CommitLineData
4a8db330 1/* BFD back-end for s-record objects.
51fbf454 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
9898b929 3 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
4a81b561 4
387cbb2b 5This file is part of BFD, the Binary File Descriptor library.
4a81b561 6
387cbb2b 7This program is free software; you can redistribute it and/or modify
4a81b561 8it under the terms of the GNU General Public License as published by
387cbb2b
JG
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
4a81b561 11
387cbb2b 12This program is distributed in the hope that it will be useful,
4a81b561
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
387cbb2b 18along with this program; if not, write to the Free Software
c3246d9b 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
4a81b561 20
9898b929
JG
21/*
22SUBSECTION
8f8fefcc 23 S-Record handling
4a81b561 24
9898b929
JG
25DESCRIPTION
26
8f8fefcc
JG
27 Ordinary S-Records cannot hold anything but addresses and
28 data, so that's all that we implement.
9783e04a 29
8f8fefcc 30 The only interesting thing is that S-Records may come out of
9898b929
JG
31 order and there is no header, so an initial scan is required
32 to discover the minimum and maximum addresses used to create
33 the vma and size of the only section we create. We
9783e04a 34 arbitrarily call this section ".text".
9898b929
JG
35
36 When bfd_get_section_contents is called the file is read
37 again, and this time the data is placed into a bfd_alloc'd
38 area.
39
40 Any number of sections may be created for output, we save them
41 up and output them when it's time to close the bfd.
42
43 An s record looks like:
44
45EXAMPLE
294eaca4 46 S<type><length><address><data><checksum>
9898b929
JG
47
48DESCRIPTION
49 Where
50 o length
51 is the number of bytes following upto the checksum. Note that
52 this is not the number of chars following, since it takes two
53 chars to represent a byte.
54 o type
55 is one of:
56 0) header record
57 1) two byte address data record
58 2) three byte address data record
59 3) four byte address data record
60 7) four byte address termination record
61 8) three byte address termination record
62 9) two byte address termination record
63
64 o address
65 is the start address of the data following, or in the case of
66 a termination record, the start address of the image
67 o data
68 is the data.
69 o checksum
70 is the sum of all the raw byte data in the record, from the length
71 upwards, modulo 256 and subtracted from 255.
8f8fefcc
JG
72
73
74SUBSECTION
75 Symbol S-Record handling
76
77DESCRIPTION
78 Some ICE equipment understands an addition to the standard
79 S-Record format; symbols and their addresses can be sent
80 before the data.
81
82 The format of this is:
83 ($$ <modulename>
84 (<space> <symbol> <address>)*)
85 $$
86
87 so a short symbol table could look like:
88
89EXAMPLE
90 $$ flash.x
91 $$ flash.c
92 _port6 $0
93 _delay $4
94 _start $14
95 _etext $8036
96 _edata $8036
97 _end $8036
9783e04a 98 $$
8f8fefcc
JG
99
100DESCRIPTION
101 We allow symbols to be anywhere in the data stream - the module names
102 are always ignored.
103
9898b929 104*/
7ed4093a 105
36773af5 106#include "bfd.h"
9898b929 107#include "sysdep.h"
4a81b561 108#include "libbfd.h"
7f4c005d 109#include "libiberty.h"
b7577823 110#include <ctype.h>
7f4c005d
KR
111
112static void srec_init PARAMS ((void));
113static boolean srec_mkobject PARAMS ((bfd *));
114static int srec_get_byte PARAMS ((bfd *, boolean *));
115static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
116static boolean srec_scan PARAMS ((bfd *));
117static const bfd_target *srec_object_p PARAMS ((bfd *));
118static const bfd_target *symbolsrec_object_p PARAMS ((bfd *));
119static boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *));
4a81b561 120
6d4f7715 121static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma,
7f4c005d
KR
122 const bfd_byte *,
123 const bfd_byte *));
6d4f7715
ILT
124static boolean srec_write_header PARAMS ((bfd *));
125static boolean srec_write_symbols PARAMS ((bfd *));
126
4c8d6c9f 127/* Macros for converting between hex and binary. */
4a81b561 128
3039e8ee 129static CONST char digs[] = "0123456789ABCDEF";
5f9ca960 130
7f4c005d 131#define NIBBLE(x) hex_value(x)
9898b929 132#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
5f9ca960
JG
133#define TOHEX(d, x, ch) \
134 d[1] = digs[(x) & 0xf]; \
135 d[0] = digs[((x)>>4)&0xf]; \
136 ch += ((x) & 0xff);
7f4c005d 137#define ISHEX(x) hex_p(x)
4a81b561 138
4c8d6c9f 139/* Initialize by filling in the hex conversion array. */
9898b929 140
e98e6ec1 141static void
57a1867e 142srec_init ()
9898b929 143{
9783e04a
DM
144 static boolean inited = false;
145
146 if (inited == false)
9898b929 147 {
9783e04a 148 inited = true;
7f4c005d 149 hex_init ();
9783e04a 150 }
9898b929
JG
151}
152
4a81b561 153/* The maximum number of bytes on a line is FF */
9783e04a 154#define MAXCHUNK 0xff
4a81b561 155/* The number of bytes we fit onto a line on output */
9898b929
JG
156#define CHUNK 21
157
7f4c005d
KR
158/* When writing an S-record file, the S-records can not be output as
159 they are seen. This structure is used to hold them in memory. */
9898b929
JG
160
161struct srec_data_list_struct
162{
7f4c005d
KR
163 struct srec_data_list_struct *next;
164 bfd_byte *data;
9783e04a
DM
165 bfd_vma where;
166 bfd_size_type size;
7f4c005d 167};
9783e04a 168
7f4c005d 169typedef struct srec_data_list_struct srec_data_list_type;
8f8fefcc 170
7f4c005d
KR
171/* When scanning the S-record file, a linked list of srec_symbol
172 structures is built to represent the symbol table (if there is
173 one). */
174
175struct srec_symbol
176{
177 struct srec_symbol *next;
178 const char *name;
179 bfd_vma val;
9783e04a 180};
9898b929 181
7f4c005d 182/* The S-record tdata information. */
4a81b561 183
9783e04a
DM
184typedef struct srec_data_struct
185 {
186 srec_data_list_type *head;
d4d16683 187 srec_data_list_type *tail;
9898b929 188 unsigned int type;
7f4c005d
KR
189 struct srec_symbol *symbols;
190 struct srec_symbol *symtail;
191 asymbol *csymbols;
9783e04a
DM
192 }
193tdata_type;
9898b929 194
6d4f7715
ILT
195static boolean srec_write_section PARAMS ((bfd *, tdata_type *,
196 srec_data_list_type *));
197static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *));
9898b929 198
7f4c005d 199/* Set up the S-record tdata information. */
9898b929 200
7f4c005d
KR
201static boolean
202srec_mkobject (abfd)
9783e04a 203 bfd *abfd;
9783e04a 204{
7f4c005d 205 srec_init ();
8f8fefcc 206
7f4c005d 207 if (abfd->tdata.srec_data == NULL)
8f8fefcc 208 {
7f4c005d
KR
209 tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
210 if (tdata == NULL)
a9713b91 211 return false;
7f4c005d
KR
212 abfd->tdata.srec_data = tdata;
213 tdata->type = 1;
214 tdata->head = NULL;
215 tdata->tail = NULL;
216 tdata->symbols = NULL;
217 tdata->symtail = NULL;
218 tdata->csymbols = NULL;
9783e04a 219 }
4a81b561 220
7f4c005d
KR
221 return true;
222}
357a1f38 223
7f4c005d
KR
224/* Read a byte from an S record file. Set *ERRORPTR if an error
225 occurred. Return EOF on error or end of file. */
4a81b561 226
7f4c005d
KR
227static int
228srec_get_byte (abfd, errorptr)
57a1867e 229 bfd *abfd;
7f4c005d 230 boolean *errorptr;
9783e04a 231{
7f4c005d
KR
232 bfd_byte c;
233
234 if (bfd_read (&c, 1, 1, abfd) != 1)
9783e04a 235 {
7f4c005d
KR
236 if (bfd_get_error () != bfd_error_file_truncated)
237 *errorptr = true;
238 return EOF;
9783e04a 239 }
7f4c005d
KR
240
241 return (int) (c & 0xff);
4a81b561
DHW
242}
243
7f4c005d
KR
244/* Report a problem in an S record file. FIXME: This probably should
245 not call fprintf, but we really do need some mechanism for printing
246 error messages. */
387cbb2b 247
7f4c005d
KR
248static void
249srec_bad_byte (abfd, lineno, c, error)
9783e04a 250 bfd *abfd;
7f4c005d
KR
251 unsigned int lineno;
252 int c;
253 boolean error;
8f8fefcc 254{
7f4c005d 255 if (c == EOF)
9783e04a 256 {
7f4c005d
KR
257 if (! error)
258 bfd_set_error (bfd_error_file_truncated);
259 }
260 else
261 {
262 char buf[10];
263
264 if (! isprint (c))
265 sprintf (buf, "\\%03o", (unsigned int) c);
266 else
267 {
268 buf[0] = c;
269 buf[1] = '\0';
270 }
a9713b91
ILT
271 (*_bfd_error_handler)
272 ("%s:%d: Unexpected character `%s' in S-record file\n",
273 bfd_get_filename (abfd), lineno, buf);
7f4c005d 274 bfd_set_error (bfd_error_bad_value);
9783e04a 275 }
8f8fefcc
JG
276}
277
7f4c005d
KR
278/* Add a new symbol found in an S-record file. */
279
8f8fefcc 280static boolean
7f4c005d 281srec_new_symbol (abfd, name, val)
57a1867e 282 bfd *abfd;
7f4c005d
KR
283 const char *name;
284 bfd_vma val;
8f8fefcc 285{
7f4c005d
KR
286 struct srec_symbol *n;
287
288 n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol));
289 if (n == NULL)
a9713b91 290 return false;
9783e04a 291
7f4c005d
KR
292 n->name = name;
293 n->val = val;
294
295 if (abfd->tdata.srec_data->symbols == NULL)
296 abfd->tdata.srec_data->symbols = n;
297 else
298 abfd->tdata.srec_data->symtail->next = n;
299 abfd->tdata.srec_data->symtail = n;
300 n->next = NULL;
301
302 ++abfd->symcount;
303
304 return true;
8f8fefcc
JG
305}
306
7f4c005d
KR
307/* Read the S record file and turn it into sections. We create a new
308 section for each contiguous set of bytes. */
309
310static boolean
311srec_scan (abfd)
4c3721d5 312 bfd *abfd;
4a81b561 313{
7f4c005d
KR
314 int c;
315 unsigned int lineno = 1;
316 boolean error = false;
317 bfd_byte *buf = NULL;
318 size_t bufsize = 0;
319 asection *sec = NULL;
e98e6ec1 320
6d4f7715 321 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
7f4c005d
KR
322 goto error_return;
323
324 while ((c = srec_get_byte (abfd, &error)) != EOF)
4a81b561 325 {
7f4c005d
KR
326 /* We only build sections from contiguous S-records, so if this
327 is not an S-record, then stop building a section. */
328 if (c != 'S' && c != '\r' && c != '\n')
329 sec = NULL;
330
331 switch (c)
8f8fefcc 332 {
9783e04a 333 default:
7f4c005d
KR
334 srec_bad_byte (abfd, lineno, c, error);
335 goto error_return;
336
337 case '\n':
338 ++lineno;
339 break;
340
341 case '\r':
9783e04a
DM
342 break;
343
344 case '$':
7f4c005d
KR
345 /* Starting a module name, which we ignore. */
346 while ((c = srec_get_byte (abfd, &error)) != '\n'
347 && c != EOF)
348 ;
349 if (c == EOF)
9783e04a 350 {
7f4c005d
KR
351 srec_bad_byte (abfd, lineno, c, error);
352 goto error_return;
9783e04a 353 }
7f4c005d
KR
354
355 ++lineno;
356
9783e04a
DM
357 break;
358
359 case ' ':
7f4c005d
KR
360 {
361 char *symname;
362 bfd_vma symval;
363
364 /* Starting a symbol definition. */
365 while ((c = srec_get_byte (abfd, &error)) != EOF
366 && (c == ' ' || c == '\t'))
367 ;
368 if (c == EOF)
369 {
370 srec_bad_byte (abfd, lineno, c, error);
371 goto error_return;
372 }
4c3721d5 373
7f4c005d
KR
374 obstack_1grow (&abfd->memory, c);
375 while ((c = srec_get_byte (abfd, &error)) != EOF
376 && ! isspace (c))
377 obstack_1grow (&abfd->memory, c);
378 if (c == EOF)
4c3721d5 379 {
7f4c005d
KR
380 srec_bad_byte (abfd, lineno, c, error);
381 goto error_return;
382 }
9783e04a 383
7f4c005d
KR
384 symname = obstack_finish (&abfd->memory);
385 if (symname == NULL)
386 {
387 bfd_set_error (bfd_error_no_memory);
388 goto error_return;
389 }
390
391 while ((c = srec_get_byte (abfd, &error)) != EOF
392 && (c == ' ' || c == '\t'))
393 ;
394 if (c == EOF)
395 {
396 srec_bad_byte (abfd, lineno, c, error);
397 goto error_return;
398 }
9783e04a 399
7f4c005d
KR
400 /* Skip a dollar sign before the hex value. */
401 if (c == '$')
402 {
403 c = srec_get_byte (abfd, &error);
404 if (c == EOF)
9783e04a 405 {
7f4c005d
KR
406 srec_bad_byte (abfd, lineno, c, error);
407 goto error_return;
9783e04a 408 }
4c3721d5 409 }
7f4c005d
KR
410
411 symval = 0;
412 while (ISHEX (c))
413 {
414 symval <<= 4;
415 symval += NIBBLE (c);
416 c = srec_get_byte (abfd, &error);
417 }
418
419 if (c == EOF || ! isspace (c))
420 {
421 srec_bad_byte (abfd, lineno, c, error);
422 goto error_return;
423 }
424
425 if (! srec_new_symbol (abfd, symname, symval))
426 goto error_return;
427
428 if (c == '\n')
429 ++lineno;
430
431 }
9783e04a 432 break;
7f4c005d 433
9783e04a 434 case 'S':
7f4c005d
KR
435 {
436 file_ptr pos;
437 char hdr[3];
438 unsigned int bytes;
439 bfd_vma address;
440 bfd_byte *data;
9783e04a 441
7f4c005d 442 /* Starting an S-record. */
9783e04a 443
7f4c005d 444 pos = bfd_tell (abfd) - 1;
9783e04a 445
7f4c005d
KR
446 if (bfd_read (hdr, 1, 3, abfd) != 3)
447 goto error_return;
9783e04a 448
7f4c005d
KR
449 if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
450 {
451 if (! ISHEX (hdr[1]))
452 c = hdr[1];
453 else
454 c = hdr[2];
455 srec_bad_byte (abfd, lineno, c, error);
456 goto error_return;
457 }
9783e04a 458
7f4c005d
KR
459 bytes = HEX (hdr + 1);
460 if (bytes * 2 > bufsize)
461 {
462 if (buf != NULL)
463 free (buf);
464 buf = (bfd_byte *) malloc (bytes * 2);
465 if (buf == NULL)
466 {
467 bfd_set_error (bfd_error_no_memory);
468 goto error_return;
469 }
470 bufsize = bytes * 2;
471 }
9783e04a 472
7f4c005d
KR
473 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
474 goto error_return;
9783e04a 475
7f4c005d
KR
476 /* Ignore the checksum byte. */
477 --bytes;
478
479 address = 0;
480 data = buf;
481 switch (hdr[0])
482 {
483 case '0':
484 case '5':
485 /* Prologue--ignore the file name, but stop building a
486 section at this point. */
487 sec = NULL;
488 break;
489
490 case '3':
491 address = HEX (data);
492 data += 2;
493 --bytes;
494 /* Fall through. */
495 case '2':
496 address = (address << 8) | HEX (data);
497 data += 2;
498 --bytes;
499 /* Fall through. */
500 case '1':
501 address = (address << 8) | HEX (data);
502 data += 2;
503 address = (address << 8) | HEX (data);
504 data += 2;
505 bytes -= 2;
506
507 if (sec != NULL
508 && sec->vma + sec->_raw_size == address)
509 {
510 /* This data goes at the end of the section we are
511 currently building. */
512 sec->_raw_size += bytes;
513 }
514 else
515 {
516 char secbuf[20];
517 char *secname;
518
519 sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
520 secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);
521 strcpy (secname, secbuf);
522 sec = bfd_make_section (abfd, secname);
523 if (sec == NULL)
524 goto error_return;
525 sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
526 sec->vma = address;
527 sec->_raw_size = bytes;
528 sec->filepos = pos;
529 }
530
531 break;
532
533 case '7':
534 address = HEX (data);
535 data += 2;
536 /* Fall through. */
537 case '8':
538 address = (address << 8) | HEX (data);
539 data += 2;
540 /* Fall through. */
541 case '9':
542 address = (address << 8) | HEX (data);
543 data += 2;
544 address = (address << 8) | HEX (data);
545 data += 2;
546
547 /* This is a termination record. */
548 abfd->start_address = address;
549
550 if (buf != NULL)
551 free (buf);
552
553 return true;
554 }
555 }
556 break;
8f8fefcc 557 }
4a81b561 558 }
9898b929 559
7f4c005d
KR
560 if (error)
561 goto error_return;
4a81b561 562
7f4c005d
KR
563 if (buf != NULL)
564 free (buf);
565
566 return true;
567
568 error_return:
569 if (buf != NULL)
570 free (buf);
571 return false;
8f8fefcc 572}
9898b929 573
7f4c005d
KR
574/* Check whether an existing file is an S-record file. */
575
2f3508ad 576static const bfd_target *
57a1867e
DM
577srec_object_p (abfd)
578 bfd *abfd;
4a81b561 579{
7f4c005d 580 bfd_byte b[4];
8f8fefcc 581
9783e04a 582 srec_init ();
9898b929 583
6d4f7715
ILT
584 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
585 || bfd_read (b, 1, 4, abfd) != 4)
586 return NULL;
9783e04a
DM
587
588 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
7f4c005d
KR
589 {
590 bfd_set_error (bfd_error_wrong_format);
591 return NULL;
592 }
9783e04a 593
7f4c005d
KR
594 if (! srec_mkobject (abfd)
595 || ! srec_scan (abfd))
596 return NULL;
4a81b561 597
7f4c005d 598 return abfd->xvec;
8f8fefcc
JG
599}
600
7f4c005d 601/* Check whether an existing file is an S-record file with symbols. */
8f8fefcc 602
2f3508ad 603static const bfd_target *
57a1867e
DM
604symbolsrec_object_p (abfd)
605 bfd *abfd;
8f8fefcc 606{
7f4c005d 607 char b[2];
8f8fefcc 608
9783e04a
DM
609 srec_init ();
610
6d4f7715 611 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
7f4c005d 612 || bfd_read (b, 1, 2, abfd) != 2)
6d4f7715 613 return NULL;
8f8fefcc
JG
614
615 if (b[0] != '$' || b[1] != '$')
7f4c005d
KR
616 {
617 bfd_set_error (bfd_error_wrong_format);
618 return NULL;
619 }
8f8fefcc 620
7f4c005d
KR
621 if (! srec_mkobject (abfd)
622 || ! srec_scan (abfd))
623 return NULL;
624
625 return abfd->xvec;
4a81b561
DHW
626}
627
7f4c005d
KR
628/* Read in the contents of a section in an S-record file. */
629
630static boolean
631srec_read_section (abfd, section, contents)
632 bfd *abfd;
633 asection *section;
634 bfd_byte *contents;
635{
636 int c;
637 bfd_size_type sofar = 0;
638 boolean error = false;
639 bfd_byte *buf = NULL;
640 size_t bufsize = 0;
641
642 if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
643 goto error_return;
644
645 while ((c = srec_get_byte (abfd, &error)) != EOF)
646 {
647 bfd_byte hdr[3];
648 unsigned int bytes;
649 bfd_vma address;
650 bfd_byte *data;
651
652 if (c == '\r' || c == '\n')
653 continue;
654
655 /* This is called after srec_scan has already been called, so we
656 ought to know the exact format. */
657 BFD_ASSERT (c == 'S');
658
659 if (bfd_read (hdr, 1, 3, abfd) != 3)
660 goto error_return;
661
662 BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
663
664 bytes = HEX (hdr + 1);
665
666 if (bytes * 2 > bufsize)
667 {
668 if (buf != NULL)
669 free (buf);
670 buf = (bfd_byte *) malloc (bytes * 2);
671 if (buf == NULL)
672 {
673 bfd_set_error (bfd_error_no_memory);
674 goto error_return;
675 }
676 bufsize = bytes * 2;
677 }
678
679 if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
680 goto error_return;
681
682 address = 0;
683 data = buf;
684 switch (hdr[0])
685 {
686 default:
687 BFD_ASSERT (sofar == section->_raw_size);
688 if (buf != NULL)
689 free (buf);
690 return true;
691
692 case '3':
693 address = HEX (data);
694 data += 2;
695 --bytes;
696 /* Fall through. */
697 case '2':
698 address = (address << 8) | HEX (data);
699 data += 2;
700 --bytes;
701 /* Fall through. */
702 case '1':
703 address = (address << 8) | HEX (data);
704 data += 2;
705 address = (address << 8) | HEX (data);
706 data += 2;
707 bytes -= 2;
708
709 if (address != section->vma + sofar)
710 {
711 /* We've come to the end of this section. */
712 BFD_ASSERT (sofar == section->_raw_size);
713 if (buf != NULL)
714 free (buf);
715 return true;
716 }
717
718 /* Don't consider checksum. */
719 --bytes;
720
721 while (bytes-- != 0)
722 {
723 contents[sofar] = HEX (data);
724 data += 2;
725 ++sofar;
726 }
727
728 break;
729 }
730 }
731
732 if (error)
733 goto error_return;
734
735 BFD_ASSERT (sofar == section->_raw_size);
736
737 if (buf != NULL)
738 free (buf);
739
740 return true;
741
742 error_return:
743 if (buf != NULL)
744 free (buf);
745 return false;
746}
747
748/* Get the contents of a section in an S-record file. */
4a81b561 749
4a81b561 750static boolean
57a1867e
DM
751srec_get_section_contents (abfd, section, location, offset, count)
752 bfd *abfd;
753 asection *section;
754 PTR location;
755 file_ptr offset;
756 bfd_size_type count;
9783e04a 757{
7f4c005d 758 if (section->used_by_bfd == NULL)
9898b929 759 {
7f4c005d
KR
760 section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
761 if (section->used_by_bfd == NULL
762 && section->_raw_size != 0)
a9713b91 763 return false;
9783e04a 764
7f4c005d
KR
765 if (! srec_read_section (abfd, section, section->used_by_bfd))
766 return false;
9898b929 767 }
9783e04a 768
b7577823
ILT
769 memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
770 (size_t) count);
4a81b561 771
7f4c005d 772 return true;
4a81b561
DHW
773}
774
c3246d9b 775/* we have to save up all the Srecords for a splurge before output */
4a81b561 776
9898b929 777static boolean
57a1867e
DM
778srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
779 bfd *abfd;
780 sec_ptr section;
781 PTR location;
782 file_ptr offset;
783 bfd_size_type bytes_to_do;
9783e04a
DM
784{
785 tdata_type *tdata = abfd->tdata.srec_data;
d4d16683 786 register srec_data_list_type *entry;
9783e04a 787
d4d16683
ILT
788 entry = ((srec_data_list_type *)
789 bfd_alloc (abfd, sizeof (srec_data_list_type)));
790 if (entry == NULL)
a9713b91 791 return false;
8f8fefcc 792
c3246d9b
ILT
793 if (bytes_to_do
794 && (section->flags & SEC_ALLOC)
9783e04a 795 && (section->flags & SEC_LOAD))
9898b929 796 {
7f4c005d 797 bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
d4d16683 798 if (data == NULL)
a9713b91 799 return false;
b7577823 800 memcpy ((PTR) data, location, (size_t) bytes_to_do);
9898b929 801
c3246d9b 802 if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
8f8fefcc 803 {
9898b929 804
8f8fefcc 805 }
c3246d9b 806 else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
9783e04a 807 && tdata->type < 2)
8f8fefcc
JG
808 {
809 tdata->type = 2;
810 }
9783e04a 811 else
8f8fefcc
JG
812 {
813 tdata->type = 3;
814 }
815
816 entry->data = data;
817 entry->where = section->lma + offset;
818 entry->size = bytes_to_do;
d4d16683
ILT
819
820 /* Sort the records by address. Optimize for the common case of
821 adding a record to the end of the list. */
822 if (tdata->tail != NULL
823 && entry->where >= tdata->tail->where)
824 {
825 tdata->tail->next = entry;
826 entry->next = NULL;
827 tdata->tail = entry;
828 }
829 else
830 {
831 register srec_data_list_type **look;
832
833 for (look = &tdata->head;
834 *look != NULL && (*look)->where < entry->where;
835 look = &(*look)->next)
836 ;
837 entry->next = *look;
838 *look = entry;
839 if (entry->next == NULL)
840 tdata->tail = entry;
841 }
8f8fefcc 842 }
9783e04a 843 return true;
9898b929
JG
844}
845
846/* Write a record of type, of the supplied number of bytes. The
847 supplied bytes and length don't have a checksum. That's worked out
848 here
849*/
6d4f7715 850static boolean
57a1867e
DM
851srec_write_record (abfd, type, address, data, end)
852 bfd *abfd;
6d4f7715 853 int type;
57a1867e 854 bfd_vma address;
7f4c005d
KR
855 const bfd_byte *data;
856 const bfd_byte *end;
9783e04a
DM
857{
858 char buffer[MAXCHUNK];
9783e04a 859 unsigned int check_sum = 0;
7f4c005d 860 CONST bfd_byte *src = data;
9783e04a
DM
861 char *dst = buffer;
862 char *length;
ae115e51 863 bfd_size_type wrlen;
9783e04a 864
9783e04a
DM
865 *dst++ = 'S';
866 *dst++ = '0' + type;
867
868 length = dst;
869 dst += 2; /* leave room for dst*/
870
871 switch (type)
9898b929 872 {
9783e04a
DM
873 case 3:
874 case 7:
875 TOHEX (dst, (address >> 24), check_sum);
876 dst += 2;
877 case 8:
878 case 2:
879 TOHEX (dst, (address >> 16), check_sum);
880 dst += 2;
881 case 9:
882 case 1:
883 case 0:
884 TOHEX (dst, (address >> 8), check_sum);
885 dst += 2;
886 TOHEX (dst, (address), check_sum);
887 dst += 2;
888 break;
4a81b561 889
4a81b561 890 }
9783e04a 891 for (src = data; src < end; src++)
9898b929 892 {
9783e04a
DM
893 TOHEX (dst, *src, check_sum);
894 dst += 2;
4a81b561
DHW
895 }
896
9783e04a
DM
897 /* Fill in the length */
898 TOHEX (length, (dst - length) / 2, check_sum);
899 check_sum &= 0xff;
900 check_sum = 255 - check_sum;
901 TOHEX (dst, check_sum, check_sum);
902 dst += 2;
903
904 *dst++ = '\r';
905 *dst++ = '\n';
ae115e51
ILT
906 wrlen = dst - buffer;
907 if (bfd_write ((PTR) buffer, 1, wrlen, abfd) != wrlen)
6d4f7715
ILT
908 return false;
909 return true;
9898b929 910}
4a81b561 911
4a81b561 912
4a81b561 913
6d4f7715 914static boolean
57a1867e
DM
915srec_write_header (abfd)
916 bfd *abfd;
9898b929 917{
7f4c005d
KR
918 bfd_byte buffer[MAXCHUNK];
919 bfd_byte *dst = buffer;
9783e04a 920 unsigned int i;
4a81b561 921
9783e04a
DM
922 /* I'll put an arbitary 40 char limit on header size */
923 for (i = 0; i < 40 && abfd->filename[i]; i++)
9898b929 924 {
9783e04a 925 *dst++ = abfd->filename[i];
9898b929 926 }
6d4f7715 927 return srec_write_record (abfd, 0, 0, buffer, dst);
4a81b561
DHW
928}
929
6d4f7715 930static boolean
57a1867e
DM
931srec_write_section (abfd, tdata, list)
932 bfd *abfd;
933 tdata_type *tdata;
934 srec_data_list_type *list;
9898b929 935{
9783e04a 936 unsigned int bytes_written = 0;
7f4c005d 937 bfd_byte *location = list->data;
9898b929 938
9783e04a 939 while (bytes_written < list->size)
9898b929 940 {
9783e04a
DM
941 bfd_vma address;
942
943 unsigned int bytes_this_chunk = list->size - bytes_written;
9898b929 944
9783e04a 945 if (bytes_this_chunk > CHUNK)
9898b929 946 {
9783e04a 947 bytes_this_chunk = CHUNK;
9898b929
JG
948 }
949
9783e04a 950 address = list->where + bytes_written;
9898b929 951
6d4f7715
ILT
952 if (! srec_write_record (abfd,
953 tdata->type,
954 address,
955 location,
956 location + bytes_this_chunk))
957 return false;
9898b929 958
9783e04a
DM
959 bytes_written += bytes_this_chunk;
960 location += bytes_this_chunk;
9898b929
JG
961 }
962
6d4f7715 963 return true;
9898b929
JG
964}
965
6d4f7715 966static boolean
57a1867e
DM
967srec_write_terminator (abfd, tdata)
968 bfd *abfd;
969 tdata_type *tdata;
9783e04a 970{
7f4c005d 971 bfd_byte buffer[2];
9783e04a 972
6d4f7715
ILT
973 return srec_write_record (abfd, 10 - tdata->type,
974 abfd->start_address, buffer, buffer);
9898b929 975}
3039e8ee 976
8f8fefcc 977
9783e04a 978
6d4f7715 979static boolean
9783e04a 980srec_write_symbols (abfd)
2c3b9e47 981 bfd *abfd;
9898b929 982{
8f8fefcc
JG
983 char buffer[MAXCHUNK];
984 /* Dump out the symbols of a bfd */
985 int i;
2f3508ad 986 int count = bfd_get_symcount (abfd);
8f8fefcc 987
2f3508ad 988 if (count)
9783e04a 989 {
6d4f7715 990 size_t len;
9783e04a
DM
991 asymbol **table = bfd_get_outsymbols (abfd);
992 sprintf (buffer, "$$ %s\r\n", abfd->filename);
8f8fefcc 993
2f3508ad 994 len = strlen (buffer);
6d4f7715
ILT
995 if (bfd_write (buffer, len, 1, abfd) != len)
996 return false;
8f8fefcc 997
2f3508ad 998 for (i = 0; i < count; i++)
9783e04a
DM
999 {
1000 asymbol *s = table[i];
8f8fefcc 1001#if 0
9783e04a 1002 int len = strlen (s->name);
8f8fefcc 1003
9783e04a 1004 /* If this symbol has a .[ocs] in it, it's probably a file name
8f8fefcc
JG
1005 and we'll output that as the module name */
1006
9783e04a
DM
1007 if (len > 3 && s->name[len - 2] == '.')
1008 {
1009 int l;
1010 sprintf (buffer, "$$ %s\r\n", s->name);
1011 l = strlen (buffer);
6d4f7715
ILT
1012 if (bfd_write (buffer, l, 1, abfd) != l)
1013 return false;
9783e04a
DM
1014 }
1015 else
8f8fefcc 1016#endif
9783e04a
DM
1017 if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
1018 && (s->flags & BSF_DEBUGGING) == 0
1019 && s->name[0] != '.'
1020 && s->name[0] != 't')
1021 {
1022 /* Just dump out non debug symbols */
ae115e51 1023 bfd_size_type l;
9783e04a
DM
1024 char buf2[40], *p;
1025
1026 sprintf_vma (buf2,
1027 s->value + s->section->output_section->lma
1028 + s->section->output_offset);
1029 p = buf2;
1030 while (p[0] == '0' && p[1] != 0)
1031 p++;
1032 sprintf (buffer, " %s $%s\r\n", s->name, p);
1033 l = strlen (buffer);
6d4f7715
ILT
1034 if (bfd_write (buffer, l, 1, abfd) != l)
1035 return false;
9783e04a
DM
1036 }
1037 }
1038 sprintf (buffer, "$$ \r\n");
2f3508ad 1039 len = strlen (buffer);
6d4f7715
ILT
1040 if (bfd_write (buffer, len, 1, abfd) != len)
1041 return false;
8f8fefcc 1042 }
6d4f7715
ILT
1043
1044 return true;
9898b929
JG
1045}
1046
9898b929 1047static boolean
9783e04a 1048internal_srec_write_object_contents (abfd, symbols)
8f8fefcc
JG
1049 bfd *abfd;
1050 int symbols;
4a81b561 1051{
9783e04a
DM
1052 tdata_type *tdata = abfd->tdata.srec_data;
1053 srec_data_list_type *list;
9898b929 1054
9783e04a 1055 if (symbols)
6d4f7715
ILT
1056 {
1057 if (! srec_write_symbols (abfd))
1058 return false;
1059 }
8f8fefcc 1060
6d4f7715
ILT
1061 if (! srec_write_header (abfd))
1062 return false;
8f8fefcc 1063
9783e04a
DM
1064 /* Now wander though all the sections provided and output them */
1065 list = tdata->head;
9898b929 1066
9783e04a 1067 while (list != (srec_data_list_type *) NULL)
9898b929 1068 {
6d4f7715
ILT
1069 if (! srec_write_section (abfd, tdata, list))
1070 return false;
9783e04a 1071 list = list->next;
9898b929 1072 }
6d4f7715 1073 return srec_write_terminator (abfd, tdata);
4a81b561
DHW
1074}
1075
8f8fefcc 1076static boolean
9783e04a 1077srec_write_object_contents (abfd)
8f8fefcc
JG
1078 bfd *abfd;
1079{
9783e04a 1080 return internal_srec_write_object_contents (abfd, 0);
8f8fefcc
JG
1081}
1082
1083static boolean
9783e04a 1084symbolsrec_write_object_contents (abfd)
8f8fefcc
JG
1085 bfd *abfd;
1086{
9783e04a 1087 return internal_srec_write_object_contents (abfd, 1);
8f8fefcc
JG
1088}
1089
9783e04a
DM
1090/*ARGSUSED*/
1091static int
57a1867e
DM
1092srec_sizeof_headers (abfd, exec)
1093 bfd *abfd;
1094 boolean exec;
39a2ce33 1095{
9783e04a 1096 return 0;
39a2ce33
SC
1097}
1098
357a1f38 1099static asymbol *
57a1867e
DM
1100srec_make_empty_symbol (abfd)
1101 bfd *abfd;
357a1f38 1102{
9783e04a
DM
1103 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
1104 if (new)
1105 new->the_bfd = abfd;
357a1f38
SC
1106 return new;
1107}
8f8fefcc 1108
7f4c005d
KR
1109/* Return the amount of memory needed to read the symbol table. */
1110
326e32d7 1111static long
9783e04a
DM
1112srec_get_symtab_upper_bound (abfd)
1113 bfd *abfd;
8f8fefcc 1114{
7f4c005d 1115 return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
8f8fefcc
JG
1116}
1117
7f4c005d
KR
1118/* Return the symbol table. */
1119
326e32d7 1120static long
57a1867e
DM
1121srec_get_symtab (abfd, alocation)
1122 bfd *abfd;
1123 asymbol **alocation;
8f8fefcc 1124{
7f4c005d
KR
1125 unsigned int symcount = bfd_get_symcount (abfd);
1126 asymbol *csymbols;
1127 unsigned int i;
1128
1129 csymbols = abfd->tdata.srec_data->csymbols;
1130 if (csymbols == NULL)
9783e04a 1131 {
7f4c005d
KR
1132 asymbol *c;
1133 struct srec_symbol *s;
1134
1135 csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
1136 if (csymbols == NULL && symcount != 0)
a9713b91 1137 return false;
7f4c005d
KR
1138 abfd->tdata.srec_data->csymbols = csymbols;
1139
1140 for (s = abfd->tdata.srec_data->symbols, c = csymbols;
1141 s != NULL;
1142 s = s->next, ++c)
1143 {
1144 c->the_bfd = abfd;
1145 c->name = s->name;
1146 c->value = s->val;
1147 c->flags = BSF_GLOBAL;
1148 c->section = bfd_abs_section_ptr;
1149 c->udata.p = NULL;
1150 }
9783e04a 1151 }
7f4c005d
KR
1152
1153 for (i = 0; i < symcount; i++)
1154 *alocation++ = csymbols++;
1155 *alocation = NULL;
1156
1157 return symcount;
8f8fefcc
JG
1158}
1159
9783e04a
DM
1160/*ARGSUSED*/
1161void
57a1867e
DM
1162srec_get_symbol_info (ignore_abfd, symbol, ret)
1163 bfd *ignore_abfd;
1164 asymbol *symbol;
1165 symbol_info *ret;
2c3b9e47
KR
1166{
1167 bfd_symbol_info (symbol, ret);
1168}
1169
9783e04a
DM
1170/*ARGSUSED*/
1171void
57a1867e
DM
1172srec_print_symbol (ignore_abfd, afile, symbol, how)
1173 bfd *ignore_abfd;
1174 PTR afile;
1175 asymbol *symbol;
1176 bfd_print_symbol_type how;
9783e04a
DM
1177{
1178 FILE *file = (FILE *) afile;
1179 switch (how)
1180 {
1181 case bfd_print_symbol_name:
1182 fprintf (file, "%s", symbol->name);
1183 break;
1184 default:
1185 bfd_print_symbol_vandf ((PTR) file, symbol);
1186 fprintf (file, " %-5s %s",
1187 symbol->section->name,
1188 symbol->name);
8f8fefcc 1189
9783e04a 1190 }
8f8fefcc
JG
1191}
1192
6812b607
ILT
1193#define srec_close_and_cleanup _bfd_generic_close_and_cleanup
1194#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1195#define srec_new_section_hook _bfd_generic_new_section_hook
9872a49c 1196
6812b607
ILT
1197#define srec_bfd_is_local_label bfd_generic_is_local_label
1198#define srec_get_lineno _bfd_nosymbols_get_lineno
1199#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
1200#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
c3246d9b
ILT
1201#define srec_read_minisymbols _bfd_generic_read_minisymbols
1202#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
d0ec7a8e 1203
7f4c005d
KR
1204#define srec_get_reloc_upper_bound \
1205 ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
1206#define srec_canonicalize_reloc \
1207 ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
1208#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1209
a9713b91
ILT
1210#define srec_get_section_contents_in_window \
1211 _bfd_generic_get_section_contents_in_window
1212
7f4c005d
KR
1213#define srec_set_arch_mach bfd_default_set_arch_mach
1214
6812b607
ILT
1215#define srec_bfd_get_relocated_section_contents \
1216 bfd_generic_get_relocated_section_contents
294eaca4 1217#define srec_bfd_relax_section bfd_generic_relax_section
4c3721d5
ILT
1218#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1219#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
1220#define srec_bfd_final_link _bfd_generic_final_link
c3246d9b 1221#define srec_bfd_link_split_section _bfd_generic_link_split_section
3039e8ee 1222
2f3508ad 1223const bfd_target srec_vec =
4a81b561 1224{
9783e04a
DM
1225 "srec", /* name */
1226 bfd_target_srec_flavour,
1227 true, /* target byte order */
1228 true, /* target headers byte order */
1229 (HAS_RELOC | EXEC_P | /* object flags */
1230 HAS_LINENO | HAS_DEBUG |
1231 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1232 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1233 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1234 0, /* leading underscore */
1235 ' ', /* ar_pad_char */
1236 16, /* ar_max_namelen */
9783e04a
DM
1237 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1238 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1239 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1240 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1241 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1242 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
9898b929
JG
1243
1244 {
9783e04a
DM
1245 _bfd_dummy_target,
1246 srec_object_p, /* bfd_check_format */
2f3508ad
ILT
1247 _bfd_dummy_target,
1248 _bfd_dummy_target,
9898b929
JG
1249 },
1250 {
9783e04a
DM
1251 bfd_false,
1252 srec_mkobject,
1253 _bfd_generic_mkarchive,
1254 bfd_false,
9898b929
JG
1255 },
1256 { /* bfd_write_contents */
9783e04a
DM
1257 bfd_false,
1258 srec_write_object_contents,
1259 _bfd_write_archive_contents,
1260 bfd_false,
9898b929 1261 },
6812b607
ILT
1262
1263 BFD_JUMP_TABLE_GENERIC (srec),
1264 BFD_JUMP_TABLE_COPY (_bfd_generic),
1265 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1266 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1267 BFD_JUMP_TABLE_SYMBOLS (srec),
7f4c005d 1268 BFD_JUMP_TABLE_RELOCS (srec),
6812b607
ILT
1269 BFD_JUMP_TABLE_WRITE (srec),
1270 BFD_JUMP_TABLE_LINK (srec),
dfc1c006 1271 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6812b607
ILT
1272
1273 (PTR) 0
9783e04a 1274};
9898b929 1275
8f8fefcc
JG
1276
1277
2f3508ad 1278const bfd_target symbolsrec_vec =
8f8fefcc 1279{
9783e04a
DM
1280 "symbolsrec", /* name */
1281 bfd_target_srec_flavour,
1282 true, /* target byte order */
1283 true, /* target headers byte order */
1284 (HAS_RELOC | EXEC_P | /* object flags */
1285 HAS_LINENO | HAS_DEBUG |
1286 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1287 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1288 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1289 0, /* leading underscore */
1290 ' ', /* ar_pad_char */
1291 16, /* ar_max_namelen */
9783e04a
DM
1292 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1293 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1294 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1295 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1296 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1297 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
8f8fefcc
JG
1298
1299 {
9783e04a
DM
1300 _bfd_dummy_target,
1301 symbolsrec_object_p, /* bfd_check_format */
2f3508ad
ILT
1302 _bfd_dummy_target,
1303 _bfd_dummy_target,
8f8fefcc
JG
1304 },
1305 {
9783e04a
DM
1306 bfd_false,
1307 srec_mkobject,
1308 _bfd_generic_mkarchive,
1309 bfd_false,
8f8fefcc
JG
1310 },
1311 { /* bfd_write_contents */
9783e04a
DM
1312 bfd_false,
1313 symbolsrec_write_object_contents,
1314 _bfd_write_archive_contents,
1315 bfd_false,
8f8fefcc 1316 },
6812b607
ILT
1317
1318 BFD_JUMP_TABLE_GENERIC (srec),
1319 BFD_JUMP_TABLE_COPY (_bfd_generic),
1320 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1321 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1322 BFD_JUMP_TABLE_SYMBOLS (srec),
7f4c005d 1323 BFD_JUMP_TABLE_RELOCS (srec),
6812b607
ILT
1324 BFD_JUMP_TABLE_WRITE (srec),
1325 BFD_JUMP_TABLE_LINK (srec),
dfc1c006 1326 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6812b607 1327
9783e04a
DM
1328 (PTR) 0
1329};
This page took 0.294143 seconds and 4 git commands to generate.