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