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