Make all callers of malloc or realloc (including via obstacks)
[deliverable/binutils-gdb.git] / bfd / srec.c
CommitLineData
4a8db330 1/* BFD back-end for s-record objects.
9783e04a 2 Copyright 1990, 1991, 1992, 1993, 1994 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
JG
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
DHW
108#include "libbfd.h"
109
5f9ca960 110/* Macros for converting between hex and binary */
4a81b561 111
3039e8ee 112static CONST char digs[] = "0123456789ABCDEF";
5f9ca960 113
9783e04a 114static char hex_value[1 + (unsigned char) ~0];
9898b929 115
9898b929 116#define NOT_HEX 20
5f9ca960 117#define NIBBLE(x) hex_value[(unsigned char)(x)]
9898b929 118#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
5f9ca960
JG
119#define TOHEX(d, x, ch) \
120 d[1] = digs[(x) & 0xf]; \
121 d[0] = digs[((x)>>4)&0xf]; \
122 ch += ((x) & 0xff);
123#define ISHEX(x) (hex_value[(unsigned char)(x)] != NOT_HEX)
4a81b561 124
4a81b561 125
9898b929 126
e98e6ec1 127static void
9783e04a 128DEFUN_VOID (srec_init)
9898b929 129{
9783e04a
DM
130 unsigned int i;
131 static boolean inited = false;
132
133 if (inited == false)
9898b929 134 {
9783e04a
DM
135
136 inited = true;
137
138 for (i = 0; i < sizeof (hex_value); i++)
9898b929 139 {
9783e04a 140 hex_value[i] = NOT_HEX;
9898b929 141 }
9783e04a
DM
142
143 for (i = 0; i < 10; i++)
9898b929 144 {
9783e04a
DM
145 hex_value[i + '0'] = i;
146
9898b929 147 }
9783e04a 148 for (i = 0; i < 6; i++)
9898b929 149 {
9783e04a
DM
150 hex_value[i + 'a'] = i + 10;
151 hex_value[i + 'A'] = i + 10;
9898b929 152 }
9783e04a 153 }
9898b929
JG
154}
155
4a81b561
DHW
156
157/* The maximum number of bytes on a line is FF */
9783e04a 158#define MAXCHUNK 0xff
4a81b561 159/* The number of bytes we fit onto a line on output */
9898b929
JG
160#define CHUNK 21
161
162/* We cannot output our srecords as we see them, we have to glue them
163 together, this is done in this structure : */
164
165struct srec_data_list_struct
166{
9783e04a
DM
167 unsigned char *data;
168 bfd_vma where;
169 bfd_size_type size;
170 struct srec_data_list_struct *next;
171
8f8fefcc 172
9783e04a 173};
9898b929
JG
174typedef struct srec_data_list_struct srec_data_list_type;
175
4a81b561 176
9783e04a
DM
177typedef struct srec_data_struct
178 {
179 srec_data_list_type *head;
9898b929 180 unsigned int type;
9783e04a 181
8f8fefcc
JG
182 int done_symbol_read;
183 int count;
184 asymbol *symbols;
185 char *strings;
186 int symbol_idx;
187 int string_size;
188 int string_idx;
9783e04a
DM
189 }
190tdata_type;
9898b929
JG
191
192
9783e04a 193/*
8f8fefcc 194 called once per input S-Record, used to work out vma and size of data.
4a81b561
DHW
195 */
196
9783e04a 197static bfd_vma low, high;
9898b929 198
9783e04a 199/*ARGSUSED*/
8f8fefcc 200static void
9783e04a
DM
201size_symbols (abfd, buf, len, val)
202 bfd *abfd;
203 char *buf;
204 int len;
205 int val;
206{
207 abfd->symcount++;
208 abfd->tdata.srec_data->string_size += len + 1;
8f8fefcc
JG
209}
210
211static void
9783e04a
DM
212fillup_symbols (abfd, buf, len, val)
213 bfd *abfd;
214 char *buf;
215 int len;
216 int val;
8f8fefcc
JG
217{
218 if (!abfd->tdata.srec_data->done_symbol_read)
8f8fefcc 219 {
9783e04a
DM
220 asymbol *p;
221 if (abfd->tdata.srec_data->symbols == 0)
222 {
223 abfd->tdata.srec_data->symbols = (asymbol *) bfd_alloc (abfd, abfd->symcount * sizeof (asymbol));
224 abfd->tdata.srec_data->strings = (char *) bfd_alloc (abfd, abfd->tdata.srec_data->string_size);
225 if (!abfd->tdata.srec_data->symbols || !abfd->tdata.srec_data->strings)
226 {
227 bfd_error = no_memory;
228 abort (); /* FIXME */
229 }
230 abfd->tdata.srec_data->symbol_idx = 0;
231 abfd->tdata.srec_data->string_idx = 0;
232 }
8f8fefcc 233
9783e04a
DM
234 p = abfd->tdata.srec_data->symbols + abfd->tdata.srec_data->symbol_idx++;
235 p->the_bfd = abfd;
236 p->name = abfd->tdata.srec_data->strings + abfd->tdata.srec_data->string_idx;
237 memcpy ((char *) (p->name), buf, len + 1);
238 abfd->tdata.srec_data->string_idx += len + 1;
239 p->value = val;
240 p->flags = BSF_EXPORT | BSF_GLOBAL;
241 p->section = &bfd_abs_section;
242 p->udata = 0;
243 }
8f8fefcc 244}
9783e04a 245/*ARGSUSED*/
4a81b561 246static void
9783e04a
DM
247DEFUN (size_srec, (abfd, section, address, raw, length),
248 bfd * abfd AND
249 asection * section AND
250 bfd_vma address AND
251 bfd_byte * raw AND
252 unsigned int length)
4a81b561 253{
357a1f38
SC
254 if (address < low)
255 low = address;
9783e04a
DM
256 if (address + length > high)
257 high = address + length - 1;
4a81b561
DHW
258}
259
357a1f38 260
4a81b561 261/*
8f8fefcc 262 called once per input S-Record, copies data from input into bfd_alloc'd area
4a81b561
DHW
263 */
264
9783e04a 265/*ARGSUSED*/
4a81b561 266static void
9783e04a
DM
267DEFUN (fillup, (abfd, section, address, raw, length),
268 bfd * abfd AND
269 asection * section AND
270 bfd_vma address AND
271 bfd_byte * raw AND
272 unsigned int length)
273{
274 unsigned int i;
275 bfd_byte *dst =
276 (bfd_byte *) (section->used_by_bfd) + address - section->vma;
277 /* length -1 because we don't read in the checksum */
278 for (i = 0; i < length - 1; i++)
279 {
280 *dst = HEX (raw);
281 dst++;
282 raw += 2;
283 }
4a81b561
DHW
284}
285
8f8fefcc 286/* Pass over an S-Record file, calling one of the above functions on each
387cbb2b
JG
287 record. */
288
9783e04a
DM
289static int
290white (x)
291 char x;
8f8fefcc 292{
9783e04a 293 return (x == ' ' || x == '\t' || x == '\n' || x == '\r');
8f8fefcc
JG
294}
295static int
9783e04a
DM
296skipwhite (src, abfd)
297 char *src;
298 bfd *abfd;
8f8fefcc
JG
299{
300 int eof = 0;
9783e04a
DM
301 while (white (*src) && !eof)
302 {
303 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
304 }
8f8fefcc
JG
305 return eof;
306}
307
308static boolean
9783e04a
DM
309DEFUN (srec_mkobject, (abfd),
310 bfd * abfd)
8f8fefcc 311{
9783e04a
DM
312 if (abfd->tdata.srec_data == 0)
313 {
314 tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
315 if (!tdata)
316 {
317 bfd_error = no_memory;
318 return false;
319 }
320 abfd->tdata.srec_data = tdata;
321 tdata->type = 1;
322 tdata->head = (srec_data_list_type *) NULL;
323 }
8f8fefcc 324 return true;
9783e04a 325
8f8fefcc
JG
326}
327
9783e04a
DM
328static void
329pass_over (abfd, func, symbolfunc, section)
4c3721d5 330 bfd *abfd;
9783e04a
DM
331 void (*func) ();
332 void (*symbolfunc) ();
4c3721d5 333 asection *section;
4a81b561 334{
8f8fefcc
JG
335 unsigned int bytes_on_line;
336 boolean eof = false;
e98e6ec1 337
9783e04a 338 srec_mkobject (abfd);
8f8fefcc 339 /* To the front of the file */
9783e04a 340 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
8f8fefcc 341 while (eof == false)
4a81b561 342 {
9783e04a
DM
343 char buffer[MAXCHUNK];
344 char *src = buffer;
345 char type;
346 bfd_vma address = 0;
347
348 /* Find first 'S' or $ */
349 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
350 switch (*src)
8f8fefcc 351 {
9783e04a
DM
352 default:
353 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
354 if (eof)
355 return;
356 break;
357
358 case '$':
359 /* Inside a symbol definition - just ignore the module name */
360 while (*src != '\n' && !eof)
361 {
362 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
363 }
364 break;
365
366 case ' ':
367 /* spaces - maybe just before a symbol */
368 while (*src != '\n' && *src != '\r' && white (*src))
369 {
370 eof = skipwhite (src, abfd);
4c3721d5 371
4c3721d5 372 {
9783e04a
DM
373 int val = 0;
374 int slen = 0;
375 char symbol[MAXCHUNK];
376
377 /* get the symbol part */
378 while (!eof && !white (*src) && slen < MAXCHUNK)
379 {
380 symbol[slen++] = *src;
381 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
382 }
383 symbol[slen] = 0;
384 eof = skipwhite (src, abfd);
385 /* skip the $ for the hex value */
386 if (*src == '$')
387 {
388 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
389 }
390
391 /* Scan off the hex number */
392 while (isxdigit (*src))
393 {
394 val *= 16;
395 if (isdigit (*src))
396 val += *src - '0';
397 else if (isupper (*src))
398 {
399 val += *src - 'A' + 10;
400 }
401 else
402 {
403 val += *src - 'a' + 10;
404 }
405 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
406 }
407 symbolfunc (abfd, symbol, slen, val);
4c3721d5 408 }
9783e04a
DM
409 }
410 break;
411 case 'S':
412 src++;
413
414 /* Fetch the type and the length */
415 bfd_read (src, 1, 3, abfd);
416
417 type = *src++;
418
419 if (!ISHEX (src[0]) || !ISHEX (src[1]))
420 break;
421
422 bytes_on_line = HEX (src);
423
424 if (bytes_on_line > MAXCHUNK / 2)
425 break;
426 src += 2;
427
428 bfd_read (src, 1, bytes_on_line * 2, abfd);
429
430 switch (type)
431 {
432 case '0':
433 case '5':
434 /* Prologue - ignore */
435 break;
436 case '3':
437 address = HEX (src);
438 src += 2;
439 bytes_on_line--;
440
441 case '2':
442 address = HEX (src) | (address << 8);
443 src += 2;
444 bytes_on_line--;
445 case '1':
446 address = HEX (src) | (address << 8);
447 src += 2;
448 address = HEX (src) | (address << 8);
449 src += 2;
450 bytes_on_line -= 2;
451 func (abfd, section, address, src, bytes_on_line);
452 break;
453 default:
454 return;
455 }
8f8fefcc 456 }
4a81b561 457 }
9898b929 458
4a81b561
DHW
459}
460
8f8fefcc 461static bfd_target *
9783e04a
DM
462object_p (abfd)
463 bfd *abfd;
8f8fefcc
JG
464{
465 asection *section;
9783e04a 466 /* We create one section called .text for all the contents,
8f8fefcc 467 and allocate enough room for the entire file. */
9783e04a
DM
468
469 section = bfd_make_section (abfd, ".text");
8f8fefcc
JG
470 section->_raw_size = 0;
471 section->vma = 0xffffffff;
472 low = 0xffffffff;
473 high = 0;
9783e04a 474 pass_over (abfd, size_srec, size_symbols, section);
8f8fefcc
JG
475 section->_raw_size = high - low;
476 section->vma = low;
477 section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
4a81b561 478
8f8fefcc 479 if (abfd->symcount)
9783e04a 480 abfd->flags |= HAS_SYMS;
8f8fefcc
JG
481 return abfd->xvec;
482}
9898b929
JG
483
484static bfd_target *
9783e04a
DM
485DEFUN (srec_object_p, (abfd),
486 bfd * abfd)
4a81b561 487{
387cbb2b 488 char b[4];
8f8fefcc 489
9783e04a 490 srec_init ();
9898b929 491
9783e04a
DM
492 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
493 bfd_read (b, 1, 4, abfd);
494
495 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
496 return (bfd_target *) NULL;
497
498 /* We create one section called .text for all the contents,
387cbb2b 499 and allocate enough room for the entire file. */
4a81b561 500
9783e04a 501 return object_p (abfd);
8f8fefcc
JG
502}
503
504
505static bfd_target *
9783e04a
DM
506DEFUN (symbolsrec_object_p, (abfd),
507 bfd * abfd)
8f8fefcc
JG
508{
509 char b[4];
510
9783e04a
DM
511 srec_init ();
512
513 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
514 bfd_read (b, 1, 4, abfd);
8f8fefcc
JG
515
516 if (b[0] != '$' || b[1] != '$')
9783e04a 517 return (bfd_target *) NULL;
8f8fefcc 518
9783e04a 519 return object_p (abfd);
4a81b561
DHW
520}
521
522
4a81b561 523static boolean
9783e04a
DM
524DEFUN (srec_get_section_contents, (abfd, section, location, offset, count),
525 bfd * abfd AND
526 asection * section AND
527 PTR location AND
528 file_ptr offset AND
529 bfd_size_type count)
530{
531 if (section->used_by_bfd == (PTR) NULL)
9898b929 532 {
9783e04a
DM
533 section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size);
534 if (!section->used_by_bfd)
535 {
536 bfd_error = no_memory;
537 return false;
538 }
539
540 pass_over (abfd, fillup, fillup_symbols, section);
9898b929 541 }
9783e04a
DM
542 memcpy ((PTR) location,
543 (PTR) ((char *) (section->used_by_bfd) + offset),
544 count);
545 return true;
4a81b561 546}
9783e04a 547
4a81b561
DHW
548
549
550boolean
9783e04a
DM
551DEFUN (srec_set_arch_mach, (abfd, arch, machine),
552 bfd * abfd AND
553 enum bfd_architecture arch AND
554 unsigned long machine)
4a81b561 555{
9783e04a 556 return bfd_default_set_arch_mach (abfd, arch, machine);
4a81b561
DHW
557}
558
559
9898b929
JG
560/* we have to save up all the Srecords for a splurge before output,
561 also remember */
4a81b561 562
9898b929 563static boolean
9783e04a
DM
564DEFUN (srec_set_section_contents, (abfd, section, location, offset, bytes_to_do),
565 bfd * abfd AND
566 sec_ptr section AND
567 PTR location AND
568 file_ptr offset AND
569 bfd_size_type bytes_to_do)
570{
571 tdata_type *tdata = abfd->tdata.srec_data;
294eaca4 572 srec_data_list_type *entry = (srec_data_list_type *)
9783e04a
DM
573 bfd_alloc (abfd, sizeof (srec_data_list_type));
574
575 if (!entry)
576 {
577 bfd_error = no_memory;
578 return false;
579 }
8f8fefcc 580
294eaca4 581 if ((section->flags & SEC_ALLOC)
9783e04a 582 && (section->flags & SEC_LOAD))
9898b929 583 {
9783e04a
DM
584 unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do);
585 if (!data)
586 {
587 bfd_error = no_memory;
588 return false;
589 }
590 memcpy (data, location, bytes_to_do);
9898b929 591
9783e04a 592 if ((section->lma + offset + bytes_to_do) <= 0xffff)
8f8fefcc 593 {
9898b929 594
8f8fefcc 595 }
9783e04a
DM
596 else if ((section->lma + offset + bytes_to_do) <= 0xffffff
597 && tdata->type < 2)
8f8fefcc
JG
598 {
599 tdata->type = 2;
600 }
9783e04a 601 else
8f8fefcc
JG
602 {
603 tdata->type = 3;
604 }
605
606 entry->data = data;
607 entry->where = section->lma + offset;
608 entry->size = bytes_to_do;
609 entry->next = tdata->head;
610 tdata->head = entry;
611 }
9783e04a 612 return true;
9898b929
JG
613}
614
615/* Write a record of type, of the supplied number of bytes. The
616 supplied bytes and length don't have a checksum. That's worked out
617 here
618*/
619static
9783e04a
DM
620void
621DEFUN (srec_write_record, (abfd, type, address, data, end),
622 bfd * abfd AND
623 char type AND
624 bfd_vma address AND
625 CONST unsigned char *data AND
626 CONST unsigned char *end)
627
628{
629 char buffer[MAXCHUNK];
630
631 unsigned int check_sum = 0;
632 CONST unsigned char *src = data;
633 char *dst = buffer;
634 char *length;
635
636
637 *dst++ = 'S';
638 *dst++ = '0' + type;
639
640 length = dst;
641 dst += 2; /* leave room for dst*/
642
643 switch (type)
9898b929 644 {
9783e04a
DM
645 case 3:
646 case 7:
647 TOHEX (dst, (address >> 24), check_sum);
648 dst += 2;
649 case 8:
650 case 2:
651 TOHEX (dst, (address >> 16), check_sum);
652 dst += 2;
653 case 9:
654 case 1:
655 case 0:
656 TOHEX (dst, (address >> 8), check_sum);
657 dst += 2;
658 TOHEX (dst, (address), check_sum);
659 dst += 2;
660 break;
4a81b561 661
4a81b561 662 }
9783e04a 663 for (src = data; src < end; src++)
9898b929 664 {
9783e04a
DM
665 TOHEX (dst, *src, check_sum);
666 dst += 2;
4a81b561
DHW
667 }
668
9783e04a
DM
669 /* Fill in the length */
670 TOHEX (length, (dst - length) / 2, check_sum);
671 check_sum &= 0xff;
672 check_sum = 255 - check_sum;
673 TOHEX (dst, check_sum, check_sum);
674 dst += 2;
675
676 *dst++ = '\r';
677 *dst++ = '\n';
678 bfd_write ((PTR) buffer, 1, dst - buffer, abfd);
9898b929 679}
4a81b561 680
4a81b561 681
4a81b561 682
9898b929 683static void
9783e04a
DM
684DEFUN (srec_write_header, (abfd),
685 bfd * abfd)
9898b929 686{
9783e04a
DM
687 unsigned char buffer[MAXCHUNK];
688 unsigned char *dst = buffer;
689 unsigned int i;
4a81b561 690
9783e04a
DM
691 /* I'll put an arbitary 40 char limit on header size */
692 for (i = 0; i < 40 && abfd->filename[i]; i++)
9898b929 693 {
9783e04a 694 *dst++ = abfd->filename[i];
9898b929 695 }
9783e04a 696 srec_write_record (abfd, 0, 0, buffer, dst);
4a81b561
DHW
697}
698
9898b929 699static void
9783e04a
DM
700DEFUN (srec_write_section, (abfd, tdata, list),
701 bfd * abfd AND
702 tdata_type * tdata AND
703 srec_data_list_type * list)
9898b929 704{
9783e04a
DM
705 unsigned int bytes_written = 0;
706 unsigned char *location = list->data;
9898b929 707
9783e04a 708 while (bytes_written < list->size)
9898b929 709 {
9783e04a
DM
710 bfd_vma address;
711
712 unsigned int bytes_this_chunk = list->size - bytes_written;
9898b929 713
9783e04a 714 if (bytes_this_chunk > CHUNK)
9898b929 715 {
9783e04a 716 bytes_this_chunk = CHUNK;
9898b929
JG
717 }
718
9783e04a 719 address = list->where + bytes_written;
9898b929 720
9783e04a
DM
721 srec_write_record (abfd,
722 tdata->type,
723 address,
724 location,
725 location + bytes_this_chunk);
9898b929 726
9783e04a
DM
727 bytes_written += bytes_this_chunk;
728 location += bytes_this_chunk;
9898b929
JG
729 }
730
731}
732
733static void
9783e04a
DM
734DEFUN (srec_write_terminator, (abfd, tdata),
735 bfd * abfd AND
736 tdata_type * tdata)
737{
738 unsigned char buffer[2];
739
740 srec_write_record (abfd, 10 - tdata->type,
741 abfd->start_address, buffer, buffer);
9898b929 742}
3039e8ee 743
8f8fefcc 744
9783e04a 745
8f8fefcc 746static void
9783e04a 747srec_write_symbols (abfd)
2c3b9e47 748 bfd *abfd;
9898b929 749{
8f8fefcc
JG
750 char buffer[MAXCHUNK];
751 /* Dump out the symbols of a bfd */
752 int i;
9783e04a 753 int len = bfd_get_symcount (abfd);
8f8fefcc 754
9783e04a
DM
755 if (len)
756 {
757 asymbol **table = bfd_get_outsymbols (abfd);
758 sprintf (buffer, "$$ %s\r\n", abfd->filename);
8f8fefcc 759
9783e04a 760 bfd_write (buffer, strlen (buffer), 1, abfd);
8f8fefcc 761
9783e04a
DM
762 for (i = 0; i < len; i++)
763 {
764 asymbol *s = table[i];
8f8fefcc 765#if 0
9783e04a 766 int len = strlen (s->name);
8f8fefcc 767
9783e04a 768 /* If this symbol has a .[ocs] in it, it's probably a file name
8f8fefcc
JG
769 and we'll output that as the module name */
770
9783e04a
DM
771 if (len > 3 && s->name[len - 2] == '.')
772 {
773 int l;
774 sprintf (buffer, "$$ %s\r\n", s->name);
775 l = strlen (buffer);
776 bfd_write (buffer, l, 1, abfd);
777 }
778 else
8f8fefcc 779#endif
9783e04a
DM
780 if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
781 && (s->flags & BSF_DEBUGGING) == 0
782 && s->name[0] != '.'
783 && s->name[0] != 't')
784 {
785 /* Just dump out non debug symbols */
786
787 int l;
788 char buf2[40], *p;
789
790 sprintf_vma (buf2,
791 s->value + s->section->output_section->lma
792 + s->section->output_offset);
793 p = buf2;
794 while (p[0] == '0' && p[1] != 0)
795 p++;
796 sprintf (buffer, " %s $%s\r\n", s->name, p);
797 l = strlen (buffer);
798 bfd_write (buffer, l, 1, abfd);
799 }
800 }
801 sprintf (buffer, "$$ \r\n");
802 bfd_write (buffer, strlen (buffer), 1, abfd);
8f8fefcc 803 }
9898b929
JG
804}
805
9898b929 806static boolean
9783e04a 807internal_srec_write_object_contents (abfd, symbols)
8f8fefcc
JG
808 bfd *abfd;
809 int symbols;
4a81b561 810{
9783e04a
DM
811 tdata_type *tdata = abfd->tdata.srec_data;
812 srec_data_list_type *list;
9898b929 813
9783e04a
DM
814 if (symbols)
815 srec_write_symbols (abfd);
8f8fefcc 816
9783e04a 817 srec_write_header (abfd);
8f8fefcc 818
9783e04a
DM
819 /* Now wander though all the sections provided and output them */
820 list = tdata->head;
9898b929 821
9783e04a 822 while (list != (srec_data_list_type *) NULL)
9898b929 823 {
9783e04a
DM
824 srec_write_section (abfd, tdata, list);
825 list = list->next;
9898b929 826 }
9783e04a
DM
827 srec_write_terminator (abfd, tdata);
828 return true;
4a81b561
DHW
829}
830
8f8fefcc 831static boolean
9783e04a 832srec_write_object_contents (abfd)
8f8fefcc
JG
833 bfd *abfd;
834{
9783e04a 835 return internal_srec_write_object_contents (abfd, 0);
8f8fefcc
JG
836}
837
838static boolean
9783e04a 839symbolsrec_write_object_contents (abfd)
8f8fefcc
JG
840 bfd *abfd;
841{
9783e04a 842 return internal_srec_write_object_contents (abfd, 1);
8f8fefcc
JG
843}
844
9783e04a
DM
845/*ARGSUSED*/
846static int
847DEFUN (srec_sizeof_headers, (abfd, exec),
848 bfd * abfd AND
849 boolean exec)
39a2ce33 850{
9783e04a 851 return 0;
39a2ce33
SC
852}
853
357a1f38 854static asymbol *
9783e04a
DM
855DEFUN (srec_make_empty_symbol, (abfd),
856 bfd * abfd)
357a1f38 857{
9783e04a
DM
858 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
859 if (new)
860 new->the_bfd = abfd;
357a1f38
SC
861 return new;
862}
8f8fefcc
JG
863
864static unsigned int
9783e04a
DM
865srec_get_symtab_upper_bound (abfd)
866 bfd *abfd;
8f8fefcc
JG
867{
868 /* Read in all the info */
9783e04a
DM
869 srec_get_section_contents (abfd, abfd->sections, 0, 0, 0);
870 return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
8f8fefcc
JG
871}
872
873static unsigned int
9783e04a
DM
874DEFUN (srec_get_symtab, (abfd, alocation),
875 bfd * abfd AND
876 asymbol ** alocation)
8f8fefcc
JG
877{
878 int lim = abfd->symcount;
879 int i;
9783e04a
DM
880 for (i = 0; i < lim; i++)
881 {
882 alocation[i] = abfd->tdata.srec_data->symbols + i;
883 }
8f8fefcc
JG
884 alocation[i] = 0;
885 return lim;
886}
887
9783e04a
DM
888/*ARGSUSED*/
889void
890DEFUN (srec_get_symbol_info, (ignore_abfd, symbol, ret),
891 bfd * ignore_abfd AND
892 asymbol * symbol AND
893 symbol_info * ret)
2c3b9e47
KR
894{
895 bfd_symbol_info (symbol, ret);
896}
897
9783e04a
DM
898/*ARGSUSED*/
899void
900DEFUN (srec_print_symbol, (ignore_abfd, afile, symbol, how),
901 bfd * ignore_abfd AND
902 PTR afile AND
903 asymbol * symbol AND
904 bfd_print_symbol_type how)
905{
906 FILE *file = (FILE *) afile;
907 switch (how)
908 {
909 case bfd_print_symbol_name:
910 fprintf (file, "%s", symbol->name);
911 break;
912 default:
913 bfd_print_symbol_vandf ((PTR) file, symbol);
914 fprintf (file, " %-5s %s",
915 symbol->section->name,
916 symbol->name);
8f8fefcc 917
9783e04a 918 }
8f8fefcc
JG
919}
920
6f715d66
SC
921#define FOO PROTO
922#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
8f8fefcc 923
6f715d66
SC
924#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
925#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
357a1f38 926
8f8fefcc 927
d0ec7a8e 928
6f715d66
SC
929#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
930#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
931#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0
9872a49c 932
d0ec7a8e
SC
933
934#define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
935#define srec_core_file_failing_signal (int (*)())bfd_0
6f715d66 936#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
d0ec7a8e
SC
937#define srec_slurp_armap bfd_true
938#define srec_slurp_extended_name_table bfd_true
939#define srec_truncate_arname (void (*)())bfd_nullvoidptr
9898b929 940#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
d0ec7a8e 941#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
2b1d8a50 942#define srec_close_and_cleanup bfd_generic_close_and_cleanup
6f715d66
SC
943#define srec_bfd_debug_info_start bfd_void
944#define srec_bfd_debug_info_end bfd_void
945#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void
e98e6ec1 946#define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
294eaca4 947#define srec_bfd_relax_section bfd_generic_relax_section
8f8fefcc
JG
948#define srec_bfd_reloc_type_lookup \
949 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
950#define srec_bfd_make_debug_symbol \
951 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
4c3721d5
ILT
952#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
953#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
954#define srec_bfd_final_link _bfd_generic_final_link
3039e8ee 955
4a81b561
DHW
956bfd_target srec_vec =
957{
9783e04a
DM
958 "srec", /* name */
959 bfd_target_srec_flavour,
960 true, /* target byte order */
961 true, /* target headers byte order */
962 (HAS_RELOC | EXEC_P | /* object flags */
963 HAS_LINENO | HAS_DEBUG |
964 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
965 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
966 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
967 0, /* leading underscore */
968 ' ', /* ar_pad_char */
969 16, /* ar_max_namelen */
970 1, /* minimum alignment */
971 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
972 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
973 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
974 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
975 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
976 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
9898b929
JG
977
978 {
9783e04a
DM
979 _bfd_dummy_target,
980 srec_object_p, /* bfd_check_format */
981 (struct bfd_target * (*)()) bfd_nullvoidptr,
982 (struct bfd_target * (*)()) bfd_nullvoidptr,
9898b929
JG
983 },
984 {
9783e04a
DM
985 bfd_false,
986 srec_mkobject,
987 _bfd_generic_mkarchive,
988 bfd_false,
9898b929
JG
989 },
990 { /* bfd_write_contents */
9783e04a
DM
991 bfd_false,
992 srec_write_object_contents,
993 _bfd_write_archive_contents,
994 bfd_false,
9898b929 995 },
9783e04a
DM
996 JUMP_TABLE (srec)
997};
9898b929 998
8f8fefcc
JG
999
1000
1001bfd_target symbolsrec_vec =
1002{
9783e04a
DM
1003 "symbolsrec", /* name */
1004 bfd_target_srec_flavour,
1005 true, /* target byte order */
1006 true, /* target headers byte order */
1007 (HAS_RELOC | EXEC_P | /* object flags */
1008 HAS_LINENO | HAS_DEBUG |
1009 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1010 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1011 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1012 0, /* leading underscore */
1013 ' ', /* ar_pad_char */
1014 16, /* ar_max_namelen */
1015 1, /* minimum alignment */
1016 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1017 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1018 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1019 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1020 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1021 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
8f8fefcc
JG
1022
1023 {
9783e04a
DM
1024 _bfd_dummy_target,
1025 symbolsrec_object_p, /* bfd_check_format */
1026 (struct bfd_target * (*)()) bfd_nullvoidptr,
1027 (struct bfd_target * (*)()) bfd_nullvoidptr,
8f8fefcc
JG
1028 },
1029 {
9783e04a
DM
1030 bfd_false,
1031 srec_mkobject,
1032 _bfd_generic_mkarchive,
1033 bfd_false,
8f8fefcc
JG
1034 },
1035 { /* bfd_write_contents */
9783e04a
DM
1036 bfd_false,
1037 symbolsrec_write_object_contents,
1038 _bfd_write_archive_contents,
1039 bfd_false,
8f8fefcc 1040 },
9783e04a
DM
1041 JUMP_TABLE (srec),
1042 (PTR) 0
1043};
This page took 0.158963 seconds and 4 git commands to generate.