2010-08-04 Tristan Gingold <gingold@adacore.com>
[binutils.git] / bfd / oasys.c
blob1f51449abc8980a34b53ddd5a6533a76f200ac02
1 /* BFD back-end for oasys objects.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
4 Free Software Foundation, Inc.
5 Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #define UNDERSCORE_HACK 1
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "safe-ctype.h"
28 #include "libbfd.h"
29 #include "oasys.h"
30 #include "liboasys.h"
32 /* Read in all the section data and relocation stuff too. */
34 static bfd_boolean
35 oasys_read_record (bfd *abfd, oasys_record_union_type *record)
37 bfd_size_type amt = sizeof (record->header);
39 if (bfd_bread ((void *) record, amt, abfd) != amt)
40 return FALSE;
42 amt = record->header.length - sizeof (record->header);
43 if ((long) amt <= 0)
44 return TRUE;
45 if (bfd_bread ((void *) ((char *) record + sizeof (record->header)), amt, abfd)
46 != amt)
47 return FALSE;
48 return TRUE;
51 static size_t
52 oasys_string_length (oasys_record_union_type *record)
54 return record->header.length
55 - ((char *) record->symbol.name - (char *) record);
58 /* Slurp the symbol table by reading in all the records at the start file
59 till we get to the first section record.
61 We'll sort the symbolss into two lists, defined and undefined. The
62 undefined symbols will be placed into the table according to their
63 refno.
65 We do this by placing all undefined symbols at the front of the table
66 moving in, and the defined symbols at the end of the table moving back. */
68 static bfd_boolean
69 oasys_slurp_symbol_table (bfd *const abfd)
71 oasys_record_union_type record;
72 oasys_data_type *data = OASYS_DATA (abfd);
73 bfd_boolean loop = TRUE;
74 asymbol *dest_defined;
75 asymbol *dest;
76 char *string_ptr;
77 bfd_size_type amt;
79 if (data->symbols != NULL)
80 return TRUE;
82 /* Buy enough memory for all the symbols and all the names. */
83 amt = abfd->symcount;
84 amt *= sizeof (asymbol);
85 data->symbols = bfd_alloc (abfd, amt);
87 amt = data->symbol_string_length;
88 #ifdef UNDERSCORE_HACK
89 /* Buy 1 more char for each symbol to keep the underscore in. */
90 amt += abfd->symcount;
91 #endif
92 data->strings = bfd_alloc (abfd, amt);
94 if (!data->symbols || !data->strings)
95 return FALSE;
97 dest_defined = data->symbols + abfd->symcount - 1;
99 string_ptr = data->strings;
100 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
101 return FALSE;
102 while (loop)
104 if (! oasys_read_record (abfd, &record))
105 return FALSE;
107 switch (record.header.type)
109 case oasys_record_is_header_enum:
110 break;
111 case oasys_record_is_local_enum:
112 case oasys_record_is_symbol_enum:
114 int flag = record.header.type == (int) oasys_record_is_local_enum ?
115 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
117 size_t length = oasys_string_length (&record);
118 switch (record.symbol.relb & RELOCATION_TYPE_BITS)
120 case RELOCATION_TYPE_ABS:
121 dest = dest_defined--;
122 dest->section = bfd_abs_section_ptr;
123 dest->flags = 0;
125 break;
126 case RELOCATION_TYPE_REL:
127 dest = dest_defined--;
128 dest->section =
129 OASYS_DATA (abfd)->sections[record.symbol.relb &
130 RELOCATION_SECT_BITS];
131 if (record.header.type == (int) oasys_record_is_local_enum)
133 dest->flags = BSF_LOCAL;
134 if (dest->section == (asection *) (~0))
136 /* It seems that sometimes internal symbols are tied up, but
137 still get output, even though there is no
138 section */
139 dest->section = 0;
142 else
143 dest->flags = flag;
144 break;
145 case RELOCATION_TYPE_UND:
146 dest = data->symbols + H_GET_16 (abfd, record.symbol.refno);
147 dest->section = bfd_und_section_ptr;
148 break;
149 case RELOCATION_TYPE_COM:
150 dest = dest_defined--;
151 dest->name = string_ptr;
152 dest->the_bfd = abfd;
153 dest->section = bfd_com_section_ptr;
154 break;
155 default:
156 dest = dest_defined--;
157 BFD_ASSERT (FALSE);
158 break;
160 dest->name = string_ptr;
161 dest->the_bfd = abfd;
162 dest->udata.p = NULL;
163 dest->value = H_GET_32 (abfd, record.symbol.value);
165 #ifdef UNDERSCORE_HACK
166 if (record.symbol.name[0] != '_')
168 string_ptr[0] = '_';
169 string_ptr++;
171 #endif
172 memcpy (string_ptr, record.symbol.name, length);
174 string_ptr[length] = 0;
175 string_ptr += length + 1;
177 break;
178 default:
179 loop = FALSE;
182 return TRUE;
185 static long
186 oasys_get_symtab_upper_bound (bfd *const abfd)
188 if (! oasys_slurp_symbol_table (abfd))
189 return -1;
191 return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
194 extern const bfd_target oasys_vec;
196 static long
197 oasys_canonicalize_symtab (bfd *abfd, asymbol **location)
199 asymbol *symbase;
200 unsigned int counter;
202 if (! oasys_slurp_symbol_table (abfd))
203 return -1;
205 symbase = OASYS_DATA (abfd)->symbols;
206 for (counter = 0; counter < abfd->symcount; counter++)
207 *(location++) = symbase++;
209 *location = 0;
210 return abfd->symcount;
213 /* Archive stuff. */
215 static const bfd_target *
216 oasys_archive_p (bfd *abfd)
218 oasys_archive_header_type header;
219 oasys_extarchive_header_type header_ext;
220 unsigned int i;
221 file_ptr filepos;
222 bfd_size_type amt;
224 amt = sizeof (header_ext);
225 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
226 || bfd_bread ((void *) &header_ext, amt, abfd) != amt)
228 if (bfd_get_error () != bfd_error_system_call)
229 bfd_set_error (bfd_error_wrong_format);
230 return NULL;
233 header.version = H_GET_32 (abfd, header_ext.version);
234 header.mod_count = H_GET_32 (abfd, header_ext.mod_count);
235 header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset);
236 header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size);
237 header.sym_count = H_GET_32 (abfd, header_ext.sym_count);
238 header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset);
239 header.xref_count = H_GET_32 (abfd, header_ext.xref_count);
240 header.xref_lst_offset = H_GET_32 (abfd, header_ext.xref_lst_offset);
242 /* There isn't a magic number in an Oasys archive, so the best we
243 can do to verify reasonableness is to make sure that the values in
244 the header are too weird. */
246 if (header.version > 10000
247 || header.mod_count > 10000
248 || header.sym_count > 100000
249 || header.xref_count > 100000)
250 return NULL;
252 /* That all worked, let's buy the space for the header and read in
253 the headers. */
255 oasys_ar_data_type *ar;
256 oasys_module_info_type *module;
257 oasys_module_table_type record;
259 amt = sizeof (oasys_ar_data_type);
260 ar = bfd_alloc (abfd, amt);
262 amt = header.mod_count;
263 amt *= sizeof (oasys_module_info_type);
264 module = bfd_alloc (abfd, amt);
266 if (!ar || !module)
267 return NULL;
269 abfd->tdata.oasys_ar_data = ar;
270 ar->module = module;
271 ar->module_count = header.mod_count;
273 filepos = header.mod_tbl_offset;
274 for (i = 0; i < header.mod_count; i++)
276 if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
277 return NULL;
279 /* There are two ways of specifying the archive header. */
281 oasys_extmodule_table_type_b_type record_ext;
283 amt = sizeof (record_ext);
284 if (bfd_bread ((void *) &record_ext, amt, abfd) != amt)
285 return NULL;
287 record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
288 record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
290 record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
291 record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
292 record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
293 record.module_name_size = H_GET_32 (abfd,
294 record_ext.mod_name_length);
296 amt = record.module_name_size;
297 module[i].name = bfd_alloc (abfd, amt + 1);
298 if (!module[i].name)
299 return NULL;
300 if (bfd_bread ((void *) module[i].name, amt, abfd) != amt)
301 return NULL;
302 module[i].name[record.module_name_size] = 0;
303 filepos += (sizeof (record_ext)
304 + record.dep_count * 4
305 + record.module_name_size + 1);
308 module[i].size = record.mod_size;
309 module[i].pos = record.file_offset;
310 module[i].abfd = 0;
313 return abfd->xvec;
316 static bfd_boolean
317 oasys_mkobject (bfd *abfd)
319 bfd_size_type amt = sizeof (oasys_data_type);
321 abfd->tdata.oasys_obj_data = bfd_alloc (abfd, amt);
323 return abfd->tdata.oasys_obj_data != NULL;
326 /* The howto table is build using the top two bits of a reloc byte to
327 index into it. The bits are PCREL,WORD/LONG. */
329 static reloc_howto_type howto_table[] =
332 HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
333 HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE),
334 HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
335 HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE)
338 /* Read in all the section data and relocation stuff too. */
340 static bfd_boolean
341 oasys_slurp_section_data (bfd *const abfd)
343 oasys_record_union_type record;
344 oasys_data_type *data = OASYS_DATA (abfd);
345 bfd_boolean loop = TRUE;
346 oasys_per_section_type *per;
347 asection *s;
348 bfd_size_type amt;
350 /* See if the data has been slurped already. */
351 for (s = abfd->sections; s != NULL; s = s->next)
353 per = oasys_per_section (s);
354 if (per->initialized)
355 return TRUE;
358 if (data->first_data_record == 0)
359 return TRUE;
361 if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
362 return FALSE;
364 while (loop)
366 if (! oasys_read_record (abfd, &record))
367 return FALSE;
369 switch (record.header.type)
371 case oasys_record_is_header_enum:
372 break;
373 case oasys_record_is_data_enum:
375 bfd_byte *src = record.data.data;
376 bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
377 bfd_byte *dst_ptr;
378 bfd_byte *dst_base_ptr;
379 unsigned int relbit;
380 unsigned int count;
381 asection *section =
382 data->sections[record.data.relb & RELOCATION_SECT_BITS];
383 bfd_vma dst_offset;
385 per = oasys_per_section (section);
387 if (! per->initialized)
389 arelent **relpp;
391 per->data = bfd_zalloc (abfd, section->size);
392 if (!per->data)
393 return FALSE;
394 relpp = &section->relocation;
395 per->reloc_tail_ptr = (oasys_reloc_type **) relpp;
396 per->had_vma = FALSE;
397 per->initialized = TRUE;
398 section->reloc_count = 0;
399 section->flags = SEC_ALLOC;
402 dst_offset = H_GET_32 (abfd, record.data.addr);
403 if (! per->had_vma)
405 /* Take the first vma we see as the base. */
406 section->vma = dst_offset;
407 per->had_vma = TRUE;
410 dst_offset -= section->vma;
412 dst_base_ptr = oasys_per_section (section)->data;
413 dst_ptr = oasys_per_section (section)->data +
414 dst_offset;
416 if (src < end_src)
417 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
419 while (src < end_src)
421 unsigned char mod_byte = *src++;
422 size_t gap = end_src - src;
424 count = 8;
425 if (mod_byte == 0 && gap >= 8)
427 dst_ptr[0] = src[0];
428 dst_ptr[1] = src[1];
429 dst_ptr[2] = src[2];
430 dst_ptr[3] = src[3];
431 dst_ptr[4] = src[4];
432 dst_ptr[5] = src[5];
433 dst_ptr[6] = src[6];
434 dst_ptr[7] = src[7];
435 dst_ptr += 8;
436 src += 8;
438 else
440 for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
442 if (relbit & mod_byte)
444 unsigned char reloc = *src;
445 /* This item needs to be relocated. */
446 switch (reloc & RELOCATION_TYPE_BITS)
448 case RELOCATION_TYPE_ABS:
449 break;
451 case RELOCATION_TYPE_REL:
453 /* Relocate the item relative to the section. */
454 oasys_reloc_type *r;
456 amt = sizeof (oasys_reloc_type);
457 r = bfd_alloc (abfd, amt);
458 if (!r)
459 return FALSE;
460 *(per->reloc_tail_ptr) = r;
461 per->reloc_tail_ptr = &r->next;
462 r->next = NULL;
463 /* Reference to undefined symbol. */
464 src++;
465 /* There is no symbol. */
466 r->symbol = 0;
467 /* Work out the howto. */
468 abort ();
469 r->relent.address = dst_ptr - dst_base_ptr;
470 r->relent.howto = &howto_table[reloc >> 6];
471 r->relent.sym_ptr_ptr = NULL;
472 section->reloc_count++;
474 /* Fake up the data to look like
475 it's got the -ve pc in it, this
476 makes it much easier to convert
477 into other formats. This is done
478 by hitting the addend. */
479 if (r->relent.howto->pc_relative)
480 r->relent.addend -= dst_ptr - dst_base_ptr;
482 break;
484 case RELOCATION_TYPE_UND:
486 oasys_reloc_type *r;
488 amt = sizeof (oasys_reloc_type);
489 r = bfd_alloc (abfd, amt);
490 if (!r)
491 return FALSE;
492 *(per->reloc_tail_ptr) = r;
493 per->reloc_tail_ptr = &r->next;
494 r->next = NULL;
495 /* Reference to undefined symbol. */
496 src++;
497 /* Get symbol number. */
498 r->symbol = (src[0] << 8) | src[1];
499 /* Work out the howto. */
500 abort ();
502 r->relent.addend = 0;
503 r->relent.address = dst_ptr - dst_base_ptr;
504 r->relent.howto = &howto_table[reloc >> 6];
505 r->relent.sym_ptr_ptr = NULL;
506 section->reloc_count++;
508 src += 2;
509 /* Fake up the data to look like
510 it's got the -ve pc in it, this
511 makes it much easier to convert
512 into other formats. This is done
513 by hitting the addend. */
514 if (r->relent.howto->pc_relative)
515 r->relent.addend -= dst_ptr - dst_base_ptr;
517 break;
518 case RELOCATION_TYPE_COM:
519 BFD_FAIL ();
522 *dst_ptr++ = *src++;
527 break;
528 case oasys_record_is_local_enum:
529 case oasys_record_is_symbol_enum:
530 case oasys_record_is_section_enum:
531 break;
532 default:
533 loop = FALSE;
537 return TRUE;
541 #define MAX_SECS 16
543 static const bfd_target *
544 oasys_object_p (bfd *abfd)
546 oasys_data_type *oasys;
547 oasys_data_type *save = OASYS_DATA (abfd);
548 bfd_boolean loop = TRUE;
549 bfd_boolean had_usefull = FALSE;
551 abfd->tdata.oasys_obj_data = 0;
552 oasys_mkobject (abfd);
553 oasys = OASYS_DATA (abfd);
554 memset ((void *) oasys->sections, 0xff, sizeof (oasys->sections));
556 /* Point to the start of the file. */
557 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
558 goto fail;
559 oasys->symbol_string_length = 0;
561 /* Inspect the records, but only keep the section info -
562 remember the size of the symbols. */
563 oasys->first_data_record = 0;
564 while (loop)
566 oasys_record_union_type record;
567 if (! oasys_read_record (abfd, &record))
568 goto fail;
569 if ((size_t) record.header.length < (size_t) sizeof (record.header))
570 goto fail;
572 switch ((oasys_record_enum_type) (record.header.type))
574 case oasys_record_is_header_enum:
575 had_usefull = TRUE;
576 break;
577 case oasys_record_is_symbol_enum:
578 case oasys_record_is_local_enum:
579 /* Count symbols and remember their size for a future malloc. */
580 abfd->symcount++;
581 oasys->symbol_string_length += 1 + oasys_string_length (&record);
582 had_usefull = TRUE;
583 break;
584 case oasys_record_is_section_enum:
586 asection *s;
587 char *buffer;
588 unsigned int section_number;
590 if (record.section.header.length != sizeof (record.section))
591 goto fail;
593 buffer = bfd_alloc (abfd, (bfd_size_type) 3);
594 if (!buffer)
595 goto fail;
596 section_number = record.section.relb & RELOCATION_SECT_BITS;
597 sprintf (buffer, "%u", section_number);
598 s = bfd_make_section (abfd, buffer);
599 oasys->sections[section_number] = s;
600 switch (record.section.relb & RELOCATION_TYPE_BITS)
602 case RELOCATION_TYPE_ABS:
603 case RELOCATION_TYPE_REL:
604 break;
605 case RELOCATION_TYPE_UND:
606 case RELOCATION_TYPE_COM:
607 BFD_FAIL ();
610 s->size = H_GET_32 (abfd, record.section.value);
611 s->vma = H_GET_32 (abfd, record.section.vma);
612 s->flags = 0;
613 had_usefull = TRUE;
615 break;
616 case oasys_record_is_data_enum:
617 oasys->first_data_record = bfd_tell (abfd) - record.header.length;
618 case oasys_record_is_debug_enum:
619 case oasys_record_is_module_enum:
620 case oasys_record_is_named_section_enum:
621 case oasys_record_is_end_enum:
622 if (! had_usefull)
623 goto fail;
624 loop = FALSE;
625 break;
626 default:
627 goto fail;
630 oasys->symbols = NULL;
632 /* Oasys support several architectures, but I can't see a simple way
633 to discover which one is in a particular file - we'll guess. */
634 bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
635 if (abfd->symcount != 0)
636 abfd->flags |= HAS_SYMS;
638 /* We don't know if a section has data until we've read it. */
639 oasys_slurp_section_data (abfd);
641 return abfd->xvec;
643 fail:
644 (void) bfd_release (abfd, oasys);
645 abfd->tdata.oasys_obj_data = save;
646 return NULL;
650 static void
651 oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
652 asymbol *symbol,
653 symbol_info *ret)
655 bfd_symbol_info (symbol, ret);
657 if (!symbol->section)
658 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
661 static void
662 oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how)
664 FILE *file = (FILE *) afile;
666 switch (how)
668 case bfd_print_symbol_name:
669 case bfd_print_symbol_more:
670 fprintf (file, "%s", symbol->name);
671 break;
672 case bfd_print_symbol_all:
674 const char *section_name = symbol->section == NULL ?
675 (const char *) "*abs" : symbol->section->name;
677 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
679 fprintf (file, " %-5s %s",
680 section_name,
681 symbol->name);
683 break;
687 static bfd_boolean
688 oasys_new_section_hook (bfd *abfd, asection *newsect)
690 if (!newsect->used_by_bfd)
692 newsect->used_by_bfd
693 = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
694 if (!newsect->used_by_bfd)
695 return FALSE;
697 oasys_per_section (newsect)->data = NULL;
698 oasys_per_section (newsect)->section = newsect;
699 oasys_per_section (newsect)->offset = 0;
700 oasys_per_section (newsect)->initialized = FALSE;
701 newsect->alignment_power = 1;
703 /* Turn the section string into an index. */
704 sscanf (newsect->name, "%u", &newsect->target_index);
706 return _bfd_generic_new_section_hook (abfd, newsect);
710 static long
711 oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
713 if (! oasys_slurp_section_data (abfd))
714 return -1;
715 return (asect->reloc_count + 1) * sizeof (arelent *);
718 static bfd_boolean
719 oasys_get_section_contents (bfd *abfd,
720 sec_ptr section,
721 void * location,
722 file_ptr offset,
723 bfd_size_type count)
725 oasys_per_section_type *p = oasys_per_section (section);
727 oasys_slurp_section_data (abfd);
729 if (! p->initialized)
730 (void) memset (location, 0, (size_t) count);
731 else
732 (void) memcpy (location, (void *) (p->data + offset), (size_t) count);
734 return TRUE;
737 static long
738 oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
739 sec_ptr section,
740 arelent **relptr,
741 asymbol **symbols ATTRIBUTE_UNUSED)
743 unsigned int reloc_count = 0;
744 oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
746 if (src != NULL)
747 abort ();
749 *relptr = NULL;
750 return section->reloc_count = reloc_count;
754 /* Writing. */
756 /* Calculate the checksum and write one record. */
758 static bfd_boolean
759 oasys_write_record (bfd *abfd,
760 oasys_record_enum_type type,
761 oasys_record_union_type *record,
762 size_t size)
764 int checksum;
765 size_t i;
766 unsigned char *ptr;
768 record->header.length = size;
769 record->header.type = (int) type;
770 record->header.check_sum = 0;
771 record->header.fill = 0;
772 ptr = (unsigned char *) &record->pad[0];
773 checksum = 0;
774 for (i = 0; i < size; i++)
775 checksum += *ptr++;
776 record->header.check_sum = 0xff & (-checksum);
777 if (bfd_bwrite ((void *) record, (bfd_size_type) size, abfd) != size)
778 return FALSE;
779 return TRUE;
783 /* Write out all the symbols. */
785 static bfd_boolean
786 oasys_write_syms (bfd *abfd)
788 unsigned int count;
789 asymbol **generic = bfd_get_outsymbols (abfd);
790 unsigned int sym_index = 0;
792 for (count = 0; count < bfd_get_symcount (abfd); count++)
794 oasys_symbol_record_type symbol;
795 asymbol *const g = generic[count];
796 const char *src = g->name;
797 char *dst = symbol.name;
798 unsigned int l = 0;
800 if (bfd_is_com_section (g->section))
802 symbol.relb = RELOCATION_TYPE_COM;
803 H_PUT_16 (abfd, sym_index, symbol.refno);
804 sym_index++;
806 else if (bfd_is_abs_section (g->section))
808 symbol.relb = RELOCATION_TYPE_ABS;
809 H_PUT_16 (abfd, 0, symbol.refno);
811 else if (bfd_is_und_section (g->section))
813 symbol.relb = RELOCATION_TYPE_UND;
814 H_PUT_16 (abfd, sym_index, symbol.refno);
815 /* Overload the value field with the output sym_index number */
816 sym_index++;
818 else if (g->flags & BSF_DEBUGGING)
819 /* Throw it away. */
820 continue;
821 else
823 if (g->section == NULL)
824 /* Sometime, the oasys tools give out a symbol with illegal
825 bits in it, we'll output it in the same broken way. */
826 symbol.relb = RELOCATION_TYPE_REL | 0;
827 else
828 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
830 H_PUT_16 (abfd, 0, symbol.refno);
833 #ifdef UNDERSCORE_HACK
834 if (src[l] == '_')
835 dst[l++] = '.';
836 #endif
837 while (src[l])
839 dst[l] = src[l];
840 l++;
843 H_PUT_32 (abfd, g->value, symbol.value);
845 if (g->flags & BSF_LOCAL)
847 if (! oasys_write_record (abfd,
848 oasys_record_is_local_enum,
849 (oasys_record_union_type *) & symbol,
850 offsetof (oasys_symbol_record_type,
851 name[0]) + l))
852 return FALSE;
854 else
856 if (! oasys_write_record (abfd,
857 oasys_record_is_symbol_enum,
858 (oasys_record_union_type *) & symbol,
859 offsetof (oasys_symbol_record_type,
860 name[0]) + l))
861 return FALSE;
863 g->value = sym_index - 1;
866 return TRUE;
869 /* Write a section header for each section. */
871 static bfd_boolean
872 oasys_write_sections (bfd *abfd)
874 asection *s;
875 static oasys_section_record_type out;
877 for (s = abfd->sections; s != NULL; s = s->next)
879 if (!ISDIGIT (s->name[0]))
881 (*_bfd_error_handler)
882 (_("%s: can not represent section `%s' in oasys"),
883 bfd_get_filename (abfd), s->name);
884 bfd_set_error (bfd_error_nonrepresentable_section);
885 return FALSE;
887 out.relb = RELOCATION_TYPE_REL | s->target_index;
888 H_PUT_32 (abfd, s->size, out.value);
889 H_PUT_32 (abfd, s->vma, out.vma);
891 if (! oasys_write_record (abfd,
892 oasys_record_is_section_enum,
893 (oasys_record_union_type *) & out,
894 sizeof (out)))
895 return FALSE;
897 return TRUE;
900 static bfd_boolean
901 oasys_write_header (bfd *abfd)
903 /* Create and write the header. */
904 oasys_header_record_type r;
905 size_t length = strlen (abfd->filename);
907 if (length > (size_t) sizeof (r.module_name))
908 length = sizeof (r.module_name);
910 (void) memcpy (r.module_name, abfd->filename, length);
911 (void) memset (r.module_name + length, ' ', sizeof (r.module_name) - length);
913 r.version_number = OASYS_VERSION_NUMBER;
914 r.rev_number = OASYS_REV_NUMBER;
916 return oasys_write_record (abfd, oasys_record_is_header_enum,
917 (oasys_record_union_type *) & r,
918 offsetof (oasys_header_record_type,
919 description[0]));
922 static bfd_boolean
923 oasys_write_end (bfd *abfd)
925 oasys_end_record_type end;
926 unsigned char null = 0;
928 end.relb = RELOCATION_TYPE_ABS;
929 H_PUT_32 (abfd, abfd->start_address, end.entry);
930 H_PUT_16 (abfd, 0, end.fill);
931 end.zero = 0;
932 if (! oasys_write_record (abfd,
933 oasys_record_is_end_enum,
934 (oasys_record_union_type *) & end,
935 sizeof (end)))
936 return FALSE;
938 return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1;
941 static int
942 comp (const void * ap, const void * bp)
944 arelent *a = *((arelent **) ap);
945 arelent *b = *((arelent **) bp);
947 return a->address - b->address;
950 static bfd_boolean
951 oasys_write_data (bfd *abfd)
953 asection *s;
955 for (s = abfd->sections; s != NULL; s = s->next)
957 if (s->flags & SEC_LOAD)
959 bfd_byte *raw_data = oasys_per_section (s)->data;
960 oasys_data_record_type processed_data;
961 bfd_size_type current_byte_index = 0;
962 unsigned int relocs_to_go = s->reloc_count;
963 arelent **p = s->orelocation;
965 if (s->reloc_count != 0)
966 /* Sort the reloc records so it's easy to insert the relocs into the
967 data. */
968 qsort (s->orelocation, s->reloc_count, sizeof (arelent **), comp);
970 current_byte_index = 0;
971 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
973 while (current_byte_index < s->size)
975 /* Scan forwards by eight bytes or however much is left and see if
976 there are any relocations going on. */
977 bfd_byte *mod = &processed_data.data[0];
978 bfd_byte *dst = &processed_data.data[1];
980 unsigned int i = 0;
981 *mod = 0;
983 H_PUT_32 (abfd, s->vma + current_byte_index,
984 processed_data.addr);
986 /* Don't start a relocation unless you're sure you can finish it
987 within the same data record. The worst case relocation is a
988 4-byte relocatable value which is split across two modification
989 bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
990 1 modification byte + 2 data = 8 bytes total). That's where
991 the magic number 8 comes from. */
992 while (current_byte_index < s->size && dst <=
993 & processed_data.data[sizeof (processed_data.data) - 8])
995 if (relocs_to_go != 0)
997 arelent *r = *p;
999 /* There is a relocation, is it for this byte ? */
1000 if (r->address == current_byte_index)
1001 abort ();
1004 /* If this is coming from an unloadable section then copy
1005 zeros. */
1006 if (raw_data == NULL)
1007 *dst++ = 0;
1008 else
1009 *dst++ = *raw_data++;
1011 if (++i >= 8)
1013 i = 0;
1014 mod = dst++;
1015 *mod = 0;
1017 current_byte_index++;
1020 /* Don't write a useless null modification byte. */
1021 if (dst == mod + 1)
1022 --dst;
1024 if (! (oasys_write_record
1025 (abfd, oasys_record_is_data_enum,
1026 ((oasys_record_union_type *) &processed_data),
1027 (size_t) (dst - (bfd_byte *) &processed_data))))
1028 return FALSE;
1033 return TRUE;
1036 static bfd_boolean
1037 oasys_write_object_contents (bfd *abfd)
1039 if (! oasys_write_header (abfd))
1040 return FALSE;
1041 if (! oasys_write_syms (abfd))
1042 return FALSE;
1043 if (! oasys_write_sections (abfd))
1044 return FALSE;
1045 if (! oasys_write_data (abfd))
1046 return FALSE;
1047 if (! oasys_write_end (abfd))
1048 return FALSE;
1049 return TRUE;
1052 /* Set section contents is complicated with OASYS since the format is
1053 not a byte image, but a record stream. */
1055 static bfd_boolean
1056 oasys_set_section_contents (bfd *abfd,
1057 sec_ptr section,
1058 const void * location,
1059 file_ptr offset,
1060 bfd_size_type count)
1062 if (count != 0)
1064 if (oasys_per_section (section)->data == NULL)
1066 oasys_per_section (section)->data = bfd_alloc (abfd, section->size);
1067 if (!oasys_per_section (section)->data)
1068 return FALSE;
1070 (void) memcpy ((void *) (oasys_per_section (section)->data + offset),
1071 location, (size_t) count);
1073 return TRUE;
1078 /* Native-level interface to symbols. */
1080 /* We read the symbols into a buffer, which is discarded when this
1081 function exits. We read the strings into a buffer large enough to
1082 hold them all plus all the cached symbol entries. */
1084 static asymbol *
1085 oasys_make_empty_symbol (bfd *abfd)
1087 bfd_size_type amt = sizeof (oasys_symbol_type);
1088 oasys_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
1090 if (!new_symbol_type)
1091 return NULL;
1092 new_symbol_type->symbol.the_bfd = abfd;
1093 return &new_symbol_type->symbol;
1096 /* User should have checked the file flags; perhaps we should return
1097 BFD_NO_MORE_SYMBOLS if there are none? */
1099 static bfd *
1100 oasys_openr_next_archived_file (bfd *arch, bfd *prev)
1102 oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
1103 oasys_module_info_type *p;
1105 /* Take the next one from the arch state, or reset. */
1106 if (prev == NULL)
1107 /* Reset the index - the first two entries are bogus. */
1108 ar->module_index = 0;
1110 p = ar->module + ar->module_index;
1111 ar->module_index++;
1113 if (ar->module_index <= ar->module_count)
1115 if (p->abfd == NULL)
1117 p->abfd = _bfd_create_empty_archive_element_shell (arch);
1118 p->abfd->origin = p->pos;
1119 p->abfd->filename = p->name;
1121 /* Fixup a pointer to this element for the member. */
1122 p->abfd->arelt_data = (void *) p;
1124 return p->abfd;
1127 bfd_set_error (bfd_error_no_more_archived_files);
1128 return NULL;
1131 static bfd_boolean
1132 oasys_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED,
1133 asection *section ATTRIBUTE_UNUSED,
1134 asymbol **symbols ATTRIBUTE_UNUSED,
1135 bfd_vma offset ATTRIBUTE_UNUSED,
1136 const char **filename_ptr ATTRIBUTE_UNUSED,
1137 const char **functionname_ptr ATTRIBUTE_UNUSED,
1138 unsigned int *line_ptr ATTRIBUTE_UNUSED)
1140 return FALSE;
1143 static bfd_boolean
1144 oasys_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
1145 const char **filename_ptr ATTRIBUTE_UNUSED,
1146 const char **functionname_ptr ATTRIBUTE_UNUSED,
1147 unsigned int *line_ptr ATTRIBUTE_UNUSED)
1149 return FALSE;
1152 static int
1153 oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
1155 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1157 if (mod == NULL)
1159 bfd_set_error (bfd_error_invalid_operation);
1160 return -1;
1163 buf->st_size = mod->size;
1164 buf->st_mode = 0666;
1165 return 0;
1168 static int
1169 oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
1170 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1172 return 0;
1175 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
1176 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1177 #define oasys_slurp_armap bfd_true
1178 #define oasys_slurp_extended_name_table bfd_true
1179 #define oasys_construct_extended_name_table ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true)
1180 #define oasys_truncate_arname bfd_dont_truncate_arname
1181 #define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true)
1182 #define oasys_read_ar_hdr bfd_nullvoidptr
1183 #define oasys_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
1184 #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
1185 #define oasys_update_armap_timestamp bfd_true
1186 #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
1187 #define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1188 #define oasys_get_lineno _bfd_nosymbols_get_lineno
1189 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1190 #define oasys_read_minisymbols _bfd_generic_read_minisymbols
1191 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1192 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1193 #define oasys_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
1194 #define oasys_set_arch_mach bfd_default_set_arch_mach
1195 #define oasys_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1196 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1197 #define oasys_bfd_relax_section bfd_generic_relax_section
1198 #define oasys_bfd_gc_sections bfd_generic_gc_sections
1199 #define oasys_bfd_merge_sections bfd_generic_merge_sections
1200 #define oasys_bfd_is_group_section bfd_generic_is_group_section
1201 #define oasys_bfd_discard_group bfd_generic_discard_group
1202 #define oasys_section_already_linked _bfd_generic_section_already_linked
1203 #define oasys_bfd_define_common_symbol bfd_generic_define_common_symbol
1204 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1205 #define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1206 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1207 #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
1208 #define oasys_bfd_copy_link_hash_symbol_type \
1209 _bfd_generic_copy_link_hash_symbol_type
1210 #define oasys_bfd_final_link _bfd_generic_final_link
1211 #define oasys_bfd_link_split_section _bfd_generic_link_split_section
1213 const bfd_target oasys_vec =
1215 "oasys", /* Name. */
1216 bfd_target_oasys_flavour,
1217 BFD_ENDIAN_BIG, /* Target byte order. */
1218 BFD_ENDIAN_BIG, /* Target headers byte order. */
1219 (HAS_RELOC | EXEC_P | /* Object flags. */
1220 HAS_LINENO | HAS_DEBUG |
1221 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1222 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1223 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
1224 0, /* Leading underscore. */
1225 ' ', /* AR_pad_char. */
1226 16, /* AR_max_namelen. */
1227 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1228 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1229 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
1230 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1231 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1232 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
1234 {_bfd_dummy_target,
1235 oasys_object_p, /* bfd_check_format. */
1236 oasys_archive_p,
1237 _bfd_dummy_target,
1239 { /* bfd_set_format. */
1240 bfd_false,
1241 oasys_mkobject,
1242 _bfd_generic_mkarchive,
1243 bfd_false
1245 { /* bfd_write_contents. */
1246 bfd_false,
1247 oasys_write_object_contents,
1248 _bfd_write_archive_contents,
1249 bfd_false,
1252 BFD_JUMP_TABLE_GENERIC (oasys),
1253 BFD_JUMP_TABLE_COPY (_bfd_generic),
1254 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1255 BFD_JUMP_TABLE_ARCHIVE (oasys),
1256 BFD_JUMP_TABLE_SYMBOLS (oasys),
1257 BFD_JUMP_TABLE_RELOCS (oasys),
1258 BFD_JUMP_TABLE_WRITE (oasys),
1259 BFD_JUMP_TABLE_LINK (oasys),
1260 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1262 NULL,
1264 NULL