22f9eff5cbbb9072f735066ed5c02cfbfbc36ce9
[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 unsigned int type;
186
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;
194 }
195 tdata_type;
196
197 static boolean srec_write_section PARAMS ((bfd *, tdata_type *,
198 srec_data_list_type *));
199 static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *));
200
201 /*
202 called once per input S-Record, used to work out vma and size of data.
203 */
204
205 static bfd_vma low, high;
206
207 /*ARGSUSED*/
208 static void
209 size_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;
217 }
218
219 static void
220 fillup_symbols (abfd, buf, len, val)
221 bfd *abfd;
222 char *buf;
223 int len;
224 int val;
225 {
226 if (!abfd->tdata.srec_data->done_symbol_read)
227 {
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 {
235 bfd_set_error (bfd_error_no_memory);
236 abort (); /* FIXME */
237 }
238 abfd->tdata.srec_data->symbol_idx = 0;
239 abfd->tdata.srec_data->string_idx = 0;
240 }
241
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_ptr;
250 p->udata = 0;
251 }
252 }
253 /*ARGSUSED*/
254 static void
255 size_srec (abfd, section, address, raw, length)
256 bfd *abfd;
257 asection *section;
258 bfd_vma address;
259 bfd_byte *raw;
260 unsigned int length;
261 {
262 if (address < low)
263 low = address;
264 if (address + length > high)
265 high = address + length - 1;
266 }
267
268
269 /*
270 called once per input S-Record, copies data from input into bfd_alloc'd area
271 */
272
273 /*ARGSUSED*/
274 static void
275 fillup (abfd, section, address, raw, length)
276 bfd *abfd;
277 asection *section;
278 bfd_vma address;
279 bfd_byte *raw;
280 unsigned int length;
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 }
292 }
293
294 /* Pass over an S-Record file, calling one of the above functions on each
295 record. */
296
297 static int
298 white (x)
299 char x;
300 {
301 return (x == ' ' || x == '\t' || x == '\n' || x == '\r');
302 }
303 static int
304 skipwhite (src, abfd)
305 char *src;
306 bfd *abfd;
307 {
308 int eof = 0;
309 while (white (*src) && !eof)
310 {
311 eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
312 }
313 return eof;
314 }
315
316 static boolean
317 srec_mkobject (abfd)
318 bfd *abfd;
319 {
320 if (abfd->tdata.srec_data == 0)
321 {
322 tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
323 if (!tdata)
324 {
325 bfd_set_error (bfd_error_no_memory);
326 return false;
327 }
328 abfd->tdata.srec_data = tdata;
329 tdata->type = 1;
330 tdata->head = (srec_data_list_type *) NULL;
331 }
332 return true;
333
334 }
335
336 static void
337 pass_over (abfd, func, symbolfunc, section)
338 bfd *abfd;
339 void (*func) ();
340 void (*symbolfunc) ();
341 asection *section;
342 {
343 unsigned int bytes_on_line;
344 boolean eof = false;
345
346 srec_mkobject (abfd);
347 /* To the front of the file */
348 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
349 abort ();
350 while (eof == false)
351 {
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)
360 {
361 default:
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);
379
380 {
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);
416 }
417 }
418 break;
419 case 'S':
420 src++;
421
422 /* Fetch the type and the length */
423 if (bfd_read (src, 1, 3, abfd) != 3)
424 abort (); /* FIXME */
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
437 if (bfd_read (src, 1, bytes_on_line * 2, abfd) != bytes_on_line * 2)
438 abort (); /* FIXME */
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
464 case '7':
465 address = HEX (src);
466 src += 2;
467 bytes_on_line--;
468 case '8':
469 address = HEX (src) | (address << 8);
470 src += 2;
471 bytes_on_line--;
472 case '9':
473 address = HEX (src) | (address << 8);
474 src += 2;
475 address = HEX (src) | (address << 8);
476 src += 2;
477 bytes_on_line -= 2;
478 abfd->start_address = address;
479 return;
480
481 default:
482 return;
483 }
484 }
485 }
486
487 }
488
489 static const bfd_target *
490 object_p (abfd)
491 bfd *abfd;
492 {
493 asection *section;
494 /* We create one section called .text for all the contents,
495 and allocate enough room for the entire file. */
496
497 section = bfd_make_section (abfd, ".text");
498 section->_raw_size = 0;
499 section->vma = 0xffffffff;
500 low = 0xffffffff;
501 high = 0;
502 pass_over (abfd, size_srec, size_symbols, section);
503 section->_raw_size = high - low;
504 section->vma = low;
505 section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
506
507 if (abfd->symcount)
508 abfd->flags |= HAS_SYMS;
509 return abfd->xvec;
510 }
511
512 static const bfd_target *
513 srec_object_p (abfd)
514 bfd *abfd;
515 {
516 char b[4];
517
518 srec_init ();
519
520 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
521 || bfd_read (b, 1, 4, abfd) != 4)
522 return NULL;
523
524 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
525 return (const bfd_target *) NULL;
526
527 /* We create one section called .text for all the contents,
528 and allocate enough room for the entire file. */
529
530 return object_p (abfd);
531 }
532
533
534 static const bfd_target *
535 symbolsrec_object_p (abfd)
536 bfd *abfd;
537 {
538 char b[4];
539
540 srec_init ();
541
542 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
543 || bfd_read (b, 1, 4, abfd) != 4)
544 return NULL;
545
546 if (b[0] != '$' || b[1] != '$')
547 return (const bfd_target *) NULL;
548
549 return object_p (abfd);
550 }
551
552
553 static boolean
554 srec_get_section_contents (abfd, section, location, offset, count)
555 bfd *abfd;
556 asection *section;
557 PTR location;
558 file_ptr offset;
559 bfd_size_type count;
560 {
561 if (section->used_by_bfd == (PTR) NULL)
562 {
563 section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size);
564 if (!section->used_by_bfd)
565 {
566 bfd_set_error (bfd_error_no_memory);
567 return false;
568 }
569
570 pass_over (abfd, fillup, fillup_symbols, section);
571 }
572 memcpy ((PTR) location,
573 (PTR) ((char *) (section->used_by_bfd) + offset),
574 count);
575 return true;
576 }
577
578
579
580 boolean
581 srec_set_arch_mach (abfd, arch, machine)
582 bfd *abfd;
583 enum bfd_architecture arch;
584 unsigned long machine;
585 {
586 return bfd_default_set_arch_mach (abfd, arch, machine);
587 }
588
589
590 /* we have to save up all the Srecords for a splurge before output,
591 also remember */
592
593 static boolean
594 srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
595 bfd *abfd;
596 sec_ptr section;
597 PTR location;
598 file_ptr offset;
599 bfd_size_type bytes_to_do;
600 {
601 tdata_type *tdata = abfd->tdata.srec_data;
602 srec_data_list_type *entry = (srec_data_list_type *)
603 bfd_alloc (abfd, sizeof (srec_data_list_type));
604
605 if (!entry)
606 {
607 bfd_set_error (bfd_error_no_memory);
608 return false;
609 }
610
611 if ((section->flags & SEC_ALLOC)
612 && (section->flags & SEC_LOAD))
613 {
614 unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do);
615 if (!data)
616 {
617 bfd_set_error (bfd_error_no_memory);
618 return false;
619 }
620 memcpy ((PTR) data, location, bytes_to_do);
621
622 if ((section->lma + offset + bytes_to_do) <= 0xffff)
623 {
624
625 }
626 else if ((section->lma + offset + bytes_to_do) <= 0xffffff
627 && tdata->type < 2)
628 {
629 tdata->type = 2;
630 }
631 else
632 {
633 tdata->type = 3;
634 }
635
636 entry->data = data;
637 entry->where = section->lma + offset;
638 entry->size = bytes_to_do;
639 entry->next = tdata->head;
640 tdata->head = entry;
641 }
642 return true;
643 }
644
645 /* Write a record of type, of the supplied number of bytes. The
646 supplied bytes and length don't have a checksum. That's worked out
647 here
648 */
649 static boolean
650 srec_write_record (abfd, type, address, data, end)
651 bfd *abfd;
652 int type;
653 bfd_vma address;
654 const unsigned char *data;
655 const unsigned char *end;
656 {
657 char buffer[MAXCHUNK];
658
659 unsigned int check_sum = 0;
660 CONST unsigned char *src = data;
661 char *dst = buffer;
662 char *length;
663
664
665 *dst++ = 'S';
666 *dst++ = '0' + type;
667
668 length = dst;
669 dst += 2; /* leave room for dst*/
670
671 switch (type)
672 {
673 case 3:
674 case 7:
675 TOHEX (dst, (address >> 24), check_sum);
676 dst += 2;
677 case 8:
678 case 2:
679 TOHEX (dst, (address >> 16), check_sum);
680 dst += 2;
681 case 9:
682 case 1:
683 case 0:
684 TOHEX (dst, (address >> 8), check_sum);
685 dst += 2;
686 TOHEX (dst, (address), check_sum);
687 dst += 2;
688 break;
689
690 }
691 for (src = data; src < end; src++)
692 {
693 TOHEX (dst, *src, check_sum);
694 dst += 2;
695 }
696
697 /* Fill in the length */
698 TOHEX (length, (dst - length) / 2, check_sum);
699 check_sum &= 0xff;
700 check_sum = 255 - check_sum;
701 TOHEX (dst, check_sum, check_sum);
702 dst += 2;
703
704 *dst++ = '\r';
705 *dst++ = '\n';
706 if (bfd_write ((PTR) buffer, 1, dst - buffer, abfd) != dst - buffer)
707 return false;
708 return true;
709 }
710
711
712
713 static boolean
714 srec_write_header (abfd)
715 bfd *abfd;
716 {
717 unsigned char buffer[MAXCHUNK];
718 unsigned char *dst = buffer;
719 unsigned int i;
720
721 /* I'll put an arbitary 40 char limit on header size */
722 for (i = 0; i < 40 && abfd->filename[i]; i++)
723 {
724 *dst++ = abfd->filename[i];
725 }
726 return srec_write_record (abfd, 0, 0, buffer, dst);
727 }
728
729 static boolean
730 srec_write_section (abfd, tdata, list)
731 bfd *abfd;
732 tdata_type *tdata;
733 srec_data_list_type *list;
734 {
735 unsigned int bytes_written = 0;
736 unsigned char *location = list->data;
737
738 while (bytes_written < list->size)
739 {
740 bfd_vma address;
741
742 unsigned int bytes_this_chunk = list->size - bytes_written;
743
744 if (bytes_this_chunk > CHUNK)
745 {
746 bytes_this_chunk = CHUNK;
747 }
748
749 address = list->where + bytes_written;
750
751 if (! srec_write_record (abfd,
752 tdata->type,
753 address,
754 location,
755 location + bytes_this_chunk))
756 return false;
757
758 bytes_written += bytes_this_chunk;
759 location += bytes_this_chunk;
760 }
761
762 return true;
763 }
764
765 static boolean
766 srec_write_terminator (abfd, tdata)
767 bfd *abfd;
768 tdata_type *tdata;
769 {
770 unsigned char buffer[2];
771
772 return srec_write_record (abfd, 10 - tdata->type,
773 abfd->start_address, buffer, buffer);
774 }
775
776
777
778 static boolean
779 srec_write_symbols (abfd)
780 bfd *abfd;
781 {
782 char buffer[MAXCHUNK];
783 /* Dump out the symbols of a bfd */
784 int i;
785 int count = bfd_get_symcount (abfd);
786
787 if (count)
788 {
789 size_t len;
790 asymbol **table = bfd_get_outsymbols (abfd);
791 sprintf (buffer, "$$ %s\r\n", abfd->filename);
792
793 len = strlen (buffer);
794 if (bfd_write (buffer, len, 1, abfd) != len)
795 return false;
796
797 for (i = 0; i < count; i++)
798 {
799 asymbol *s = table[i];
800 #if 0
801 int len = strlen (s->name);
802
803 /* If this symbol has a .[ocs] in it, it's probably a file name
804 and we'll output that as the module name */
805
806 if (len > 3 && s->name[len - 2] == '.')
807 {
808 int l;
809 sprintf (buffer, "$$ %s\r\n", s->name);
810 l = strlen (buffer);
811 if (bfd_write (buffer, l, 1, abfd) != l)
812 return false;
813 }
814 else
815 #endif
816 if (s->flags & (BSF_GLOBAL | BSF_LOCAL)
817 && (s->flags & BSF_DEBUGGING) == 0
818 && s->name[0] != '.'
819 && s->name[0] != 't')
820 {
821 /* Just dump out non debug symbols */
822
823 int l;
824 char buf2[40], *p;
825
826 sprintf_vma (buf2,
827 s->value + s->section->output_section->lma
828 + s->section->output_offset);
829 p = buf2;
830 while (p[0] == '0' && p[1] != 0)
831 p++;
832 sprintf (buffer, " %s $%s\r\n", s->name, p);
833 l = strlen (buffer);
834 if (bfd_write (buffer, l, 1, abfd) != l)
835 return false;
836 }
837 }
838 sprintf (buffer, "$$ \r\n");
839 len = strlen (buffer);
840 if (bfd_write (buffer, len, 1, abfd) != len)
841 return false;
842 }
843
844 return true;
845 }
846
847 static boolean
848 internal_srec_write_object_contents (abfd, symbols)
849 bfd *abfd;
850 int symbols;
851 {
852 tdata_type *tdata = abfd->tdata.srec_data;
853 srec_data_list_type *list;
854
855 if (symbols)
856 {
857 if (! srec_write_symbols (abfd))
858 return false;
859 }
860
861 if (! srec_write_header (abfd))
862 return false;
863
864 /* Now wander though all the sections provided and output them */
865 list = tdata->head;
866
867 while (list != (srec_data_list_type *) NULL)
868 {
869 if (! srec_write_section (abfd, tdata, list))
870 return false;
871 list = list->next;
872 }
873 return srec_write_terminator (abfd, tdata);
874 }
875
876 static boolean
877 srec_write_object_contents (abfd)
878 bfd *abfd;
879 {
880 return internal_srec_write_object_contents (abfd, 0);
881 }
882
883 static boolean
884 symbolsrec_write_object_contents (abfd)
885 bfd *abfd;
886 {
887 return internal_srec_write_object_contents (abfd, 1);
888 }
889
890 /*ARGSUSED*/
891 static int
892 srec_sizeof_headers (abfd, exec)
893 bfd *abfd;
894 boolean exec;
895 {
896 return 0;
897 }
898
899 static asymbol *
900 srec_make_empty_symbol (abfd)
901 bfd *abfd;
902 {
903 asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
904 if (new)
905 new->the_bfd = abfd;
906 return new;
907 }
908
909 static long
910 srec_get_symtab_upper_bound (abfd)
911 bfd *abfd;
912 {
913 /* Read in all the info */
914 if (! srec_get_section_contents (abfd, abfd->sections, 0, 0, 0))
915 return -1;
916 return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
917 }
918
919 static long
920 srec_get_symtab (abfd, alocation)
921 bfd *abfd;
922 asymbol **alocation;
923 {
924 int lim = abfd->symcount;
925 int i;
926 for (i = 0; i < lim; i++)
927 {
928 alocation[i] = abfd->tdata.srec_data->symbols + i;
929 }
930 alocation[i] = 0;
931 return lim;
932 }
933
934 /*ARGSUSED*/
935 void
936 srec_get_symbol_info (ignore_abfd, symbol, ret)
937 bfd *ignore_abfd;
938 asymbol *symbol;
939 symbol_info *ret;
940 {
941 bfd_symbol_info (symbol, ret);
942 }
943
944 /*ARGSUSED*/
945 void
946 srec_print_symbol (ignore_abfd, afile, symbol, how)
947 bfd *ignore_abfd;
948 PTR afile;
949 asymbol *symbol;
950 bfd_print_symbol_type how;
951 {
952 FILE *file = (FILE *) afile;
953 switch (how)
954 {
955 case bfd_print_symbol_name:
956 fprintf (file, "%s", symbol->name);
957 break;
958 default:
959 bfd_print_symbol_vandf ((PTR) file, symbol);
960 fprintf (file, " %-5s %s",
961 symbol->section->name,
962 symbol->name);
963
964 }
965 }
966
967 #define srec_close_and_cleanup _bfd_generic_close_and_cleanup
968 #define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
969 #define srec_new_section_hook _bfd_generic_new_section_hook
970
971 #define srec_bfd_is_local_label bfd_generic_is_local_label
972 #define srec_get_lineno _bfd_nosymbols_get_lineno
973 #define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
974 #define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
975
976 #define srec_bfd_get_relocated_section_contents \
977 bfd_generic_get_relocated_section_contents
978 #define srec_bfd_relax_section bfd_generic_relax_section
979 #define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
980 #define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
981 #define srec_bfd_final_link _bfd_generic_final_link
982
983 const bfd_target srec_vec =
984 {
985 "srec", /* name */
986 bfd_target_srec_flavour,
987 true, /* target byte order */
988 true, /* target headers byte order */
989 (HAS_RELOC | EXEC_P | /* object flags */
990 HAS_LINENO | HAS_DEBUG |
991 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
992 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
993 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
994 0, /* leading underscore */
995 ' ', /* ar_pad_char */
996 16, /* ar_max_namelen */
997 1, /* minimum alignment */
998 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
999 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1000 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1001 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1002 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1003 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1004
1005 {
1006 _bfd_dummy_target,
1007 srec_object_p, /* bfd_check_format */
1008 _bfd_dummy_target,
1009 _bfd_dummy_target,
1010 },
1011 {
1012 bfd_false,
1013 srec_mkobject,
1014 _bfd_generic_mkarchive,
1015 bfd_false,
1016 },
1017 { /* bfd_write_contents */
1018 bfd_false,
1019 srec_write_object_contents,
1020 _bfd_write_archive_contents,
1021 bfd_false,
1022 },
1023
1024 BFD_JUMP_TABLE_GENERIC (srec),
1025 BFD_JUMP_TABLE_COPY (_bfd_generic),
1026 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1027 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1028 BFD_JUMP_TABLE_SYMBOLS (srec),
1029 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1030 BFD_JUMP_TABLE_WRITE (srec),
1031 BFD_JUMP_TABLE_LINK (srec),
1032 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1033
1034 (PTR) 0
1035 };
1036
1037
1038
1039 const bfd_target symbolsrec_vec =
1040 {
1041 "symbolsrec", /* name */
1042 bfd_target_srec_flavour,
1043 true, /* target byte order */
1044 true, /* target headers byte order */
1045 (HAS_RELOC | EXEC_P | /* object flags */
1046 HAS_LINENO | HAS_DEBUG |
1047 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1048 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1049 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1050 0, /* leading underscore */
1051 ' ', /* ar_pad_char */
1052 16, /* ar_max_namelen */
1053 1, /* minimum alignment */
1054 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1055 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1056 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1057 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1058 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1059 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1060
1061 {
1062 _bfd_dummy_target,
1063 symbolsrec_object_p, /* bfd_check_format */
1064 _bfd_dummy_target,
1065 _bfd_dummy_target,
1066 },
1067 {
1068 bfd_false,
1069 srec_mkobject,
1070 _bfd_generic_mkarchive,
1071 bfd_false,
1072 },
1073 { /* bfd_write_contents */
1074 bfd_false,
1075 symbolsrec_write_object_contents,
1076 _bfd_write_archive_contents,
1077 bfd_false,
1078 },
1079
1080 BFD_JUMP_TABLE_GENERIC (srec),
1081 BFD_JUMP_TABLE_COPY (_bfd_generic),
1082 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1083 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1084 BFD_JUMP_TABLE_SYMBOLS (srec),
1085 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1086 BFD_JUMP_TABLE_WRITE (srec),
1087 BFD_JUMP_TABLE_LINK (srec),
1088 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1089
1090 (PTR) 0
1091 };
This page took 0.157175 seconds and 4 git commands to generate.