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