Pick three bugfixes from next branch to trunk for inclusion in 4.5.0 RC2, as discusse...
[sdcc.git] / sdcc / support / sdbinutils / bfd / asxxxx.c
blobb6dc184eb958d7955eab23887e391d3f2161fe9d
1 /* BFD back-end for asxxxx .rel objects.
2 Copyright 2011
3 Borut Razem (Free Software Foundation, Inc.)
4 Written by Borut Razem <borut.razem@gmail.com>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 /* SUBSECTION
25 The object module contains the following designators:
27 [XDQ][HL][234]
28 X Hexadecimal radix
29 D Decimal radix
30 Q Octal radix
32 H Most significant byte first
33 L Least significant byte first
35 2 16-Bit Addressing
36 3 24-Bit Addressing
37 4 32-Bit Addressing
39 H Header
40 M Module
41 G Merge Mode
42 B Bank
43 A Area
44 S Symbol
45 T Object code
46 R Relocation information
47 P Paging information
49 3.5.1 Object Module Format
50 [XDQ][HL][234]
52 3.5.2 Header Line
53 H aa areas gg global symbols
55 3.5.3 Module Line
56 M name
58 3.5.4 Merge Mode Line
59 G nn ii 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
61 3.5.5 Bank Line
62 B name base nn size nn map nn flags nn fsfx string
64 3.5.6 Area Line
65 A label size ss flags ff
67 3.5.7 Symbol Line
68 S name Defnnnn
70 S name Refnnnn
72 3.5.8 T Line
73 T xx xx nn nn nn nn nn ...
75 3.5.9 R Line
76 R 0 0 nn nn n1 n2 xx xx ...
78 3.5.10 P Line
79 P 0 0 nn nn n1 n2 xx xx
82 #include "sysdep.h"
83 #include "bfd.h"
84 #include "libbfd.h"
85 #include "libiberty.h"
86 #include "safe-ctype.h"
88 #define asxxxx_bfd_group_name bfd_generic_group_name
89 #define asxxxx_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
93 #define NELEM(x) (sizeof (x) / sizeof (x)[0])
95 /* ******************* from asld aslink.h ******************* */
97 * ASLINK - Version 3 Definitions
101 * The "A3_" area constants define values used in
102 * generating the assembler area output data.
104 * Area flags
106 * 8 7 6 5 4 3 2 1 0
107 * A_ A_ A_ A_ A3_ A3_ A3_
108 * +-----++-----+-----+-----+-----+-----+-----+-----+-----+
109 * |LOAD || BIT |XDATA|CODE | PAG | ABS | OVR | | |
110 * +-----++-----+-----+-----+-----+-----+-----+-----+-----+
113 #define A3_CON 000 /* concatenate */
114 #define A3_OVR 004 /* overlay */
115 #define A3_REL 000 /* relocatable */
116 #define A3_ABS 010 /* absolute */
117 #define A3_NOPAG 000 /* non-paged */
118 #define A3_PAG 020 /* paged */
120 /* sdld specific */
121 /* Additional flags for 8051 address spaces */
122 #define A_DATA 0000 /* data space (default)*/
123 #define A_CODE 0040 /* code space */
124 #define A_XDATA 0100 /* external data space */
125 #define A_BIT 0200 /* bit addressable space */
127 /* Additional flags for hc08 */
128 #define A_NOLOAD 0400 /* nonloadable */
129 #define A_LOAD 0000 /* loadable (default) */
130 /* end sdld specific */
133 * ASLINK - Version 4 Definitions
137 * The "A4_" area constants define values used in
138 * generating the assembler area output data.
140 * Area flags
142 * 7 6 5 4 3 2 1 0
143 * +-----+-----+-----+-----+-----+-----+-----+-----+
144 * | BNK | SEG | | PAG | ABS | OVR | WL1 | WL0 |
145 * +-----+-----+-----+-----+-----+-----+-----+-----+
148 #define A4_BYTE 0x0000 /* 8 bit */
149 #define A4_WORD 0x0001 /* 16 bit */
151 #define A4_1BYTE 0x0000 /* 1 Byte Word Length */
152 #define A4_2BYTE 0x0001 /* 2 Byte Word Length */
153 #define A4_3BYTE 0x0002 /* 3 Byte Word Length */
154 #define A4_4BYTE 0x0003 /* 4 Byte Word Length */
155 #define A4_WLMSK 0x0003 /* Word Length Mask */
157 #define A4_CON 0x0400 /* Concatenating */
158 #define A4_OVR 0x0404 /* Overlaying */
159 #define A4_REL 0x0800 /* Relocatable */
160 #define A4_ABS 0x0808 /* absolute */
161 #define A4_NOPAG 0x1000 /* Non-Paged */
162 #define A4_PAG 0x1010 /* Paged */
164 #define A4_CSEG 0x4000 /* CSEG */
165 #define A4_DSEG 0x4040 /* DSEG */
166 #define A4_NOBNK 0x8000 /* Non-Banked */
167 #define A4_BNK 0x8080 /* Banked */
169 #define A4_OUT 0x0100 /* Output Code Flag */
170 /* ********************************************************** */
172 /* Macros for converting between hex and binary. */
174 #define NIBBLE(x) hex_value(x)
175 #define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1]))
176 #define ISHEX(x) hex_p(x)
178 /* When scanning the asxxxx .rel file, a linked list of asxxxx_symbol
179 structures is built to represent the symbol table (if there is
180 one). */
182 struct asxxxx_symbol
184 struct asxxxx_symbol *next;
185 const char *name;
186 symvalue val;
187 flagword flags;
188 struct bfd_section *section;
191 /* The asxxxx .rel tdata information. */
193 enum asxxxx_cpu_type_e
195 CPU_UNKNOWN = 0,
196 CPU_MCS51,
197 CPU_DS390,
198 CPU_DS400,
199 CPU_HC08,
200 CPU_Z80,
201 CPU_GBZ80,
202 CPU_R2K,
205 enum asxxxx_rel_version_e
207 REL_VER_3 = 0,
208 REL_VER_4,
211 enum asxxxx_radix_e
213 RADIX_OCT = 8,
214 RADIX_DEC = 10,
215 RADIX_HEX = 16,
218 enum asxxxx_endian_e
220 ENDIAN_LITTLE = 0,
221 ENDIAN_BIG,
224 enum asxxxx_address_size_e
226 ADDR_SIZE_2 = 2,
227 ADDR_SIZE_3 = 3,
228 ADDR_SIZE_4 = 4,
231 typedef struct asxxxx_data_struct
233 struct asxxxx_symbol *symbols;
234 struct asxxxx_symbol *symtail;
235 asymbol *csymbols;
236 asection *sections;
237 asection *secttail;
238 #define CURRENT_SECT(abfd) ((abfd)->tdata.asxxxx_data->secttail)
240 unsigned int sect_id;
241 #define NEXT_SECT_ID(abfd) (++(abfd)->tdata.asxxxx_data->sect_id)
243 enum asxxxx_cpu_type_e cpu_type;
244 #define SET_CPU_TYPE(abfd, type) ((abfd)->tdata.asxxxx_data->cpu_type = (type))
245 #define GET_CPU_TYPE(abfd) ((abfd)->tdata.asxxxx_data->cpu_type)
247 enum asxxxx_rel_version_e rel_version;
248 #define SET_REL_VERSION(abfd, version) ((abfd)->tdata.asxxxx_data->rel_version = (version))
249 #define GET_REL_VERSION(abfd) ((abfd)->tdata.asxxxx_data->rel_version)
251 enum asxxxx_radix_e radix;
252 #define SET_RADIX(abfd, r) ((abfd)->tdata.asxxxx_data->radix = (r))
253 #define GET_RADIX(abfd) ((abfd)->tdata.asxxxx_data->radix)
255 enum asxxxx_endian_e endian;
256 #define SET_ENDIAN(abfd, e) ((abfd)->tdata.asxxxx_data->endian = (e))
257 #define GET_ENDIAN(abfd) ((abfd)->tdata.asxxxx_data->endian)
259 enum asxxxx_address_size_e address_size;
260 #define SET_ADDRESS_SIZE(abfd, as) ((abfd)->tdata.asxxxx_data->address_size = (as))
261 #define GET_ADDRESS_SIZE(abfd) ((abfd)->tdata.asxxxx_data->address_size)
263 tdata_type;
265 /* Initialize by filling in the hex conversion array. */
267 static void
268 asxxxx_init (void)
270 static bool inited = false;
272 if (! inited)
274 inited = true;
275 hex_init ();
279 /* Set up the asxxxx .rel tdata information. */
281 static bool
282 asxxxx_mkobject (bfd *abfd)
284 tdata_type *tdata;
286 asxxxx_init ();
288 tdata = (tdata_type *) bfd_zalloc (abfd, sizeof (tdata_type));
289 if (tdata == NULL)
290 return false;
292 abfd->tdata.asxxxx_data = tdata;
294 return true;
297 /* Read a byte from an asxxxx .rel file. Set *ERRORPTR if an error
298 occurred. Return EOF on error or end of file. */
300 static int
301 asxxxx_get_byte (bfd *abfd, bool *errorptr)
303 bfd_byte c;
305 if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
307 if (bfd_get_error () == bfd_error_invalid_operation){
308 // FEATURE? // this error is set at EOF
309 // BUG // caller expects no error
310 } else if (bfd_get_error () == bfd_error_file_truncated){
311 // possibly this error was set at EOF in binutils<2.38
312 } else {
313 *errorptr = true;
315 return EOF;
318 return (int) (c & 0xff);
321 /* Report a problem in an asxxxx .rel file. FIXME: This probably should
322 not call fprintf, but we really do need some mechanism for printing
323 error messages. */
325 static void
326 asxxxx_bad_byte (bfd *abfd,
327 int c,
328 unsigned int lineno,
329 bool error)
331 if (c == EOF)
333 if (! error)
334 bfd_set_error (bfd_error_file_truncated);
336 else
338 char buf[16];
340 if (! ISPRINT (c))
341 sprintf (buf, "\\%03o", (unsigned int) c);
342 else
344 buf[0] = c;
345 buf[1] = '\0';
347 (*_bfd_error_handler)
348 (_("%pB:%d: Unexpected character `%s' in asxxxx .rel file\n"),
349 abfd, lineno, buf);
350 bfd_set_error (bfd_error_bad_value);
354 /* Add a new symbol found in an asxxxx .rel file. */
356 static bool
357 asxxxx_new_symbol (bfd *abfd, const char *name, symvalue val, flagword flags, struct bfd_section *section)
359 struct asxxxx_symbol *n;
361 n = (struct asxxxx_symbol *) bfd_alloc (abfd, sizeof (* n));
362 if (n == NULL)
363 return false;
365 n->name = name;
366 n->val = val;
367 n->flags = flags;
368 n->section = section;
370 if (abfd->tdata.asxxxx_data->symbols == NULL)
371 abfd->tdata.asxxxx_data->symbols = n;
372 else
373 abfd->tdata.asxxxx_data->symtail->next = n;
374 abfd->tdata.asxxxx_data->symtail = n;
375 n->next = NULL;
377 ++abfd->symcount;
379 return true;
382 /* Add a new section found in an asxxxx .rel file. */
384 static flagword
385 asxxxx_to_asection_flags(bfd *abfd, unsigned int flags, unsigned int sect_size)
387 flagword sect_flags = SEC_NO_FLAGS;
389 if (sect_size)
390 sect_flags |= SEC_HAS_CONTENTS;
392 if (GET_REL_VERSION (abfd) == REL_VER_3)
395 * 8 7 6 5 4 3 2 1 0
396 * A_ A_ A_ A_ A3_ A3_ A3_
397 * +-----++-----+-----+-----+-----+-----+-----+-----+-----+
398 * |LOAD || BIT |XDATA|CODE | PAG | ABS | OVR | | |
399 * +-----++-----+-----+-----+-----+-----+-----+-----+-----+
402 if (!(flags & A3_ABS))
403 sect_flags |= SEC_RELOC;
405 switch (GET_CPU_TYPE (abfd))
407 case CPU_MCS51:
408 sect_flags |= SEC_LOAD;
409 if (flags & A_CODE)
410 sect_flags |= (SEC_CODE | SEC_ROM | SEC_READONLY);
411 if (flags & (A_XDATA | A_BIT) || !(flags & (A_CODE | A_XDATA | A_BIT)))
412 sect_flags |= SEC_DATA;
413 break;
415 case CPU_HC08:
416 sect_flags |= SEC_CODE;
417 sect_flags |= (flags & A_LOAD) ? SEC_LOAD : SEC_NEVER_LOAD;
418 break;
420 default:
421 sect_flags |= SEC_CODE;
422 sect_flags |= SEC_LOAD;
423 break;
426 else
429 * 7 6 5 4 3 2 1 0
430 * +-----+-----+-----+-----+-----+-----+-----+-----+
431 * | BNK | SEG | | PAG | ABS | OVR | WL1 | WL0 |
432 * +-----+-----+-----+-----+-----+-----+-----+-----+
435 if (!(flags & A4_ABS))
436 sect_flags |= SEC_RELOC;
438 sect_flags |= (flags & A4_DSEG) ? SEC_DATA : SEC_CODE;
439 sect_flags |= SEC_LOAD;
442 return sect_flags;
445 static bool
446 asxxxx_new_section (bfd *abfd, const char *sect_name, unsigned int sect_size, unsigned int sect_flags, unsigned int sect_addr)
448 asection *sect;
450 if ((sect = (asection *) bfd_zalloc (abfd, sizeof (*sect))) == NULL)
451 return false;
453 sect->name = sect_name;
454 sect->id = sect->index = NEXT_SECT_ID(abfd);
455 sect->flags = asxxxx_to_asection_flags(abfd, sect_flags, sect_size);
456 sect->size = sect->rawsize = sect_size;
457 sect->vma = sect->lma = sect_addr;
459 if (abfd->tdata.asxxxx_data->sections == NULL)
460 abfd->tdata.asxxxx_data->sections = sect;
461 else
463 sect->prev = abfd->tdata.asxxxx_data->secttail;
464 abfd->tdata.asxxxx_data->secttail->next = sect;
466 abfd->tdata.asxxxx_data->secttail = sect;
468 return true;
471 /* Read the asxxxx .rel file and turn it into sections. We create a new
472 section for each contiguous set of bytes. */
474 static bool
475 asxxxx_skip_spaces (bfd *abfd, int *p_c, unsigned int lineno, bool *errorptr)
477 if (! ISSPACE (*p_c))
479 asxxxx_bad_byte (abfd, *p_c, lineno, *errorptr);
480 return false;
483 while (ISSPACE (*p_c = asxxxx_get_byte (abfd, errorptr)))
486 return true;
489 static bool
490 asxxxx_skip_word (bfd *abfd, char *word, int *p_c, unsigned int lineno, bool *errorptr)
492 char *p;
494 for (p = word; *p != '\0'; ++p)
496 if (*p_c == *p)
498 *p_c = asxxxx_get_byte (abfd, errorptr);
500 else
502 asxxxx_bad_byte (abfd, *p_c, lineno, *errorptr);
503 return false;
507 return true;
510 static bool
511 asxxxx_get_word (bfd *abfd, char **p_word, int *p_c, unsigned int lineno, bool *errorptr)
513 bfd_size_type alc;
514 char *p, *symname;
515 char *symbuf;
517 alc = 10;
518 symbuf = (char *) bfd_malloc (alc + 1);
519 if (symbuf == NULL)
520 goto error_return;
522 p = symbuf;
524 *p++ = *p_c;
525 while (! ISSPACE (*p_c = asxxxx_get_byte (abfd, errorptr)) && *p_c != EOF)
527 if ((bfd_size_type) (p - symbuf) >= alc)
529 char *n;
531 alc *= 2;
532 n = (char *) bfd_realloc (symbuf, alc + 1);
533 if (n == NULL)
534 goto error_return;
535 p = n + (p - symbuf);
536 symbuf = n;
539 *p++ = *p_c;
542 if (*p_c == EOF)
544 asxxxx_bad_byte (abfd, *p_c, lineno, *errorptr);
545 goto error_return;
548 *p++ = '\0';
550 symname = (char *) bfd_alloc (abfd, (bfd_size_type) (p - symbuf));
551 if (symname == NULL)
552 goto error_return;
554 strcpy (symname, symbuf);
555 free (symbuf);
557 *p_word = symname;
559 return true;
561 error_return:
562 if (symbuf != NULL)
563 free (symbuf);
565 *p_word = NULL;
567 return false;
570 static bool
571 asxxxx_get_hex (bfd *abfd, unsigned int *p_val, int *p_c, unsigned int lineno, bool *errorptr)
573 *p_val = 0;
574 while (ISHEX (*p_c))
576 *p_val = (*p_val << 4) + NIBBLE (*p_c);
577 *p_c = asxxxx_get_byte (abfd, errorptr);
580 if (*p_c == EOF)
582 asxxxx_bad_byte (abfd, *p_c, lineno, *errorptr);
583 return false;
586 return true;
589 static bool
590 asxxxx_get_eol (bfd *abfd, int *p_c, unsigned int *p_lineno, bool *errorptr)
592 if (*p_c == '\n')
594 ++*p_lineno;
595 return true;
597 else if (*p_c != '\r')
599 asxxxx_bad_byte (abfd, *p_c, *p_lineno, *errorptr);
600 return false;
603 return true;
606 static bool
607 asxxxx_skip_line (bfd *abfd, int *p_c, unsigned int *p_lineno, bool *errorptr)
609 while ((*p_c = asxxxx_get_byte (abfd, errorptr)) != EOF && *p_c != '\n' && *p_c != '\r')
612 return asxxxx_get_eol (abfd, p_c, p_lineno, errorptr);
615 static void
616 asxxxx_set_cpu_type(bfd *abfd, const char *cpu_type)
618 struct cpu
620 const char *name;
621 enum asxxxx_cpu_type_e type;
623 cpus[] =
625 { "-mmcs51", CPU_MCS51 },
626 { "-mds390", CPU_DS390 },
627 { "-mds400", CPU_DS400 },
628 { "-mhc08", CPU_HC08 },
629 { "-mz80", CPU_Z80 },
630 { "-mgbz80", CPU_GBZ80 },
631 { "-mr2K", CPU_R2K },
633 size_t i;
635 for (i = 0; i < NELEM (cpus); ++i)
637 if (! strcmp (cpu_type, cpus[i].name))
639 SET_CPU_TYPE (abfd, cpus[i].type);
640 return;
644 SET_CPU_TYPE (abfd, CPU_UNKNOWN);
647 static bool
648 asxxxx_scan (bfd *abfd, unsigned int *p_lineno)
650 int c;
651 bool error = false;
653 bfd_set_error (bfd_error_file_truncated);
655 while ((c = asxxxx_get_byte (abfd, &error)) != EOF)
657 switch (c)
659 default:
660 /* unknown line */
661 asxxxx_bad_byte (abfd, c, *p_lineno, error);
662 goto error_return;
663 break;
665 case '\n':
666 ++p_lineno;
667 break;
669 case '\r':
670 break;
672 case 'A':
673 /* A CSEG size 12E2 flags 20 addr 0 */
675 char *sect_name;
676 unsigned int sect_size, sect_flags, sect_addr;
678 /* Starting a symbol definition. */
679 c = asxxxx_get_byte (abfd, &error);
681 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
682 goto error_return;
684 if (! asxxxx_get_word (abfd, &sect_name, &c, *p_lineno, &error))
685 goto error_return;
687 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
688 goto error_return;
690 if (! asxxxx_skip_word (abfd, "size", &c, *p_lineno, &error))
691 goto error_return;
693 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
694 goto error_return;
696 if (! asxxxx_get_hex (abfd, &sect_size, &c, *p_lineno, &error))
697 goto error_return;
699 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
700 goto error_return;
702 if (! asxxxx_skip_word (abfd, "flags", &c, *p_lineno, &error))
703 goto error_return;
705 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
706 goto error_return;
708 if (! asxxxx_get_hex (abfd, &sect_flags, &c, *p_lineno, &error))
709 goto error_return;
711 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
712 goto error_return;
714 if (! asxxxx_skip_word (abfd, "addr", &c, *p_lineno, &error))
715 goto error_return;
717 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
718 goto error_return;
720 if (! asxxxx_get_hex (abfd, &sect_addr, &c, *p_lineno, &error))
721 goto error_return;
723 if (! asxxxx_get_eol (abfd, &c, p_lineno, &error))
724 goto error_return;
726 if (! asxxxx_new_section (abfd, sect_name, sect_size, sect_flags, sect_addr))
727 goto error_return;
729 break;
730 case 'O':
732 * O -mds390 --model-flat24
733 * O -mds400 --model-flat24
734 * O -mhc08
735 * O -mmcs51 --model-huge
736 * O -mmcs51 --model-large
737 * O -mmcs51 --model-medium
738 * O -mmcs51 --model-small
739 * O -mmcs51 --model-small --xstack
742 char *cpu_type;
744 /* check if the next character is space */
745 c = asxxxx_get_byte (abfd, &error);
747 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
748 goto error_return;
750 if (! asxxxx_get_word (abfd, &cpu_type, &c, *p_lineno, &error))
751 goto error_return;
753 /* eat the rest of line */
754 if (! asxxxx_skip_line (abfd, &c, p_lineno, &error))
755 goto error_return;
757 asxxxx_set_cpu_type(abfd, cpu_type);
759 break;
760 case 'G': /* V 4.XX+ */
761 case 'B': /* V 4.XX+ */
762 SET_REL_VERSION (abfd, REL_VER_4);
763 /* fall through */
764 case 'H':
765 case 'M':
766 case 'T':
767 case 'R':
768 case 'P':
769 /* check if the next character is space */
770 c = asxxxx_get_byte (abfd, &error);
772 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
773 goto error_return;
775 /* eat the rest of line */
776 if (! asxxxx_skip_line (abfd, &c, p_lineno, &error))
777 goto error_return;
778 break;
780 case 'S':
781 /* S __ret3 Def0001 */
783 char *symname = NULL;
784 unsigned int symval;
785 bool is_def;
787 /* Starting a symbol definition. */
788 c = asxxxx_get_byte (abfd, &error);
790 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
791 goto error_return;
793 if (! asxxxx_get_word (abfd, &symname, &c, *p_lineno, &error))
794 goto error_return;
796 if (! asxxxx_skip_spaces (abfd, &c, *p_lineno, &error))
797 goto error_return;
799 if (c != 'D' && c != 'R')
801 asxxxx_bad_byte (abfd, c, *p_lineno, error);
802 goto error_return;
805 is_def = (c == 'D');
807 c = asxxxx_get_byte (abfd, &error);
808 if (! asxxxx_skip_word (abfd, "ef", &c, *p_lineno, &error))
809 goto error_return;
811 if (! asxxxx_get_hex(abfd, &symval, &c, *p_lineno, &error))
812 goto error_return;
814 if (! asxxxx_get_eol (abfd, &c, p_lineno, &error))
815 goto error_return;
817 if (! asxxxx_new_symbol (abfd, symname, symval, BSF_GLOBAL, CURRENT_SECT(abfd) ? CURRENT_SECT(abfd) : (is_def ? bfd_abs_section_ptr : bfd_und_section_ptr)))
818 goto error_return;
820 break;
824 if (error)
825 goto error_return;
827 return true;
829 error_return:
830 return false;
833 /* Check whether an existing file is an asxxxx .rel file. */
835 static bool
836 asxxxx_is_rel (bfd *abfd, unsigned int *p_lineno)
838 int c;
839 bool error = false;
841 __begin_check:
842 error = false;
844 /* [XDQ][HL][234] */
845 switch (c = asxxxx_get_byte (abfd, &error))
847 default:
848 /* unknown line */
849 asxxxx_bad_byte (abfd, c, *p_lineno, error);
850 return false;
852 case ';':
853 c = asxxxx_get_byte (abfd, &error);
855 if (! asxxxx_skip_word (abfd, "!FILE ", &c, *p_lineno, &error))
857 return false;
859 /* eat the rest of line */
860 if (! asxxxx_skip_line (abfd, &c, p_lineno, &error))
861 return false;
862 goto __begin_check;
864 case 'X':
865 SET_RADIX (abfd, RADIX_HEX);
866 goto get_endian;
867 case 'D':
868 SET_RADIX (abfd, RADIX_DEC);
869 goto get_endian;
870 case 'Q':
871 SET_RADIX (abfd, RADIX_OCT);
872 get_endian:
873 switch (c = asxxxx_get_byte (abfd, &error))
875 default:
876 asxxxx_bad_byte (abfd, c, *p_lineno, error);
877 return false;
879 case 'H':
880 SET_ENDIAN (abfd, ENDIAN_BIG);
881 goto get_addr_size;
882 case 'L':
883 SET_ENDIAN (abfd, ENDIAN_LITTLE);
884 get_addr_size:
885 switch (c = asxxxx_get_byte (abfd, &error))
887 default:
888 asxxxx_bad_byte (abfd, c, *p_lineno, error);
889 return false;
891 case '\n':
892 ++*p_lineno;
893 /* fall through */
894 case '\r':
895 SET_ADDRESS_SIZE (abfd, ADDR_SIZE_2);
896 break;
898 case '2':
899 SET_ADDRESS_SIZE (abfd, ADDR_SIZE_2);
900 goto get_eol;
901 case '3':
902 SET_ADDRESS_SIZE (abfd, ADDR_SIZE_3);
903 goto get_eol;
904 case '4':
905 SET_ADDRESS_SIZE (abfd, ADDR_SIZE_4);
906 get_eol:
907 c = asxxxx_get_byte (abfd, &error);
908 if (! asxxxx_get_eol (abfd, &c, p_lineno, &error))
909 return false;
910 break;
912 break;
914 break;
917 return error ? false : true;
920 static void asxxxx_cleanup(bfd *abfd)
922 bfd_release (abfd, abfd->tdata.any);
923 abfd->tdata.any = NULL;
926 bfd_cleanup
927 asxxxx_object_p (bfd *abfd);
929 bfd_cleanup
930 asxxxx_object_p (bfd *abfd)
932 void * tdata_save;
933 unsigned int lineno = 1;
935 asxxxx_init ();
937 if (! asxxxx_mkobject (abfd) || ! asxxxx_is_rel (abfd, &lineno))
939 bfd_set_error (bfd_error_wrong_format);
940 return NULL;
943 tdata_save = abfd->tdata.any;
944 if (! asxxxx_scan (abfd, &lineno))
946 if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
947 bfd_release (abfd, abfd->tdata.any);
948 abfd->tdata.any = tdata_save;
949 return NULL;
952 if (abfd->symcount > 0)
953 abfd->flags |= HAS_SYMS;
955 return asxxxx_cleanup;
958 /* Get the contents of a section. */
960 static bool
961 asxxxx_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
962 asection *section ATTRIBUTE_UNUSED,
963 void * location ATTRIBUTE_UNUSED,
964 file_ptr offset ATTRIBUTE_UNUSED,
965 bfd_size_type count ATTRIBUTE_UNUSED)
967 return false;
970 /* Set the architecture. We accept an unknown architecture here. */
972 static bool
973 asxxxx_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach)
975 if (arch != bfd_arch_unknown)
976 return bfd_default_set_arch_mach (abfd, arch, mach);
978 abfd->arch_info = & bfd_default_arch_struct;
979 return true;
982 /* Set the contents of a section. */
984 static bool
985 asxxxx_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
986 sec_ptr section ATTRIBUTE_UNUSED,
987 const void * location ATTRIBUTE_UNUSED,
988 file_ptr offset ATTRIBUTE_UNUSED,
989 bfd_size_type bytes_to_do ATTRIBUTE_UNUSED)
991 return false;
994 static int
995 asxxxx_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
996 struct bfd_link_info *info ATTRIBUTE_UNUSED)
998 return 0;
1001 /* Return the amount of memory needed to read the symbol table. */
1003 static long
1004 asxxxx_get_symtab_upper_bound (bfd *abfd)
1006 return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
1009 /* Return the symbol table. */
1011 static long
1012 asxxxx_canonicalize_symtab (bfd *abfd, asymbol **alocation)
1014 bfd_size_type symcount = bfd_get_symcount (abfd);
1015 asymbol *csymbols;
1016 unsigned int i;
1018 csymbols = abfd->tdata.asxxxx_data->csymbols;
1019 if (csymbols == NULL && symcount != 0)
1021 asymbol *c;
1022 struct asxxxx_symbol *s;
1024 csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
1025 if (csymbols == NULL)
1026 return -1;
1027 abfd->tdata.asxxxx_data->csymbols = csymbols;
1029 for (s = abfd->tdata.asxxxx_data->symbols, c = csymbols;
1030 s != NULL;
1031 s = s->next, ++c)
1033 c->the_bfd = abfd;
1034 c->name = s->name;
1035 c->value = s->val;
1036 c->flags = s->flags;
1037 c->section = s->section;
1038 c->udata.p = NULL;
1042 for (i = 0; i < symcount; i++)
1043 *alocation++ = csymbols++;
1044 *alocation = NULL;
1046 return symcount;
1049 static void
1050 asxxxx_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
1051 asymbol *symbol,
1052 symbol_info *ret)
1054 bfd_symbol_info (symbol, ret);
1057 #define asxxxx_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string
1059 static void
1060 asxxxx_print_symbol (bfd *abfd,
1061 void * afile,
1062 asymbol *symbol,
1063 bfd_print_symbol_type how)
1065 FILE *file = (FILE *) afile;
1067 switch (how)
1069 case bfd_print_symbol_name:
1070 fprintf (file, "%s", symbol->name);
1071 break;
1072 default:
1073 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
1074 fprintf (file, " %-5s %s",
1075 symbol->section->name,
1076 symbol->name);
1080 static bool asxxxx_bfd_is_target_special_symbol(bfd * a, asymbol * b)
1082 (void) a;
1083 (void) b;
1084 return false;
1087 #define asxxxx_find_line _bfd_nosymbols_find_line
1088 #define asxxxx_close_and_cleanup _bfd_generic_close_and_cleanup
1089 #define asxxxx_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1090 #define asxxxx_new_section_hook _bfd_generic_new_section_hook
1091 #define asxxxx_bfd_is_local_label_name bfd_generic_is_local_label_name
1092 #define asxxxx_get_lineno _bfd_nosymbols_get_lineno
1093 #define asxxxx_find_nearest_line _bfd_nosymbols_find_nearest_line
1094 #define asxxxx_find_inliner_info _bfd_nosymbols_find_inliner_info
1095 #define asxxxx_make_empty_symbol _bfd_generic_make_empty_symbol
1096 #define asxxxx_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1097 #define asxxxx_read_minisymbols _bfd_generic_read_minisymbols
1098 #define asxxxx_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1099 #define asxxxx_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1100 #define asxxxx_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1101 #define asxxxx_bfd_relax_section bfd_generic_relax_section
1102 #define asxxxx_bfd_gc_sections bfd_generic_gc_sections
1103 #define asxxxx_bfd_lookup_section_flags bfd_generic_lookup_section_flags
1104 #define asxxxx_bfd_merge_sections bfd_generic_merge_sections
1105 #define asxxxx_bfd_is_group_section bfd_generic_is_group_section
1106 #define asxxxx_bfd_discard_group bfd_generic_discard_group
1107 #define asxxxx_section_already_linked _bfd_generic_section_already_linked
1108 #define asxxxx_bfd_define_common_symbol bfd_generic_define_common_symbol
1109 #define asxxxx_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1110 #define asxxxx_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1111 #define asxxxx_bfd_link_add_symbols _bfd_generic_link_add_symbols
1112 #define asxxxx_bfd_link_just_syms _bfd_generic_link_just_syms
1113 #define asxxxx_bfd_copy_link_hash_symbol_type _bfd_generic_copy_link_hash_symbol_type
1114 #define asxxxx_bfd_final_link _bfd_generic_final_link
1115 #define asxxxx_bfd_link_split_section _bfd_generic_link_split_section
1116 #define asxxxx_bfd_link_check_relocs _bfd_generic_link_check_relocs
1117 #define asxxxx_bfd_define_start_stop bfd_generic_define_start_stop
1119 const bfd_target asxxxx_vec =
1121 "asxxxx", /* Name. */
1122 bfd_target_asxxxx_flavour,
1123 BFD_ENDIAN_UNKNOWN, /* Target byte order. */
1124 BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
1125 (HAS_RELOC | EXEC_P | /* Object flags. */
1126 HAS_LINENO | HAS_DEBUG |
1127 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1128 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1129 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
1130 0, /* Leading underscore. */
1131 '/', /* AR_pad_char. */
1132 15, /* AR_max_namelen. */
1133 1, /* match priority. */
1134 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
1135 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1136 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1137 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
1138 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1139 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1140 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */
1142 { /* Check the format of a file being read. Return a <<bfd_target *>> or zero. */
1144 _bfd_dummy_target,
1145 asxxxx_object_p, /* object */
1146 bfd_generic_archive_p, /* archive */
1147 _bfd_dummy_target, /* core */
1149 { /* Set the format of a file being written. */
1150 false,
1151 asxxxx_mkobject, /* object */
1152 _bfd_generic_mkarchive, /* archive */
1153 false, /* core */
1155 { /* Write cached information into a file being written, at <<bfd_close>>. */
1156 false,
1157 false, /* asxxxx_write_object_contents, object */
1158 _bfd_write_archive_contents, /* archive */
1159 false, /* core */
1162 BFD_JUMP_TABLE_GENERIC (asxxxx),
1163 BFD_JUMP_TABLE_COPY (_bfd_generic),
1164 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1165 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1166 BFD_JUMP_TABLE_SYMBOLS (asxxxx),
1167 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1168 BFD_JUMP_TABLE_WRITE (asxxxx),
1169 BFD_JUMP_TABLE_LINK (asxxxx),
1170 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1172 NULL,
1174 NULL