* config/i386/tm-i386v4.h (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP,
[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 {
5e808126 227 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
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 {
5e808126 317 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
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 352 default:
9783e04a
DM
353 if (eof)
354 return;
355 break;
356
357 case '$':
358 /* Inside a symbol definition - just ignore the module name */
359 while (*src != '\n' && !eof)
360 {
361 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
362 }
363 break;
364
365 case ' ':
366 /* spaces - maybe just before a symbol */
367 while (*src != '\n' && *src != '\r' && white (*src))
368 {
369 eof = skipwhite (src, abfd);
4c3721d5 370
4c3721d5 371 {
9783e04a
DM
372 int val = 0;
373 int slen = 0;
374 char symbol[MAXCHUNK];
375
376 /* get the symbol part */
377 while (!eof && !white (*src) && slen < MAXCHUNK)
378 {
379 symbol[slen++] = *src;
380 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
381 }
382 symbol[slen] = 0;
383 eof = skipwhite (src, abfd);
384 /* skip the $ for the hex value */
385 if (*src == '$')
386 {
387 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
388 }
389
390 /* Scan off the hex number */
391 while (isxdigit (*src))
392 {
393 val *= 16;
394 if (isdigit (*src))
395 val += *src - '0';
396 else if (isupper (*src))
397 {
398 val += *src - 'A' + 10;
399 }
400 else
401 {
402 val += *src - 'a' + 10;
403 }
404 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
405 }
406 symbolfunc (abfd, symbol, slen, val);
4c3721d5 407 }
9783e04a
DM
408 }
409 break;
410 case 'S':
411 src++;
412
413 /* Fetch the type and the length */
414 bfd_read (src, 1, 3, abfd);
415
416 type = *src++;
417
418 if (!ISHEX (src[0]) || !ISHEX (src[1]))
419 break;
420
421 bytes_on_line = HEX (src);
422
423 if (bytes_on_line > MAXCHUNK / 2)
424 break;
425 src += 2;
426
427 bfd_read (src, 1, bytes_on_line * 2, abfd);
428
429 switch (type)
430 {
431 case '0':
432 case '5':
433 /* Prologue - ignore */
434 break;
435 case '3':
436 address = HEX (src);
437 src += 2;
438 bytes_on_line--;
439
440 case '2':
441 address = HEX (src) | (address << 8);
442 src += 2;
443 bytes_on_line--;
444 case '1':
445 address = HEX (src) | (address << 8);
446 src += 2;
447 address = HEX (src) | (address << 8);
448 src += 2;
449 bytes_on_line -= 2;
450 func (abfd, section, address, src, bytes_on_line);
451 break;
452 default:
453 return;
454 }
8f8fefcc 455 }
4a81b561 456 }
9898b929 457
4a81b561
DHW
458}
459
8f8fefcc 460static bfd_target *
9783e04a
DM
461object_p (abfd)
462 bfd *abfd;
8f8fefcc
JG
463{
464 asection *section;
9783e04a 465 /* We create one section called .text for all the contents,
8f8fefcc 466 and allocate enough room for the entire file. */
9783e04a
DM
467
468 section = bfd_make_section (abfd, ".text");
8f8fefcc
JG
469 section->_raw_size = 0;
470 section->vma = 0xffffffff;
471 low = 0xffffffff;
472 high = 0;
9783e04a 473 pass_over (abfd, size_srec, size_symbols, section);
8f8fefcc
JG
474 section->_raw_size = high - low;
475 section->vma = low;
476 section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
4a81b561 477
8f8fefcc 478 if (abfd->symcount)
9783e04a 479 abfd->flags |= HAS_SYMS;
8f8fefcc
JG
480 return abfd->xvec;
481}
9898b929
JG
482
483static bfd_target *
9783e04a
DM
484DEFUN (srec_object_p, (abfd),
485 bfd * abfd)
4a81b561 486{
387cbb2b 487 char b[4];
8f8fefcc 488
9783e04a 489 srec_init ();
9898b929 490
9783e04a
DM
491 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
492 bfd_read (b, 1, 4, abfd);
493
494 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
495 return (bfd_target *) NULL;
496
497 /* We create one section called .text for all the contents,
387cbb2b 498 and allocate enough room for the entire file. */
4a81b561 499
9783e04a 500 return object_p (abfd);
8f8fefcc
JG
501}
502
503
504static bfd_target *
9783e04a
DM
505DEFUN (symbolsrec_object_p, (abfd),
506 bfd * abfd)
8f8fefcc
JG
507{
508 char b[4];
509
9783e04a
DM
510 srec_init ();
511
512 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
513 bfd_read (b, 1, 4, abfd);
8f8fefcc
JG
514
515 if (b[0] != '$' || b[1] != '$')
9783e04a 516 return (bfd_target *) NULL;
8f8fefcc 517
9783e04a 518 return object_p (abfd);
4a81b561
DHW
519}
520
521
4a81b561 522static boolean
9783e04a
DM
523DEFUN (srec_get_section_contents, (abfd, section, location, offset, count),
524 bfd * abfd AND
525 asection * section AND
526 PTR location AND
527 file_ptr offset AND
528 bfd_size_type count)
529{
530 if (section->used_by_bfd == (PTR) NULL)
9898b929 531 {
9783e04a
DM
532 section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size);
533 if (!section->used_by_bfd)
534 {
5e808126 535 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
536 return false;
537 }
538
539 pass_over (abfd, fillup, fillup_symbols, section);
9898b929 540 }
9783e04a
DM
541 memcpy ((PTR) location,
542 (PTR) ((char *) (section->used_by_bfd) + offset),
543 count);
544 return true;
4a81b561 545}
9783e04a 546
4a81b561
DHW
547
548
549boolean
9783e04a
DM
550DEFUN (srec_set_arch_mach, (abfd, arch, machine),
551 bfd * abfd AND
552 enum bfd_architecture arch AND
553 unsigned long machine)
4a81b561 554{
9783e04a 555 return bfd_default_set_arch_mach (abfd, arch, machine);
4a81b561
DHW
556}
557
558
9898b929
JG
559/* we have to save up all the Srecords for a splurge before output,
560 also remember */
4a81b561 561
9898b929 562static boolean
9783e04a
DM
563DEFUN (srec_set_section_contents, (abfd, section, location, offset, bytes_to_do),
564 bfd * abfd AND
565 sec_ptr section AND
566 PTR location AND
567 file_ptr offset AND
568 bfd_size_type bytes_to_do)
569{
570 tdata_type *tdata = abfd->tdata.srec_data;
294eaca4 571 srec_data_list_type *entry = (srec_data_list_type *)
9783e04a
DM
572 bfd_alloc (abfd, sizeof (srec_data_list_type));
573
574 if (!entry)
575 {
5e808126 576 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
577 return false;
578 }
8f8fefcc 579
294eaca4 580 if ((section->flags & SEC_ALLOC)
9783e04a 581 && (section->flags & SEC_LOAD))
9898b929 582 {
9783e04a
DM
583 unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do);
584 if (!data)
585 {
5e808126 586 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
587 return false;
588 }
68241b2b 589 memcpy ((PTR) data, location, bytes_to_do);
9898b929 590
9783e04a 591 if ((section->lma + offset + bytes_to_do) <= 0xffff)
8f8fefcc 592 {
9898b929 593
8f8fefcc 594 }
9783e04a
DM
595 else if ((section->lma + offset + bytes_to_do) <= 0xffffff
596 && tdata->type < 2)
8f8fefcc
JG
597 {
598 tdata->type = 2;
599 }
9783e04a 600 else
8f8fefcc
JG
601 {
602 tdata->type = 3;
603 }
604
605 entry->data = data;
606 entry->where = section->lma + offset;
607 entry->size = bytes_to_do;
608 entry->next = tdata->head;
609 tdata->head = entry;
610 }
9783e04a 611 return true;
9898b929
JG
612}
613
614/* Write a record of type, of the supplied number of bytes. The
615 supplied bytes and length don't have a checksum. That's worked out
616 here
617*/
618static
9783e04a
DM
619void
620DEFUN (srec_write_record, (abfd, type, address, data, end),
621 bfd * abfd AND
622 char type AND
623 bfd_vma address AND
624 CONST unsigned char *data AND
625 CONST unsigned char *end)
626
627{
628 char buffer[MAXCHUNK];
629
630 unsigned int check_sum = 0;
631 CONST unsigned char *src = data;
632 char *dst = buffer;
633 char *length;
634
635
636 *dst++ = 'S';
637 *dst++ = '0' + type;
638
639 length = dst;
640 dst += 2; /* leave room for dst*/
641
642 switch (type)
9898b929 643 {
9783e04a
DM
644 case 3:
645 case 7:
646 TOHEX (dst, (address >> 24), check_sum);
647 dst += 2;
648 case 8:
649 case 2:
650 TOHEX (dst, (address >> 16), check_sum);
651 dst += 2;
652 case 9:
653 case 1:
654 case 0:
655 TOHEX (dst, (address >> 8), check_sum);
656 dst += 2;
657 TOHEX (dst, (address), check_sum);
658 dst += 2;
659 break;
4a81b561 660
4a81b561 661 }
9783e04a 662 for (src = data; src < end; src++)
9898b929 663 {
9783e04a
DM
664 TOHEX (dst, *src, check_sum);
665 dst += 2;
4a81b561
DHW
666 }
667
9783e04a
DM
668 /* Fill in the length */
669 TOHEX (length, (dst - length) / 2, check_sum);
670 check_sum &= 0xff;
671 check_sum = 255 - check_sum;
672 TOHEX (dst, check_sum, check_sum);
673 dst += 2;
674
675 *dst++ = '\r';
676 *dst++ = '\n';
677 bfd_write ((PTR) buffer, 1, dst - buffer, abfd);
9898b929 678}
4a81b561 679
4a81b561 680
4a81b561 681
9898b929 682static void
9783e04a
DM
683DEFUN (srec_write_header, (abfd),
684 bfd * abfd)
9898b929 685{
9783e04a
DM
686 unsigned char buffer[MAXCHUNK];
687 unsigned char *dst = buffer;
688 unsigned int i;
4a81b561 689
9783e04a
DM
690 /* I'll put an arbitary 40 char limit on header size */
691 for (i = 0; i < 40 && abfd->filename[i]; i++)
9898b929 692 {
9783e04a 693 *dst++ = abfd->filename[i];
9898b929 694 }
9783e04a 695 srec_write_record (abfd, 0, 0, buffer, dst);
4a81b561
DHW
696}
697
9898b929 698static void
9783e04a
DM
699DEFUN (srec_write_section, (abfd, tdata, list),
700 bfd * abfd AND
701 tdata_type * tdata AND
702 srec_data_list_type * list)
9898b929 703{
9783e04a
DM
704 unsigned int bytes_written = 0;
705 unsigned char *location = list->data;
9898b929 706
9783e04a 707 while (bytes_written < list->size)
9898b929 708 {
9783e04a
DM
709 bfd_vma address;
710
711 unsigned int bytes_this_chunk = list->size - bytes_written;
9898b929 712
9783e04a 713 if (bytes_this_chunk > CHUNK)
9898b929 714 {
9783e04a 715 bytes_this_chunk = CHUNK;
9898b929
JG
716 }
717
9783e04a 718 address = list->where + bytes_written;
9898b929 719
9783e04a
DM
720 srec_write_record (abfd,
721 tdata->type,
722 address,
723 location,
724 location + bytes_this_chunk);
9898b929 725
9783e04a
DM
726 bytes_written += bytes_this_chunk;
727 location += bytes_this_chunk;
9898b929
JG
728 }
729
730}
731
732static void
9783e04a
DM
733DEFUN (srec_write_terminator, (abfd, tdata),
734 bfd * abfd AND
735 tdata_type * tdata)
736{
737 unsigned char buffer[2];
738
739 srec_write_record (abfd, 10 - tdata->type,
740 abfd->start_address, buffer, buffer);
9898b929 741}
3039e8ee 742
8f8fefcc 743
9783e04a 744
8f8fefcc 745static void
9783e04a 746srec_write_symbols (abfd)
2c3b9e47 747 bfd *abfd;
9898b929 748{
8f8fefcc
JG
749 char buffer[MAXCHUNK];
750 /* Dump out the symbols of a bfd */
751 int i;
9783e04a 752 int len = bfd_get_symcount (abfd);
8f8fefcc 753
9783e04a
DM
754 if (len)
755 {
756 asymbol **table = bfd_get_outsymbols (abfd);
757 sprintf (buffer, "$$ %s\r\n", abfd->filename);
8f8fefcc 758
9783e04a 759 bfd_write (buffer, strlen (buffer), 1, abfd);
8f8fefcc 760
9783e04a
DM
761 for (i = 0; i < len; i++)
762 {
763 asymbol *s = table[i];
8f8fefcc 764#if 0
9783e04a 765 int len = strlen (s->name);
8f8fefcc 766
9783e04a 767 /* If this symbol has a .[ocs] in it, it's probably a file name
8f8fefcc
JG
768 and we'll output that as the module name */
769
9783e04a
DM
770 if (len > 3 && s->name[len - 2] == '.')
771 {
772 int l;
773 sprintf (buffer, "$$ %s\r\n", s->name);
774 l = strlen (buffer);
775 bfd_write (buffer, l, 1, abfd);
776 }
777 else
8f8fefcc 778#endif
9783e04a
DM
779 if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
780 && (s->flags & BSF_DEBUGGING) == 0
781 && s->name[0] != '.'
782 && s->name[0] != 't')
783 {
784 /* Just dump out non debug symbols */
785
786 int l;
787 char buf2[40], *p;
788
789 sprintf_vma (buf2,
790 s->value + s->section->output_section->lma
791 + s->section->output_offset);
792 p = buf2;
793 while (p[0] == '0' && p[1] != 0)
794 p++;
795 sprintf (buffer, " %s $%s\r\n", s->name, p);
796 l = strlen (buffer);
797 bfd_write (buffer, l, 1, abfd);
798 }
799 }
800 sprintf (buffer, "$$ \r\n");
801 bfd_write (buffer, strlen (buffer), 1, abfd);
8f8fefcc 802 }
9898b929
JG
803}
804
9898b929 805static boolean
9783e04a 806internal_srec_write_object_contents (abfd, symbols)
8f8fefcc
JG
807 bfd *abfd;
808 int symbols;
4a81b561 809{
9783e04a
DM
810 tdata_type *tdata = abfd->tdata.srec_data;
811 srec_data_list_type *list;
9898b929 812
9783e04a
DM
813 if (symbols)
814 srec_write_symbols (abfd);
8f8fefcc 815
9783e04a 816 srec_write_header (abfd);
8f8fefcc 817
9783e04a
DM
818 /* Now wander though all the sections provided and output them */
819 list = tdata->head;
9898b929 820
9783e04a 821 while (list != (srec_data_list_type *) NULL)
9898b929 822 {
9783e04a
DM
823 srec_write_section (abfd, tdata, list);
824 list = list->next;
9898b929 825 }
9783e04a
DM
826 srec_write_terminator (abfd, tdata);
827 return true;
4a81b561
DHW
828}
829
8f8fefcc 830static boolean
9783e04a 831srec_write_object_contents (abfd)
8f8fefcc
JG
832 bfd *abfd;
833{
9783e04a 834 return internal_srec_write_object_contents (abfd, 0);
8f8fefcc
JG
835}
836
837static boolean
9783e04a 838symbolsrec_write_object_contents (abfd)
8f8fefcc
JG
839 bfd *abfd;
840{
9783e04a 841 return internal_srec_write_object_contents (abfd, 1);
8f8fefcc
JG
842}
843
9783e04a
DM
844/*ARGSUSED*/
845static int
846DEFUN (srec_sizeof_headers, (abfd, exec),
847 bfd * abfd AND
848 boolean exec)
39a2ce33 849{
9783e04a 850 return 0;
39a2ce33
SC
851}
852
357a1f38 853static asymbol *
9783e04a
DM
854DEFUN (srec_make_empty_symbol, (abfd),
855 bfd * abfd)
357a1f38 856{
9783e04a
DM
857 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
858 if (new)
859 new->the_bfd = abfd;
357a1f38
SC
860 return new;
861}
8f8fefcc
JG
862
863static unsigned int
9783e04a
DM
864srec_get_symtab_upper_bound (abfd)
865 bfd *abfd;
8f8fefcc
JG
866{
867 /* Read in all the info */
9783e04a
DM
868 srec_get_section_contents (abfd, abfd->sections, 0, 0, 0);
869 return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
8f8fefcc
JG
870}
871
872static unsigned int
9783e04a
DM
873DEFUN (srec_get_symtab, (abfd, alocation),
874 bfd * abfd AND
875 asymbol ** alocation)
8f8fefcc
JG
876{
877 int lim = abfd->symcount;
878 int i;
9783e04a
DM
879 for (i = 0; i < lim; i++)
880 {
881 alocation[i] = abfd->tdata.srec_data->symbols + i;
882 }
8f8fefcc
JG
883 alocation[i] = 0;
884 return lim;
885}
886
9783e04a
DM
887/*ARGSUSED*/
888void
889DEFUN (srec_get_symbol_info, (ignore_abfd, symbol, ret),
890 bfd * ignore_abfd AND
891 asymbol * symbol AND
892 symbol_info * ret)
2c3b9e47
KR
893{
894 bfd_symbol_info (symbol, ret);
895}
896
9783e04a
DM
897/*ARGSUSED*/
898void
899DEFUN (srec_print_symbol, (ignore_abfd, afile, symbol, how),
900 bfd * ignore_abfd AND
901 PTR afile AND
902 asymbol * symbol AND
903 bfd_print_symbol_type how)
904{
905 FILE *file = (FILE *) afile;
906 switch (how)
907 {
908 case bfd_print_symbol_name:
909 fprintf (file, "%s", symbol->name);
910 break;
911 default:
912 bfd_print_symbol_vandf ((PTR) file, symbol);
913 fprintf (file, " %-5s %s",
914 symbol->section->name,
915 symbol->name);
8f8fefcc 916
9783e04a 917 }
8f8fefcc
JG
918}
919
6f715d66
SC
920#define FOO PROTO
921#define srec_new_section_hook (FOO(boolean, (*), (bfd *, asection *)))bfd_true
8f8fefcc 922
6f715d66
SC
923#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
924#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
357a1f38 925
8f8fefcc 926
d0ec7a8e 927
6f715d66
SC
928#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
929#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
930#define srec_generic_stat_arch_elt (FOO(int, (*), (bfd *,struct stat *))) bfd_0
9872a49c 931
d0ec7a8e
SC
932
933#define srec_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
934#define srec_core_file_failing_signal (int (*)())bfd_0
6f715d66 935#define srec_core_file_matches_executable_p (FOO(boolean, (*),(bfd*, bfd*)))bfd_false
d0ec7a8e
SC
936#define srec_slurp_armap bfd_true
937#define srec_slurp_extended_name_table bfd_true
938#define srec_truncate_arname (void (*)())bfd_nullvoidptr
9898b929 939#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
d0ec7a8e 940#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
2b1d8a50 941#define srec_close_and_cleanup bfd_generic_close_and_cleanup
6f715d66
SC
942#define srec_bfd_debug_info_start bfd_void
943#define srec_bfd_debug_info_end bfd_void
944#define srec_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *))) bfd_void
e98e6ec1 945#define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
294eaca4 946#define srec_bfd_relax_section bfd_generic_relax_section
8f8fefcc
JG
947#define srec_bfd_reloc_type_lookup \
948 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
949#define srec_bfd_make_debug_symbol \
950 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
4c3721d5
ILT
951#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
952#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
953#define srec_bfd_final_link _bfd_generic_final_link
3039e8ee 954
4a81b561
DHW
955bfd_target srec_vec =
956{
9783e04a
DM
957 "srec", /* name */
958 bfd_target_srec_flavour,
959 true, /* target byte order */
960 true, /* target headers byte order */
961 (HAS_RELOC | EXEC_P | /* object flags */
962 HAS_LINENO | HAS_DEBUG |
963 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
964 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
965 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
966 0, /* leading underscore */
967 ' ', /* ar_pad_char */
968 16, /* ar_max_namelen */
969 1, /* minimum alignment */
970 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
971 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
972 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
973 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
974 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
975 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
9898b929
JG
976
977 {
9783e04a
DM
978 _bfd_dummy_target,
979 srec_object_p, /* bfd_check_format */
980 (struct bfd_target * (*)()) bfd_nullvoidptr,
981 (struct bfd_target * (*)()) bfd_nullvoidptr,
9898b929
JG
982 },
983 {
9783e04a
DM
984 bfd_false,
985 srec_mkobject,
986 _bfd_generic_mkarchive,
987 bfd_false,
9898b929
JG
988 },
989 { /* bfd_write_contents */
9783e04a
DM
990 bfd_false,
991 srec_write_object_contents,
992 _bfd_write_archive_contents,
993 bfd_false,
9898b929 994 },
9783e04a
DM
995 JUMP_TABLE (srec)
996};
9898b929 997
8f8fefcc
JG
998
999
1000bfd_target symbolsrec_vec =
1001{
9783e04a
DM
1002 "symbolsrec", /* name */
1003 bfd_target_srec_flavour,
1004 true, /* target byte order */
1005 true, /* target headers byte order */
1006 (HAS_RELOC | EXEC_P | /* object flags */
1007 HAS_LINENO | HAS_DEBUG |
1008 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1009 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1010 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1011 0, /* leading underscore */
1012 ' ', /* ar_pad_char */
1013 16, /* ar_max_namelen */
1014 1, /* minimum alignment */
1015 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1016 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1017 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1018 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1019 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1020 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
8f8fefcc
JG
1021
1022 {
9783e04a
DM
1023 _bfd_dummy_target,
1024 symbolsrec_object_p, /* bfd_check_format */
1025 (struct bfd_target * (*)()) bfd_nullvoidptr,
1026 (struct bfd_target * (*)()) bfd_nullvoidptr,
8f8fefcc
JG
1027 },
1028 {
9783e04a
DM
1029 bfd_false,
1030 srec_mkobject,
1031 _bfd_generic_mkarchive,
1032 bfd_false,
8f8fefcc
JG
1033 },
1034 { /* bfd_write_contents */
9783e04a
DM
1035 bfd_false,
1036 symbolsrec_write_object_contents,
1037 _bfd_write_archive_contents,
1038 bfd_false,
8f8fefcc 1039 },
9783e04a
DM
1040 JUMP_TABLE (srec),
1041 (PTR) 0
1042};
This page took 0.156337 seconds and 4 git commands to generate.