daily update
[deliverable/binutils-gdb.git] / bfd / srec.c
CommitLineData
252b5132 1/* BFD back-end for s-record objects.
7898deda 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
72adc230 3 2000, 2001, 2002, 2003, 2004
252b5132
RH
4 Free Software Foundation, Inc.
5 Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23/*
24SUBSECTION
25 S-Record handling
26
27DESCRIPTION
7b82c249 28
252b5132
RH
29 Ordinary S-Records cannot hold anything but addresses and
30 data, so that's all that we implement.
31
32 The only interesting thing is that S-Records may come out of
33 order and there is no header, so an initial scan is required
34 to discover the minimum and maximum addresses used to create
35 the vma and size of the only section we create. We
36 arbitrarily call this section ".text".
37
38 When bfd_get_section_contents is called the file is read
39 again, and this time the data is placed into a bfd_alloc'd
40 area.
41
42 Any number of sections may be created for output, we save them
43 up and output them when it's time to close the bfd.
44
45 An s record looks like:
7b82c249 46
252b5132
RH
47EXAMPLE
48 S<type><length><address><data><checksum>
7b82c249 49
252b5132
RH
50DESCRIPTION
51 Where
52 o length
53 is the number of bytes following upto the checksum. Note that
54 this is not the number of chars following, since it takes two
55 chars to represent a byte.
56 o type
57 is one of:
58 0) header record
59 1) two byte address data record
60 2) three byte address data record
61 3) four byte address data record
62 7) four byte address termination record
63 8) three byte address termination record
64 9) two byte address termination record
7b82c249 65
252b5132
RH
66 o address
67 is the start address of the data following, or in the case of
68 a termination record, the start address of the image
69 o data
70 is the data.
71 o checksum
72 is the sum of all the raw byte data in the record, from the length
73 upwards, modulo 256 and subtracted from 255.
74
252b5132
RH
75SUBSECTION
76 Symbol S-Record handling
77
78DESCRIPTION
79 Some ICE equipment understands an addition to the standard
80 S-Record format; symbols and their addresses can be sent
81 before the data.
82
83 The format of this is:
84 ($$ <modulename>
85 (<space> <symbol> <address>)*)
86 $$
87
88 so a short symbol table could look like:
89
90EXAMPLE
91 $$ flash.x
92 $$ flash.c
93 _port6 $0
94 _delay $4
95 _start $14
96 _etext $8036
97 _edata $8036
98 _end $8036
99 $$
100
101DESCRIPTION
102 We allow symbols to be anywhere in the data stream - the module names
103 are always ignored.
7b82c249 104
252b5132
RH
105*/
106
107#include "bfd.h"
108#include "sysdep.h"
109#include "libbfd.h"
110#include "libiberty.h"
3882b010 111#include "safe-ctype.h"
252b5132
RH
112
113static void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
114static void srec_print_symbol
115 PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
116static void srec_init PARAMS ((void));
b34976b6
AM
117static bfd_boolean srec_mkobject PARAMS ((bfd *));
118static int srec_get_byte PARAMS ((bfd *, bfd_boolean *));
119static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, bfd_boolean));
120static bfd_boolean srec_scan PARAMS ((bfd *));
252b5132
RH
121static const bfd_target *srec_object_p PARAMS ((bfd *));
122static const bfd_target *symbolsrec_object_p PARAMS ((bfd *));
b34976b6
AM
123static bfd_boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *));
124
125static bfd_boolean srec_write_record
126 PARAMS ((bfd *, unsigned int, bfd_vma, const bfd_byte *, const bfd_byte *));
127static bfd_boolean srec_write_header PARAMS ((bfd *));
128static bfd_boolean srec_write_symbols PARAMS ((bfd *));
129static bfd_boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma));
130static bfd_boolean srec_get_section_contents
252b5132 131 PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
b34976b6 132static bfd_boolean srec_set_arch_mach
252b5132 133 PARAMS ((bfd *, enum bfd_architecture, unsigned long));
b34976b6 134static bfd_boolean srec_set_section_contents
0f867abe 135 PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
b34976b6
AM
136static bfd_boolean internal_srec_write_object_contents PARAMS ((bfd *, int));
137static bfd_boolean srec_write_object_contents PARAMS ((bfd *));
138static bfd_boolean symbolsrec_write_object_contents PARAMS ((bfd *));
139static int srec_sizeof_headers PARAMS ((bfd *, bfd_boolean));
252b5132 140static long srec_get_symtab_upper_bound PARAMS ((bfd *));
6cee3f79 141static long srec_canonicalize_symtab PARAMS ((bfd *, asymbol **));
252b5132 142
c3b7c767 143/* Macros for converting between hex and binary. */
252b5132 144
dc810e39 145static const char digs[] = "0123456789ABCDEF";
252b5132
RH
146
147#define NIBBLE(x) hex_value(x)
148#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
149#define TOHEX(d, x, ch) \
150 d[1] = digs[(x) & 0xf]; \
151 d[0] = digs[((x)>>4)&0xf]; \
152 ch += ((x) & 0xff);
153#define ISHEX(x) hex_p(x)
154
c3b7c767 155/* Initialize by filling in the hex conversion array. */
252b5132
RH
156
157static void
158srec_init ()
159{
b34976b6 160 static bfd_boolean inited = FALSE;
252b5132 161
82e51918 162 if (! inited)
252b5132 163 {
b34976b6 164 inited = TRUE;
252b5132
RH
165 hex_init ();
166 }
167}
168
d8dce692 169/* The maximum number of address+data+crc bytes on a line is FF. */
252b5132 170#define MAXCHUNK 0xff
420496c1
NC
171
172/* Default size for a CHUNK. */
173#define DEFAULT_CHUNK 16
174
d8dce692 175/* The number of data bytes we actually fit onto a line on output.
420496c1
NC
176 This variable can be modified by objcopy's --srec-len parameter.
177 For a 0x75 byte record you should set --srec-len=0x70. */
178unsigned int Chunk = DEFAULT_CHUNK;
179
180/* The type of srec output (free or forced to S3).
181 This variable can be modified by objcopy's --srec-forceS3
182 parameter. */
b34976b6 183bfd_boolean S3Forced = FALSE;
252b5132
RH
184
185/* When writing an S-record file, the S-records can not be output as
186 they are seen. This structure is used to hold them in memory. */
187
188struct srec_data_list_struct
189{
190 struct srec_data_list_struct *next;
191 bfd_byte *data;
192 bfd_vma where;
193 bfd_size_type size;
194};
195
196typedef struct srec_data_list_struct srec_data_list_type;
197
198/* When scanning the S-record file, a linked list of srec_symbol
199 structures is built to represent the symbol table (if there is
200 one). */
201
202struct srec_symbol
203{
204 struct srec_symbol *next;
205 const char *name;
206 bfd_vma val;
207};
208
209/* The S-record tdata information. */
210
211typedef struct srec_data_struct
212 {
213 srec_data_list_type *head;
214 srec_data_list_type *tail;
215 unsigned int type;
216 struct srec_symbol *symbols;
217 struct srec_symbol *symtail;
218 asymbol *csymbols;
219 }
220tdata_type;
221
b34976b6
AM
222static bfd_boolean srec_write_section
223 PARAMS ((bfd *, tdata_type *, srec_data_list_type *));
224static bfd_boolean srec_write_terminator
225 PARAMS ((bfd *, tdata_type *));
252b5132
RH
226
227/* Set up the S-record tdata information. */
228
b34976b6 229static bfd_boolean
252b5132
RH
230srec_mkobject (abfd)
231 bfd *abfd;
232{
487e54f2
AM
233 bfd_size_type amt;
234 tdata_type *tdata;
235
252b5132
RH
236 srec_init ();
237
487e54f2
AM
238 amt = sizeof (tdata_type);
239 tdata = (tdata_type *) bfd_alloc (abfd, amt);
240 if (tdata == NULL)
b34976b6
AM
241 return FALSE;
242
487e54f2
AM
243 abfd->tdata.srec_data = tdata;
244 tdata->type = 1;
245 tdata->head = NULL;
246 tdata->tail = NULL;
247 tdata->symbols = NULL;
248 tdata->symtail = NULL;
249 tdata->csymbols = NULL;
252b5132 250
b34976b6 251 return TRUE;
252b5132
RH
252}
253
254/* Read a byte from an S record file. Set *ERRORPTR if an error
255 occurred. Return EOF on error or end of file. */
256
257static int
258srec_get_byte (abfd, errorptr)
259 bfd *abfd;
b34976b6 260 bfd_boolean *errorptr;
252b5132
RH
261{
262 bfd_byte c;
263
dc810e39 264 if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
252b5132
RH
265 {
266 if (bfd_get_error () != bfd_error_file_truncated)
b34976b6 267 *errorptr = TRUE;
252b5132
RH
268 return EOF;
269 }
270
271 return (int) (c & 0xff);
272}
273
274/* Report a problem in an S record file. FIXME: This probably should
275 not call fprintf, but we really do need some mechanism for printing
276 error messages. */
277
278static void
279srec_bad_byte (abfd, lineno, c, error)
280 bfd *abfd;
281 unsigned int lineno;
282 int c;
b34976b6 283 bfd_boolean error;
252b5132
RH
284{
285 if (c == EOF)
286 {
287 if (! error)
288 bfd_set_error (bfd_error_file_truncated);
289 }
290 else
291 {
292 char buf[10];
293
3882b010 294 if (! ISPRINT (c))
252b5132
RH
295 sprintf (buf, "\\%03o", (unsigned int) c);
296 else
297 {
298 buf[0] = c;
299 buf[1] = '\0';
300 }
301 (*_bfd_error_handler)
302 (_("%s:%d: Unexpected character `%s' in S-record file\n"),
8f615d07 303 bfd_archive_filename (abfd), lineno, buf);
252b5132
RH
304 bfd_set_error (bfd_error_bad_value);
305 }
306}
307
308/* Add a new symbol found in an S-record file. */
309
b34976b6 310static bfd_boolean
252b5132
RH
311srec_new_symbol (abfd, name, val)
312 bfd *abfd;
313 const char *name;
314 bfd_vma val;
315{
316 struct srec_symbol *n;
dc810e39 317 bfd_size_type amt = sizeof (struct srec_symbol);
252b5132 318
dc810e39 319 n = (struct srec_symbol *) bfd_alloc (abfd, amt);
252b5132 320 if (n == NULL)
b34976b6 321 return FALSE;
252b5132
RH
322
323 n->name = name;
324 n->val = val;
325
326 if (abfd->tdata.srec_data->symbols == NULL)
327 abfd->tdata.srec_data->symbols = n;
328 else
329 abfd->tdata.srec_data->symtail->next = n;
330 abfd->tdata.srec_data->symtail = n;
331 n->next = NULL;
332
333 ++abfd->symcount;
334
b34976b6 335 return TRUE;
252b5132
RH
336}
337
338/* Read the S record file and turn it into sections. We create a new
339 section for each contiguous set of bytes. */
340
b34976b6 341static bfd_boolean
252b5132
RH
342srec_scan (abfd)
343 bfd *abfd;
344{
345 int c;
346 unsigned int lineno = 1;
b34976b6 347 bfd_boolean error = FALSE;
252b5132
RH
348 bfd_byte *buf = NULL;
349 size_t bufsize = 0;
350 asection *sec = NULL;
351 char *symbuf = NULL;
352
353 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
354 goto error_return;
355
356 while ((c = srec_get_byte (abfd, &error)) != EOF)
357 {
358 /* We only build sections from contiguous S-records, so if this
b34976b6 359 is not an S-record, then stop building a section. */
252b5132
RH
360 if (c != 'S' && c != '\r' && c != '\n')
361 sec = NULL;
362
363 switch (c)
364 {
365 default:
366 srec_bad_byte (abfd, lineno, c, error);
367 goto error_return;
368
369 case '\n':
370 ++lineno;
371 break;
372
373 case '\r':
374 break;
375
376 case '$':
377 /* Starting a module name, which we ignore. */
378 while ((c = srec_get_byte (abfd, &error)) != '\n'
379 && c != EOF)
380 ;
381 if (c == EOF)
382 {
383 srec_bad_byte (abfd, lineno, c, error);
384 goto error_return;
385 }
386
387 ++lineno;
388
389 break;
390
391 case ' ':
392 do
393 {
dc810e39 394 bfd_size_type alc;
252b5132
RH
395 char *p, *symname;
396 bfd_vma symval;
397
398 /* Starting a symbol definition. */
399 while ((c = srec_get_byte (abfd, &error)) != EOF
400 && (c == ' ' || c == '\t'))
401 ;
402
403 if (c == '\n' || c == '\r')
404 break;
405
406 if (c == EOF)
407 {
408 srec_bad_byte (abfd, lineno, c, error);
409 goto error_return;
410 }
411
412 alc = 10;
413 symbuf = (char *) bfd_malloc (alc + 1);
414 if (symbuf == NULL)
415 goto error_return;
416
417 p = symbuf;
418
419 *p++ = c;
420 while ((c = srec_get_byte (abfd, &error)) != EOF
3882b010 421 && ! ISSPACE (c))
252b5132 422 {
dc810e39 423 if ((bfd_size_type) (p - symbuf) >= alc)
252b5132
RH
424 {
425 char *n;
426
427 alc *= 2;
428 n = (char *) bfd_realloc (symbuf, alc + 1);
429 if (n == NULL)
430 goto error_return;
431 p = n + (p - symbuf);
432 symbuf = n;
433 }
434
435 *p++ = c;
436 }
437
438 if (c == EOF)
439 {
440 srec_bad_byte (abfd, lineno, c, error);
441 goto error_return;
442 }
443
444 *p++ = '\0';
dc810e39 445 symname = bfd_alloc (abfd, (bfd_size_type) (p - symbuf));
252b5132
RH
446 if (symname == NULL)
447 goto error_return;
448 strcpy (symname, symbuf);
449 free (symbuf);
450 symbuf = NULL;
451
452 while ((c = srec_get_byte (abfd, &error)) != EOF
453 && (c == ' ' || c == '\t'))
454 ;
455 if (c == EOF)
456 {
457 srec_bad_byte (abfd, lineno, c, error);
458 goto error_return;
459 }
460
461 /* Skip a dollar sign before the hex value. */
462 if (c == '$')
463 {
464 c = srec_get_byte (abfd, &error);
465 if (c == EOF)
466 {
467 srec_bad_byte (abfd, lineno, c, error);
468 goto error_return;
469 }
470 }
471
472 symval = 0;
473 while (ISHEX (c))
474 {
475 symval <<= 4;
476 symval += NIBBLE (c);
477 c = srec_get_byte (abfd, &error);
478 }
479
480 if (! srec_new_symbol (abfd, symname, symval))
481 goto error_return;
482 }
c3b7c767
NC
483 while (c == ' ' || c == '\t')
484 ;
252b5132
RH
485
486 if (c == '\n')
487 ++lineno;
488 else if (c != '\r')
489 {
490 srec_bad_byte (abfd, lineno, c, error);
491 goto error_return;
492 }
493
494 break;
c3b7c767 495
252b5132
RH
496 case 'S':
497 {
498 file_ptr pos;
499 char hdr[3];
500 unsigned int bytes;
501 bfd_vma address;
502 bfd_byte *data;
503
504 /* Starting an S-record. */
505
506 pos = bfd_tell (abfd) - 1;
507
dc810e39 508 if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3)
252b5132
RH
509 goto error_return;
510
511 if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
512 {
513 if (! ISHEX (hdr[1]))
514 c = hdr[1];
515 else
516 c = hdr[2];
517 srec_bad_byte (abfd, lineno, c, error);
518 goto error_return;
519 }
520
521 bytes = HEX (hdr + 1);
522 if (bytes * 2 > bufsize)
523 {
524 if (buf != NULL)
525 free (buf);
dc810e39 526 buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2);
252b5132
RH
527 if (buf == NULL)
528 goto error_return;
529 bufsize = bytes * 2;
530 }
531
dc810e39 532 if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2)
252b5132
RH
533 goto error_return;
534
535 /* Ignore the checksum byte. */
536 --bytes;
537
538 address = 0;
539 data = buf;
540 switch (hdr[0])
541 {
542 case '0':
543 case '5':
544 /* Prologue--ignore the file name, but stop building a
b34976b6 545 section at this point. */
252b5132
RH
546 sec = NULL;
547 break;
548
549 case '3':
550 address = HEX (data);
551 data += 2;
552 --bytes;
553 /* Fall through. */
554 case '2':
555 address = (address << 8) | HEX (data);
556 data += 2;
557 --bytes;
558 /* Fall through. */
559 case '1':
560 address = (address << 8) | HEX (data);
561 data += 2;
562 address = (address << 8) | HEX (data);
563 data += 2;
564 bytes -= 2;
565
566 if (sec != NULL
567 && sec->vma + sec->_raw_size == address)
568 {
569 /* This data goes at the end of the section we are
b34976b6 570 currently building. */
252b5132
RH
571 sec->_raw_size += bytes;
572 }
573 else
574 {
575 char secbuf[20];
576 char *secname;
dc810e39 577 bfd_size_type amt;
252b5132
RH
578
579 sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
dc810e39
AM
580 amt = strlen (secbuf) + 1;
581 secname = (char *) bfd_alloc (abfd, amt);
252b5132
RH
582 strcpy (secname, secbuf);
583 sec = bfd_make_section (abfd, secname);
584 if (sec == NULL)
585 goto error_return;
586 sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
587 sec->vma = address;
588 sec->lma = address;
589 sec->_raw_size = bytes;
590 sec->filepos = pos;
591 }
592
593 break;
594
595 case '7':
596 address = HEX (data);
597 data += 2;
598 /* Fall through. */
599 case '8':
600 address = (address << 8) | HEX (data);
601 data += 2;
602 /* Fall through. */
603 case '9':
604 address = (address << 8) | HEX (data);
605 data += 2;
606 address = (address << 8) | HEX (data);
607 data += 2;
608
609 /* This is a termination record. */
610 abfd->start_address = address;
611
612 if (buf != NULL)
613 free (buf);
614
b34976b6 615 return TRUE;
252b5132
RH
616 }
617 }
618 break;
619 }
620 }
621
622 if (error)
623 goto error_return;
624
625 if (buf != NULL)
626 free (buf);
627
b34976b6 628 return TRUE;
252b5132
RH
629
630 error_return:
631 if (symbuf != NULL)
632 free (symbuf);
633 if (buf != NULL)
634 free (buf);
b34976b6 635 return FALSE;
252b5132
RH
636}
637
638/* Check whether an existing file is an S-record file. */
639
640static const bfd_target *
641srec_object_p (abfd)
642 bfd *abfd;
643{
487e54f2 644 PTR tdata_save;
252b5132
RH
645 bfd_byte b[4];
646
647 srec_init ();
648
649 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
dc810e39 650 || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
252b5132
RH
651 return NULL;
652
653 if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
654 {
655 bfd_set_error (bfd_error_wrong_format);
656 return NULL;
657 }
658
487e54f2
AM
659 tdata_save = abfd->tdata.any;
660 if (! srec_mkobject (abfd) || ! srec_scan (abfd))
661 {
662 if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
663 bfd_release (abfd, abfd->tdata.any);
664 abfd->tdata.any = tdata_save;
665 return NULL;
666 }
252b5132
RH
667
668 if (abfd->symcount > 0)
669 abfd->flags |= HAS_SYMS;
670
671 return abfd->xvec;
672}
673
674/* Check whether an existing file is an S-record file with symbols. */
675
676static const bfd_target *
677symbolsrec_object_p (abfd)
678 bfd *abfd;
679{
487e54f2 680 PTR tdata_save;
252b5132
RH
681 char b[2];
682
683 srec_init ();
684
685 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
dc810e39 686 || bfd_bread (b, (bfd_size_type) 2, abfd) != 2)
252b5132
RH
687 return NULL;
688
689 if (b[0] != '$' || b[1] != '$')
690 {
691 bfd_set_error (bfd_error_wrong_format);
692 return NULL;
693 }
694
487e54f2
AM
695 tdata_save = abfd->tdata.any;
696 if (! srec_mkobject (abfd) || ! srec_scan (abfd))
697 {
698 if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
699 bfd_release (abfd, abfd->tdata.any);
700 abfd->tdata.any = tdata_save;
701 return NULL;
702 }
252b5132
RH
703
704 if (abfd->symcount > 0)
705 abfd->flags |= HAS_SYMS;
706
707 return abfd->xvec;
708}
709
710/* Read in the contents of a section in an S-record file. */
711
b34976b6 712static bfd_boolean
252b5132
RH
713srec_read_section (abfd, section, contents)
714 bfd *abfd;
715 asection *section;
716 bfd_byte *contents;
717{
718 int c;
719 bfd_size_type sofar = 0;
b34976b6 720 bfd_boolean error = FALSE;
252b5132
RH
721 bfd_byte *buf = NULL;
722 size_t bufsize = 0;
723
724 if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
725 goto error_return;
726
727 while ((c = srec_get_byte (abfd, &error)) != EOF)
728 {
729 bfd_byte hdr[3];
730 unsigned int bytes;
731 bfd_vma address;
732 bfd_byte *data;
733
734 if (c == '\r' || c == '\n')
735 continue;
736
737 /* This is called after srec_scan has already been called, so we
b34976b6 738 ought to know the exact format. */
252b5132
RH
739 BFD_ASSERT (c == 'S');
740
dc810e39 741 if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3)
252b5132
RH
742 goto error_return;
743
744 BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
745
746 bytes = HEX (hdr + 1);
747
748 if (bytes * 2 > bufsize)
749 {
750 if (buf != NULL)
751 free (buf);
dc810e39 752 buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2);
252b5132
RH
753 if (buf == NULL)
754 goto error_return;
755 bufsize = bytes * 2;
756 }
757
dc810e39 758 if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2)
252b5132
RH
759 goto error_return;
760
761 address = 0;
762 data = buf;
763 switch (hdr[0])
764 {
765 default:
766 BFD_ASSERT (sofar == section->_raw_size);
767 if (buf != NULL)
768 free (buf);
b34976b6 769 return TRUE;
252b5132
RH
770
771 case '3':
772 address = HEX (data);
773 data += 2;
774 --bytes;
775 /* Fall through. */
776 case '2':
777 address = (address << 8) | HEX (data);
778 data += 2;
779 --bytes;
780 /* Fall through. */
781 case '1':
782 address = (address << 8) | HEX (data);
783 data += 2;
784 address = (address << 8) | HEX (data);
785 data += 2;
786 bytes -= 2;
787
788 if (address != section->vma + sofar)
789 {
790 /* We've come to the end of this section. */
791 BFD_ASSERT (sofar == section->_raw_size);
792 if (buf != NULL)
793 free (buf);
b34976b6 794 return TRUE;
252b5132
RH
795 }
796
797 /* Don't consider checksum. */
798 --bytes;
799
800 while (bytes-- != 0)
801 {
802 contents[sofar] = HEX (data);
803 data += 2;
804 ++sofar;
805 }
806
807 break;
808 }
809 }
810
811 if (error)
812 goto error_return;
813
814 BFD_ASSERT (sofar == section->_raw_size);
815
816 if (buf != NULL)
817 free (buf);
818
b34976b6 819 return TRUE;
252b5132
RH
820
821 error_return:
822 if (buf != NULL)
823 free (buf);
b34976b6 824 return FALSE;
252b5132
RH
825}
826
827/* Get the contents of a section in an S-record file. */
828
b34976b6 829static bfd_boolean
252b5132
RH
830srec_get_section_contents (abfd, section, location, offset, count)
831 bfd *abfd;
832 asection *section;
833 PTR location;
834 file_ptr offset;
835 bfd_size_type count;
836{
837 if (section->used_by_bfd == NULL)
838 {
839 section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
dc810e39 840 if (section->used_by_bfd == NULL && section->_raw_size != 0)
b34976b6 841 return FALSE;
252b5132
RH
842
843 if (! srec_read_section (abfd, section, section->used_by_bfd))
b34976b6 844 return FALSE;
252b5132
RH
845 }
846
847 memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
848 (size_t) count);
849
b34976b6 850 return TRUE;
252b5132
RH
851}
852
853/* Set the architecture. We accept an unknown architecture here. */
854
b34976b6 855static bfd_boolean
252b5132
RH
856srec_set_arch_mach (abfd, arch, mach)
857 bfd *abfd;
858 enum bfd_architecture arch;
859 unsigned long mach;
860{
861 if (arch == bfd_arch_unknown)
862 {
863 abfd->arch_info = &bfd_default_arch_struct;
b34976b6 864 return TRUE;
252b5132
RH
865 }
866 return bfd_default_set_arch_mach (abfd, arch, mach);
867}
868
c3b7c767 869/* We have to save up all the Srecords for a splurge before output. */
252b5132 870
b34976b6 871static bfd_boolean
252b5132
RH
872srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
873 bfd *abfd;
874 sec_ptr section;
0f867abe 875 const PTR location;
252b5132
RH
876 file_ptr offset;
877 bfd_size_type bytes_to_do;
878{
879 tdata_type *tdata = abfd->tdata.srec_data;
880 register srec_data_list_type *entry;
881
882 entry = ((srec_data_list_type *)
dc810e39 883 bfd_alloc (abfd, (bfd_size_type) sizeof (srec_data_list_type)));
252b5132 884 if (entry == NULL)
b34976b6 885 return FALSE;
252b5132
RH
886
887 if (bytes_to_do
888 && (section->flags & SEC_ALLOC)
889 && (section->flags & SEC_LOAD))
890 {
dc810e39
AM
891 bfd_byte *data;
892
893 data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
252b5132 894 if (data == NULL)
b34976b6 895 return FALSE;
252b5132
RH
896 memcpy ((PTR) data, location, (size_t) bytes_to_do);
897
b34976b6 898 /* Ff S3Forced is TRUE then always select S3 records,
420496c1
NC
899 regardless of the siez of the addresses. */
900 if (S3Forced)
901 tdata->type = 3;
7b82c249 902 else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
420496c1 903 ; /* The default, S1, is OK. */
252b5132
RH
904 else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
905 && tdata->type <= 2)
420496c1 906 tdata->type = 2;
252b5132 907 else
420496c1 908 tdata->type = 3;
252b5132
RH
909
910 entry->data = data;
911 entry->where = section->lma + offset;
912 entry->size = bytes_to_do;
913
914 /* Sort the records by address. Optimize for the common case of
b34976b6 915 adding a record to the end of the list. */
252b5132
RH
916 if (tdata->tail != NULL
917 && entry->where >= tdata->tail->where)
918 {
919 tdata->tail->next = entry;
920 entry->next = NULL;
921 tdata->tail = entry;
922 }
923 else
924 {
925 register srec_data_list_type **look;
926
927 for (look = &tdata->head;
928 *look != NULL && (*look)->where < entry->where;
929 look = &(*look)->next)
930 ;
931 entry->next = *look;
932 *look = entry;
933 if (entry->next == NULL)
934 tdata->tail = entry;
935 }
936 }
b34976b6 937 return TRUE;
252b5132
RH
938}
939
940/* Write a record of type, of the supplied number of bytes. The
941 supplied bytes and length don't have a checksum. That's worked out
c3b7c767
NC
942 here. */
943
b34976b6 944static bfd_boolean
252b5132
RH
945srec_write_record (abfd, type, address, data, end)
946 bfd *abfd;
dc810e39 947 unsigned int type;
252b5132
RH
948 bfd_vma address;
949 const bfd_byte *data;
950 const bfd_byte *end;
951{
d8dce692 952 char buffer[2 * MAXCHUNK + 6];
252b5132 953 unsigned int check_sum = 0;
dc810e39 954 const bfd_byte *src = data;
252b5132
RH
955 char *dst = buffer;
956 char *length;
957 bfd_size_type wrlen;
958
959 *dst++ = 'S';
960 *dst++ = '0' + type;
961
962 length = dst;
c3b7c767 963 dst += 2; /* Leave room for dst. */
252b5132
RH
964
965 switch (type)
966 {
967 case 3:
968 case 7:
969 TOHEX (dst, (address >> 24), check_sum);
970 dst += 2;
971 case 8:
972 case 2:
973 TOHEX (dst, (address >> 16), check_sum);
974 dst += 2;
975 case 9:
976 case 1:
977 case 0:
978 TOHEX (dst, (address >> 8), check_sum);
979 dst += 2;
980 TOHEX (dst, (address), check_sum);
981 dst += 2;
982 break;
983
984 }
985 for (src = data; src < end; src++)
986 {
987 TOHEX (dst, *src, check_sum);
988 dst += 2;
989 }
990
c3b7c767 991 /* Fill in the length. */
252b5132
RH
992 TOHEX (length, (dst - length) / 2, check_sum);
993 check_sum &= 0xff;
994 check_sum = 255 - check_sum;
995 TOHEX (dst, check_sum, check_sum);
996 dst += 2;
997
998 *dst++ = '\r';
999 *dst++ = '\n';
1000 wrlen = dst - buffer;
dc810e39 1001 if (bfd_bwrite ((PTR) buffer, wrlen, abfd) != wrlen)
b34976b6
AM
1002 return FALSE;
1003 return TRUE;
252b5132
RH
1004}
1005
b34976b6 1006static bfd_boolean
252b5132
RH
1007srec_write_header (abfd)
1008 bfd *abfd;
1009{
d8dce692 1010 unsigned int len = strlen (abfd->filename);
252b5132 1011
7dee875e 1012 /* I'll put an arbitrary 40 char limit on header size. */
d8dce692
AM
1013 if (len > 40)
1014 len = 40;
c3b7c767 1015
d8dce692
AM
1016 return srec_write_record (abfd, 0, (bfd_vma) 0,
1017 abfd->filename, abfd->filename + len);
252b5132
RH
1018}
1019
b34976b6 1020static bfd_boolean
252b5132
RH
1021srec_write_section (abfd, tdata, list)
1022 bfd *abfd;
1023 tdata_type *tdata;
1024 srec_data_list_type *list;
1025{
9a968f43 1026 unsigned int octets_written = 0;
252b5132
RH
1027 bfd_byte *location = list->data;
1028
d8dce692
AM
1029 /* Validate number of data bytes to write. The srec length byte
1030 counts the address, data and crc bytes. S1 (tdata->type == 1)
1031 records have two address bytes, S2 (tdata->type == 2) records
1032 have three, and S3 (tdata->type == 3) records have four.
1033 The total length can't exceed 255, and a zero data length will
1034 spin for a long time. */
1035 if (Chunk == 0)
1036 Chunk = 1;
1037 else if (Chunk > MAXCHUNK - tdata->type - 2)
1038 Chunk = MAXCHUNK - tdata->type - 2;
1039
9a968f43 1040 while (octets_written < list->size)
252b5132
RH
1041 {
1042 bfd_vma address;
9a968f43 1043 unsigned int octets_this_chunk = list->size - octets_written;
252b5132 1044
420496c1
NC
1045 if (octets_this_chunk > Chunk)
1046 octets_this_chunk = Chunk;
252b5132 1047
9a968f43 1048 address = list->where + octets_written / bfd_octets_per_byte (abfd);
252b5132
RH
1049
1050 if (! srec_write_record (abfd,
1051 tdata->type,
1052 address,
1053 location,
9a968f43 1054 location + octets_this_chunk))
b34976b6 1055 return FALSE;
252b5132 1056
9a968f43
NC
1057 octets_written += octets_this_chunk;
1058 location += octets_this_chunk;
252b5132
RH
1059 }
1060
b34976b6 1061 return TRUE;
252b5132
RH
1062}
1063
b34976b6 1064static bfd_boolean
252b5132
RH
1065srec_write_terminator (abfd, tdata)
1066 bfd *abfd;
1067 tdata_type *tdata;
1068{
252b5132 1069 return srec_write_record (abfd, 10 - tdata->type,
d8dce692 1070 abfd->start_address, NULL, NULL);
252b5132
RH
1071}
1072
b34976b6 1073static bfd_boolean
252b5132
RH
1074srec_write_symbols (abfd)
1075 bfd *abfd;
1076{
c3b7c767 1077 /* Dump out the symbols of a bfd. */
252b5132
RH
1078 int i;
1079 int count = bfd_get_symcount (abfd);
1080
1081 if (count)
1082 {
dc810e39 1083 bfd_size_type len;
252b5132 1084 asymbol **table = bfd_get_outsymbols (abfd);
d8dce692
AM
1085 len = strlen (abfd->filename);
1086 if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3
1087 || bfd_bwrite (abfd->filename, len, abfd) != len
1088 || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2)
b34976b6 1089 return FALSE;
252b5132
RH
1090
1091 for (i = 0; i < count; i++)
1092 {
1093 asymbol *s = table[i];
1094 if (! bfd_is_local_label (abfd, s)
1095 && (s->flags & BSF_DEBUGGING) == 0)
1096 {
c3b7c767 1097 /* Just dump out non debug symbols. */
c5c1944d 1098 char buf[43], *p;
d8dce692
AM
1099
1100 len = strlen (s->name);
1101 if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2
1102 || bfd_bwrite (s->name, len, abfd) != len)
b34976b6 1103 return FALSE;
252b5132 1104
c5c1944d 1105 sprintf_vma (buf + 2, (s->value
d8dce692
AM
1106 + s->section->output_section->lma
1107 + s->section->output_offset));
c5c1944d 1108 p = buf + 2;
252b5132
RH
1109 while (p[0] == '0' && p[1] != 0)
1110 p++;
d8dce692
AM
1111 len = strlen (p);
1112 p[len] = '\r';
1113 p[len + 1] = '\n';
c5c1944d 1114 *--p = '$';
d8dce692 1115 *--p = ' ';
c5c1944d 1116 len += 4;
d8dce692 1117 if (bfd_bwrite (p, len, abfd) != len)
b34976b6 1118 return FALSE;
252b5132
RH
1119 }
1120 }
d8dce692 1121 if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5)
b34976b6 1122 return FALSE;
252b5132
RH
1123 }
1124
b34976b6 1125 return TRUE;
252b5132
RH
1126}
1127
b34976b6 1128static bfd_boolean
252b5132
RH
1129internal_srec_write_object_contents (abfd, symbols)
1130 bfd *abfd;
1131 int symbols;
1132{
1133 tdata_type *tdata = abfd->tdata.srec_data;
1134 srec_data_list_type *list;
1135
1136 if (symbols)
1137 {
1138 if (! srec_write_symbols (abfd))
b34976b6 1139 return FALSE;
252b5132
RH
1140 }
1141
1142 if (! srec_write_header (abfd))
b34976b6 1143 return FALSE;
252b5132 1144
c3b7c767 1145 /* Now wander though all the sections provided and output them. */
252b5132
RH
1146 list = tdata->head;
1147
1148 while (list != (srec_data_list_type *) NULL)
1149 {
1150 if (! srec_write_section (abfd, tdata, list))
b34976b6 1151 return FALSE;
252b5132
RH
1152 list = list->next;
1153 }
1154 return srec_write_terminator (abfd, tdata);
1155}
1156
b34976b6 1157static bfd_boolean
252b5132
RH
1158srec_write_object_contents (abfd)
1159 bfd *abfd;
1160{
1161 return internal_srec_write_object_contents (abfd, 0);
1162}
1163
b34976b6 1164static bfd_boolean
252b5132
RH
1165symbolsrec_write_object_contents (abfd)
1166 bfd *abfd;
1167{
1168 return internal_srec_write_object_contents (abfd, 1);
1169}
1170
252b5132
RH
1171static int
1172srec_sizeof_headers (abfd, exec)
7442e600 1173 bfd *abfd ATTRIBUTE_UNUSED;
b34976b6 1174 bfd_boolean exec ATTRIBUTE_UNUSED;
252b5132
RH
1175{
1176 return 0;
1177}
1178
252b5132
RH
1179/* Return the amount of memory needed to read the symbol table. */
1180
1181static long
1182srec_get_symtab_upper_bound (abfd)
1183 bfd *abfd;
1184{
1185 return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
1186}
1187
1188/* Return the symbol table. */
1189
1190static long
6cee3f79 1191srec_canonicalize_symtab (abfd, alocation)
252b5132
RH
1192 bfd *abfd;
1193 asymbol **alocation;
1194{
dc810e39 1195 bfd_size_type symcount = bfd_get_symcount (abfd);
252b5132
RH
1196 asymbol *csymbols;
1197 unsigned int i;
1198
1199 csymbols = abfd->tdata.srec_data->csymbols;
1200 if (csymbols == NULL)
1201 {
1202 asymbol *c;
1203 struct srec_symbol *s;
1204
1205 csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
1206 if (csymbols == NULL && symcount != 0)
c5c1944d 1207 return 0;
252b5132
RH
1208 abfd->tdata.srec_data->csymbols = csymbols;
1209
1210 for (s = abfd->tdata.srec_data->symbols, c = csymbols;
1211 s != NULL;
1212 s = s->next, ++c)
1213 {
1214 c->the_bfd = abfd;
1215 c->name = s->name;
1216 c->value = s->val;
1217 c->flags = BSF_GLOBAL;
1218 c->section = bfd_abs_section_ptr;
1219 c->udata.p = NULL;
1220 }
1221 }
c3b7c767 1222
252b5132
RH
1223 for (i = 0; i < symcount; i++)
1224 *alocation++ = csymbols++;
1225 *alocation = NULL;
1226
1227 return symcount;
1228}
1229
252b5132
RH
1230static void
1231srec_get_symbol_info (ignore_abfd, symbol, ret)
7442e600 1232 bfd *ignore_abfd ATTRIBUTE_UNUSED;
252b5132
RH
1233 asymbol *symbol;
1234 symbol_info *ret;
1235{
1236 bfd_symbol_info (symbol, ret);
1237}
1238
252b5132 1239static void
60b89a18
L
1240srec_print_symbol (abfd, afile, symbol, how)
1241 bfd *abfd;
252b5132
RH
1242 PTR afile;
1243 asymbol *symbol;
1244 bfd_print_symbol_type how;
1245{
1246 FILE *file = (FILE *) afile;
1247 switch (how)
1248 {
1249 case bfd_print_symbol_name:
1250 fprintf (file, "%s", symbol->name);
1251 break;
1252 default:
60b89a18 1253 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
252b5132
RH
1254 fprintf (file, " %-5s %s",
1255 symbol->section->name,
1256 symbol->name);
1257
1258 }
1259}
1260
1261#define srec_close_and_cleanup _bfd_generic_close_and_cleanup
1262#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1263#define srec_new_section_hook _bfd_generic_new_section_hook
1264
1265#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name
1266#define srec_get_lineno _bfd_nosymbols_get_lineno
1267#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
3f3c5c34 1268#define srec_make_empty_symbol _bfd_generic_make_empty_symbol
252b5132
RH
1269#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1270#define srec_read_minisymbols _bfd_generic_read_minisymbols
1271#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1272
1273#define srec_get_reloc_upper_bound \
1274 ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
1275#define srec_canonicalize_reloc \
1276 ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
1277#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1278
1279#define srec_get_section_contents_in_window \
1280 _bfd_generic_get_section_contents_in_window
1281
1282#define srec_bfd_get_relocated_section_contents \
1283 bfd_generic_get_relocated_section_contents
1284#define srec_bfd_relax_section bfd_generic_relax_section
1285#define srec_bfd_gc_sections bfd_generic_gc_sections
8550eb6e 1286#define srec_bfd_merge_sections bfd_generic_merge_sections
72adc230 1287#define srec_bfd_is_group_section bfd_generic_is_group_section
e61463e1 1288#define srec_bfd_discard_group bfd_generic_discard_group
252b5132 1289#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
e2d34d7d 1290#define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
252b5132 1291#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
2d653fc7 1292#define srec_bfd_link_just_syms _bfd_generic_link_just_syms
252b5132
RH
1293#define srec_bfd_final_link _bfd_generic_final_link
1294#define srec_bfd_link_split_section _bfd_generic_link_split_section
1295
1296const bfd_target srec_vec =
1297{
1298 "srec", /* name */
1299 bfd_target_srec_flavour,
1300 BFD_ENDIAN_UNKNOWN, /* target byte order */
1301 BFD_ENDIAN_UNKNOWN, /* target headers byte order */
1302 (HAS_RELOC | EXEC_P | /* object flags */
1303 HAS_LINENO | HAS_DEBUG |
1304 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1305 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1306 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1307 0, /* leading underscore */
1308 ' ', /* ar_pad_char */
1309 16, /* ar_max_namelen */
1310 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1311 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1312 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1313 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1314 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1315 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1316
1317 {
1318 _bfd_dummy_target,
1319 srec_object_p, /* bfd_check_format */
1320 _bfd_dummy_target,
1321 _bfd_dummy_target,
1322 },
1323 {
1324 bfd_false,
1325 srec_mkobject,
1326 _bfd_generic_mkarchive,
1327 bfd_false,
1328 },
1329 { /* bfd_write_contents */
1330 bfd_false,
1331 srec_write_object_contents,
1332 _bfd_write_archive_contents,
1333 bfd_false,
1334 },
1335
1336 BFD_JUMP_TABLE_GENERIC (srec),
1337 BFD_JUMP_TABLE_COPY (_bfd_generic),
1338 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1339 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1340 BFD_JUMP_TABLE_SYMBOLS (srec),
1341 BFD_JUMP_TABLE_RELOCS (srec),
1342 BFD_JUMP_TABLE_WRITE (srec),
1343 BFD_JUMP_TABLE_LINK (srec),
1344 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1345
c3c89269 1346 NULL,
c3b7c767 1347
252b5132
RH
1348 (PTR) 0
1349};
1350
252b5132
RH
1351const bfd_target symbolsrec_vec =
1352{
1353 "symbolsrec", /* name */
1354 bfd_target_srec_flavour,
1355 BFD_ENDIAN_UNKNOWN, /* target byte order */
1356 BFD_ENDIAN_UNKNOWN, /* target headers byte order */
1357 (HAS_RELOC | EXEC_P | /* object flags */
1358 HAS_LINENO | HAS_DEBUG |
1359 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1360 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1361 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1362 0, /* leading underscore */
1363 ' ', /* ar_pad_char */
1364 16, /* ar_max_namelen */
1365 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1366 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1367 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1368 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1369 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1370 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1371
1372 {
1373 _bfd_dummy_target,
1374 symbolsrec_object_p, /* bfd_check_format */
1375 _bfd_dummy_target,
1376 _bfd_dummy_target,
1377 },
1378 {
1379 bfd_false,
1380 srec_mkobject,
1381 _bfd_generic_mkarchive,
1382 bfd_false,
1383 },
1384 { /* bfd_write_contents */
1385 bfd_false,
1386 symbolsrec_write_object_contents,
1387 _bfd_write_archive_contents,
1388 bfd_false,
1389 },
1390
1391 BFD_JUMP_TABLE_GENERIC (srec),
1392 BFD_JUMP_TABLE_COPY (_bfd_generic),
1393 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1394 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1395 BFD_JUMP_TABLE_SYMBOLS (srec),
1396 BFD_JUMP_TABLE_RELOCS (srec),
1397 BFD_JUMP_TABLE_WRITE (srec),
1398 BFD_JUMP_TABLE_LINK (srec),
1399 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1400
c3c89269 1401 NULL,
c3b7c767 1402
252b5132
RH
1403 (PTR) 0
1404};
This page took 0.365479 seconds and 4 git commands to generate.