* MAINTAINERS: Add myself as M88k maintainer.
[binutils.git] / bfd / oasys.c
blob0ae82887d7230b86c199e0785bbbaa98438de695
1 /* BFD back-end for oasys objects.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
3 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #define UNDERSCORE_HACK 1
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "safe-ctype.h"
26 #include "libbfd.h"
27 #include "oasys.h"
28 #include "liboasys.h"
30 static bfd_boolean oasys_slurp_section_data
31 PARAMS ((bfd * const));
32 static bfd_boolean oasys_read_record
33 PARAMS ((bfd *, oasys_record_union_type *));
34 static bfd_boolean oasys_write_sections
35 PARAMS ((bfd *));
36 static bfd_boolean oasys_write_record
37 PARAMS ((bfd *, oasys_record_enum_type, oasys_record_union_type *, size_t));
38 static bfd_boolean oasys_write_syms
39 PARAMS ((bfd *));
40 static bfd_boolean oasys_write_header
41 PARAMS ((bfd *));
42 static bfd_boolean oasys_write_end
43 PARAMS ((bfd *));
44 static bfd_boolean oasys_write_data
45 PARAMS ((bfd *));
46 static size_t oasys_string_length
47 PARAMS ((oasys_record_union_type *));
48 static bfd_boolean oasys_slurp_symbol_table
49 PARAMS ((bfd *const));
50 static long int oasys_get_symtab_upper_bound
51 PARAMS ((bfd *const));
52 static const bfd_target *oasys_archive_p
53 PARAMS ((bfd *));
54 static bfd_boolean oasys_mkobject
55 PARAMS ((bfd *));
56 static const bfd_target *oasys_object_p
57 PARAMS ((bfd *));
58 static void oasys_get_symbol_info
59 PARAMS ((bfd *, asymbol *, symbol_info *));
60 static void oasys_print_symbol
61 PARAMS ((bfd *, void *, asymbol *, bfd_print_symbol_type));
62 static bfd_boolean oasys_new_section_hook
63 PARAMS ((bfd *, asection *));
64 static long int oasys_get_reloc_upper_bound
65 PARAMS ((bfd *, sec_ptr));
66 static bfd_boolean oasys_get_section_contents
67 PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type));
68 static int comp
69 PARAMS ((const void *, const void *));
70 static bfd_boolean oasys_write_object_contents
71 PARAMS ((bfd *));
72 static bfd_boolean oasys_set_section_contents
73 PARAMS ((bfd *, sec_ptr, const void *, file_ptr, bfd_size_type));
74 static asymbol *oasys_make_empty_symbol
75 PARAMS ((bfd *));
76 static bfd *oasys_openr_next_archived_file
77 PARAMS ((bfd *, bfd *));
78 static bfd_boolean oasys_find_nearest_line
79 PARAMS ((bfd *, asection *, asymbol **, bfd_vma,
80 const char **, const char **, unsigned int *));
81 static int oasys_generic_stat_arch_elt
82 PARAMS ((bfd *, struct stat *));
83 static int oasys_sizeof_headers
84 PARAMS ((bfd *, bfd_boolean));
86 long oasys_canonicalize_symtab
87 PARAMS ((bfd *, asymbol **));
88 long oasys_canonicalize_reloc
89 PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
91 /* Read in all the section data and relocation stuff too. */
93 static bfd_boolean
94 oasys_read_record (abfd, record)
95 bfd *abfd;
96 oasys_record_union_type *record;
98 bfd_size_type amt = sizeof (record->header);
99 if (bfd_bread ((PTR) record, amt, abfd) != amt)
100 return FALSE;
102 amt = record->header.length - sizeof (record->header);
103 if ((long) amt <= 0)
104 return TRUE;
105 if (bfd_bread ((PTR) ((char *) record + sizeof (record->header)), amt, abfd)
106 != amt)
107 return FALSE;
108 return TRUE;
111 static size_t
112 oasys_string_length (record)
113 oasys_record_union_type *record;
115 return record->header.length
116 - ((char *) record->symbol.name - (char *) record);
119 /*****************************************************************************/
123 Slurp the symbol table by reading in all the records at the start file
124 till we get to the first section record.
126 We'll sort the symbolss into two lists, defined and undefined. The
127 undefined symbols will be placed into the table according to their
128 refno.
130 We do this by placing all undefined symbols at the front of the table
131 moving in, and the defined symbols at the end of the table moving back.
135 static bfd_boolean
136 oasys_slurp_symbol_table (abfd)
137 bfd *const abfd;
139 oasys_record_union_type record;
140 oasys_data_type *data = OASYS_DATA (abfd);
141 bfd_boolean loop = TRUE;
142 asymbol *dest_defined;
143 asymbol *dest;
144 char *string_ptr;
145 bfd_size_type amt;
147 if (data->symbols != (asymbol *) NULL)
149 return TRUE;
151 /* Buy enough memory for all the symbols and all the names */
152 amt = abfd->symcount;
153 amt *= sizeof (asymbol);
154 data->symbols = (asymbol *) bfd_alloc (abfd, amt);
156 amt = data->symbol_string_length;
157 #ifdef UNDERSCORE_HACK
158 /* buy 1 more char for each symbol to keep the underscore in*/
159 amt += abfd->symcount;
160 #endif
161 data->strings = bfd_alloc (abfd, amt);
163 if (!data->symbols || !data->strings)
164 return FALSE;
166 dest_defined = data->symbols + abfd->symcount - 1;
168 string_ptr = data->strings;
169 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
170 return FALSE;
171 while (loop)
174 if (! oasys_read_record (abfd, &record))
175 return FALSE;
176 switch (record.header.type)
178 case oasys_record_is_header_enum:
179 break;
180 case oasys_record_is_local_enum:
181 case oasys_record_is_symbol_enum:
183 int flag = record.header.type == (int) oasys_record_is_local_enum ?
184 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
187 size_t length = oasys_string_length (&record);
188 switch (record.symbol.relb & RELOCATION_TYPE_BITS)
190 case RELOCATION_TYPE_ABS:
191 dest = dest_defined--;
192 dest->section = bfd_abs_section_ptr;
193 dest->flags = 0;
195 break;
196 case RELOCATION_TYPE_REL:
197 dest = dest_defined--;
198 dest->section =
199 OASYS_DATA (abfd)->sections[record.symbol.relb &
200 RELOCATION_SECT_BITS];
201 if (record.header.type == (int) oasys_record_is_local_enum)
203 dest->flags = BSF_LOCAL;
204 if (dest->section == (asection *) (~0))
206 /* It seems that sometimes internal symbols are tied up, but
207 still get output, even though there is no
208 section */
209 dest->section = 0;
212 else
215 dest->flags = flag;
217 break;
218 case RELOCATION_TYPE_UND:
219 dest = data->symbols + H_GET_16 (abfd, record.symbol.refno);
220 dest->section = bfd_und_section_ptr;
221 break;
222 case RELOCATION_TYPE_COM:
223 dest = dest_defined--;
224 dest->name = string_ptr;
225 dest->the_bfd = abfd;
227 dest->section = bfd_com_section_ptr;
229 break;
230 default:
231 dest = dest_defined--;
232 BFD_ASSERT (0);
233 break;
235 dest->name = string_ptr;
236 dest->the_bfd = abfd;
237 dest->udata.p = (PTR) NULL;
238 dest->value = H_GET_32 (abfd, record.symbol.value);
240 #ifdef UNDERSCORE_HACK
241 if (record.symbol.name[0] != '_')
243 string_ptr[0] = '_';
244 string_ptr++;
246 #endif
247 memcpy (string_ptr, record.symbol.name, length);
250 string_ptr[length] = 0;
251 string_ptr += length + 1;
253 break;
254 default:
255 loop = FALSE;
258 return TRUE;
261 static long
262 oasys_get_symtab_upper_bound (abfd)
263 bfd *const abfd;
265 if (! oasys_slurp_symbol_table (abfd))
266 return -1;
268 return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
271 extern const bfd_target oasys_vec;
273 long
274 oasys_canonicalize_symtab (abfd, location)
275 bfd *abfd;
276 asymbol **location;
278 asymbol *symbase;
279 unsigned int counter;
280 if (! oasys_slurp_symbol_table (abfd))
282 return -1;
284 symbase = OASYS_DATA (abfd)->symbols;
285 for (counter = 0; counter < abfd->symcount; counter++)
287 *(location++) = symbase++;
289 *location = 0;
290 return abfd->symcount;
293 /***********************************************************************
294 * archive stuff
297 static const bfd_target *
298 oasys_archive_p (abfd)
299 bfd *abfd;
301 oasys_archive_header_type header;
302 oasys_extarchive_header_type header_ext;
303 unsigned int i;
304 file_ptr filepos;
305 bfd_size_type amt;
307 amt = sizeof (header_ext);
308 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
309 || bfd_bread ((PTR) &header_ext, amt, abfd) != amt)
311 if (bfd_get_error () != bfd_error_system_call)
312 bfd_set_error (bfd_error_wrong_format);
313 return NULL;
316 header.version = H_GET_32 (abfd, header_ext.version);
317 header.mod_count = H_GET_32 (abfd, header_ext.mod_count);
318 header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset);
319 header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size);
320 header.sym_count = H_GET_32 (abfd, header_ext.sym_count);
321 header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset);
322 header.xref_count = H_GET_32 (abfd, header_ext.xref_count);
323 header.xref_lst_offset = H_GET_32 (abfd, header_ext.xref_lst_offset);
326 There isn't a magic number in an Oasys archive, so the best we
327 can do to verify reasonableness is to make sure that the values in
328 the header are too weird
331 if (header.version > 10000 ||
332 header.mod_count > 10000 ||
333 header.sym_count > 100000 ||
334 header.xref_count > 100000)
335 return (const bfd_target *) NULL;
338 That all worked, let's buy the space for the header and read in
339 the headers.
342 oasys_ar_data_type *ar;
343 oasys_module_info_type *module;
344 oasys_module_table_type record;
346 amt = sizeof (oasys_ar_data_type);
347 ar = (oasys_ar_data_type *) bfd_alloc (abfd, amt);
349 amt = header.mod_count;
350 amt *= sizeof (oasys_module_info_type);
351 module = (oasys_module_info_type *) bfd_alloc (abfd, amt);
353 if (!ar || !module)
354 return NULL;
356 abfd->tdata.oasys_ar_data = ar;
357 ar->module = module;
358 ar->module_count = header.mod_count;
360 filepos = header.mod_tbl_offset;
361 for (i = 0; i < header.mod_count; i++)
363 if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
364 return NULL;
366 /* There are two ways of specifying the archive header */
368 if (0)
370 oasys_extmodule_table_type_a_type record_ext;
372 amt = sizeof (record_ext);
373 if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
374 return NULL;
376 record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
377 record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
379 record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
380 record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
381 record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
383 module[i].name = bfd_alloc (abfd, (bfd_size_type) 33);
384 if (!module[i].name)
385 return NULL;
387 memcpy (module[i].name, record_ext.mod_name, 33);
388 filepos +=
389 sizeof (record_ext) +
390 record.dep_count * 4 +
391 record.depee_count * 4 +
392 record.sect_count * 8 + 187;
394 else
396 oasys_extmodule_table_type_b_type record_ext;
398 amt = sizeof (record_ext);
399 if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
400 return NULL;
402 record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
403 record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
405 record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
406 record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
407 record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
408 record.module_name_size = H_GET_32 (abfd,
409 record_ext.mod_name_length);
411 amt = record.module_name_size;
412 module[i].name = bfd_alloc (abfd, amt + 1);
413 if (!module[i].name)
414 return NULL;
415 if (bfd_bread ((PTR) module[i].name, amt, abfd) != amt)
416 return NULL;
417 module[i].name[record.module_name_size] = 0;
418 filepos += (sizeof (record_ext)
419 + record.dep_count * 4
420 + record.module_name_size + 1);
423 module[i].size = record.mod_size;
424 module[i].pos = record.file_offset;
425 module[i].abfd = 0;
428 return abfd->xvec;
431 static bfd_boolean
432 oasys_mkobject (abfd)
433 bfd *abfd;
435 bfd_size_type amt = sizeof (oasys_data_type);
436 abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, amt);
437 return abfd->tdata.oasys_obj_data != NULL;
440 #define MAX_SECS 16
441 static const bfd_target *
442 oasys_object_p (abfd)
443 bfd *abfd;
445 oasys_data_type *oasys;
446 oasys_data_type *save = OASYS_DATA (abfd);
447 bfd_boolean loop = TRUE;
448 bfd_boolean had_usefull = FALSE;
450 abfd->tdata.oasys_obj_data = 0;
451 oasys_mkobject (abfd);
452 oasys = OASYS_DATA (abfd);
453 memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));
455 /* Point to the start of the file */
456 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
457 goto fail;
458 oasys->symbol_string_length = 0;
459 /* Inspect the records, but only keep the section info -
460 remember the size of the symbols
462 oasys->first_data_record = 0;
463 while (loop)
465 oasys_record_union_type record;
466 if (! oasys_read_record (abfd, &record))
467 goto fail;
468 if ((size_t) record.header.length < (size_t) sizeof (record.header))
469 goto fail;
472 switch ((oasys_record_enum_type) (record.header.type))
474 case oasys_record_is_header_enum:
475 had_usefull = TRUE;
476 break;
477 case oasys_record_is_symbol_enum:
478 case oasys_record_is_local_enum:
479 /* Count symbols and remember their size for a future malloc */
480 abfd->symcount++;
481 oasys->symbol_string_length += 1 + oasys_string_length (&record);
482 had_usefull = TRUE;
483 break;
484 case oasys_record_is_section_enum:
486 asection *s;
487 char *buffer;
488 unsigned int section_number;
489 if (record.section.header.length != sizeof (record.section))
491 goto fail;
493 buffer = bfd_alloc (abfd, (bfd_size_type) 3);
494 if (!buffer)
495 goto fail;
496 section_number = record.section.relb & RELOCATION_SECT_BITS;
497 sprintf (buffer, "%u", section_number);
498 s = bfd_make_section (abfd, buffer);
499 oasys->sections[section_number] = s;
500 switch (record.section.relb & RELOCATION_TYPE_BITS)
502 case RELOCATION_TYPE_ABS:
503 case RELOCATION_TYPE_REL:
504 break;
505 case RELOCATION_TYPE_UND:
506 case RELOCATION_TYPE_COM:
507 BFD_FAIL ();
510 s->size = H_GET_32 (abfd, record.section.value);
511 s->vma = H_GET_32 (abfd, record.section.vma);
512 s->flags = 0;
513 had_usefull = TRUE;
515 break;
516 case oasys_record_is_data_enum:
517 oasys->first_data_record = bfd_tell (abfd) - record.header.length;
518 case oasys_record_is_debug_enum:
519 case oasys_record_is_module_enum:
520 case oasys_record_is_named_section_enum:
521 case oasys_record_is_end_enum:
522 if (! had_usefull)
523 goto fail;
524 loop = FALSE;
525 break;
526 default:
527 goto fail;
530 oasys->symbols = (asymbol *) NULL;
532 Oasys support several architectures, but I can't see a simple way
533 to discover which one is in a particular file - we'll guess
535 bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
536 if (abfd->symcount != 0)
538 abfd->flags |= HAS_SYMS;
542 We don't know if a section has data until we've read it..
545 oasys_slurp_section_data (abfd);
548 return abfd->xvec;
550 fail:
551 (void) bfd_release (abfd, oasys);
552 abfd->tdata.oasys_obj_data = save;
553 return (const bfd_target *) NULL;
557 static void
558 oasys_get_symbol_info (ignore_abfd, symbol, ret)
559 bfd *ignore_abfd ATTRIBUTE_UNUSED;
560 asymbol *symbol;
561 symbol_info *ret;
563 bfd_symbol_info (symbol, ret);
564 if (!symbol->section)
565 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
568 static void
569 oasys_print_symbol (abfd, afile, symbol, how)
570 bfd *abfd;
571 PTR afile;
572 asymbol *symbol;
573 bfd_print_symbol_type how;
575 FILE *file = (FILE *) afile;
577 switch (how)
579 case bfd_print_symbol_name:
580 case bfd_print_symbol_more:
581 fprintf (file, "%s", symbol->name);
582 break;
583 case bfd_print_symbol_all:
585 const char *section_name = symbol->section == (asection *) NULL ?
586 (const char *) "*abs" : symbol->section->name;
588 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
590 fprintf (file, " %-5s %s",
591 section_name,
592 symbol->name);
594 break;
598 The howto table is build using the top two bits of a reloc byte to
599 index into it. The bits are PCREL,WORD/LONG
601 static reloc_howto_type howto_table[] =
604 HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
605 HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE),
606 HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
607 HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE)
610 /* Read in all the section data and relocation stuff too */
611 static bfd_boolean
612 oasys_slurp_section_data (abfd)
613 bfd *const abfd;
615 oasys_record_union_type record;
616 oasys_data_type *data = OASYS_DATA (abfd);
617 bfd_boolean loop = TRUE;
618 oasys_per_section_type *per;
619 asection *s;
620 bfd_size_type amt;
622 /* See if the data has been slurped already .. */
623 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
625 per = oasys_per_section (s);
626 if (per->initialized)
627 return TRUE;
630 if (data->first_data_record == 0)
631 return TRUE;
633 if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
634 return FALSE;
635 while (loop)
637 if (! oasys_read_record (abfd, &record))
638 return FALSE;
639 switch (record.header.type)
641 case oasys_record_is_header_enum:
642 break;
643 case oasys_record_is_data_enum:
646 bfd_byte *src = record.data.data;
647 bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
648 bfd_byte *dst_ptr;
649 bfd_byte *dst_base_ptr;
650 unsigned int relbit;
651 unsigned int count;
652 asection *section =
653 data->sections[record.data.relb & RELOCATION_SECT_BITS];
654 bfd_vma dst_offset;
656 per = oasys_per_section (section);
658 if (! per->initialized)
660 per->data = (bfd_byte *) bfd_zalloc (abfd, section->size);
661 if (!per->data)
662 return FALSE;
663 per->reloc_tail_ptr
664 = (oasys_reloc_type **) &section->relocation;
665 per->had_vma = FALSE;
666 per->initialized = TRUE;
667 section->reloc_count = 0;
668 section->flags = SEC_ALLOC;
671 dst_offset = H_GET_32 (abfd, record.data.addr);
672 if (! per->had_vma)
674 /* Take the first vma we see as the base */
675 section->vma = dst_offset;
676 per->had_vma = TRUE;
679 dst_offset -= section->vma;
681 dst_base_ptr = oasys_per_section (section)->data;
682 dst_ptr = oasys_per_section (section)->data +
683 dst_offset;
685 if (src < end_src)
687 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
689 while (src < end_src)
691 unsigned char mod_byte = *src++;
692 size_t gap = end_src - src;
694 count = 8;
695 if (mod_byte == 0 && gap >= 8)
697 dst_ptr[0] = src[0];
698 dst_ptr[1] = src[1];
699 dst_ptr[2] = src[2];
700 dst_ptr[3] = src[3];
701 dst_ptr[4] = src[4];
702 dst_ptr[5] = src[5];
703 dst_ptr[6] = src[6];
704 dst_ptr[7] = src[7];
705 dst_ptr += 8;
706 src += 8;
708 else
710 for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
712 if (relbit & mod_byte)
714 unsigned char reloc = *src;
715 /* This item needs to be relocated */
716 switch (reloc & RELOCATION_TYPE_BITS)
718 case RELOCATION_TYPE_ABS:
720 break;
722 case RELOCATION_TYPE_REL:
724 /* Relocate the item relative to the section */
725 oasys_reloc_type *r;
727 amt = sizeof (oasys_reloc_type);
728 r = (oasys_reloc_type *) bfd_alloc (abfd,
729 amt);
730 if (!r)
731 return FALSE;
732 *(per->reloc_tail_ptr) = r;
733 per->reloc_tail_ptr = &r->next;
734 r->next = (oasys_reloc_type *) NULL;
735 /* Reference to undefined symbol */
736 src++;
737 /* There is no symbol */
738 r->symbol = 0;
739 /* Work out the howto */
740 abort ();
741 r->relent.address = dst_ptr - dst_base_ptr;
742 r->relent.howto = &howto_table[reloc >> 6];
743 r->relent.sym_ptr_ptr = (asymbol **) NULL;
744 section->reloc_count++;
746 /* Fake up the data to look like
747 it's got the -ve pc in it, this
748 makes it much easier to convert
749 into other formats. This is done
750 by hitting the addend. */
751 if (r->relent.howto->pc_relative)
752 r->relent.addend -= dst_ptr - dst_base_ptr;
754 break;
757 case RELOCATION_TYPE_UND:
759 oasys_reloc_type *r;
761 amt = sizeof (oasys_reloc_type);
762 r = (oasys_reloc_type *) bfd_alloc (abfd,
763 amt);
764 if (!r)
765 return FALSE;
766 *(per->reloc_tail_ptr) = r;
767 per->reloc_tail_ptr = &r->next;
768 r->next = (oasys_reloc_type *) NULL;
769 /* Reference to undefined symbol */
770 src++;
771 /* Get symbol number */
772 r->symbol = (src[0] << 8) | src[1];
773 /* Work out the howto */
774 abort ();
776 r->relent.addend = 0;
777 r->relent.address = dst_ptr - dst_base_ptr;
778 r->relent.howto = &howto_table[reloc >> 6];
779 r->relent.sym_ptr_ptr = (asymbol **) NULL;
780 section->reloc_count++;
782 src += 2;
783 /* Fake up the data to look like
784 it's got the -ve pc in it, this
785 makes it much easier to convert
786 into other formats. This is done
787 by hitting the addend. */
788 if (r->relent.howto->pc_relative)
789 r->relent.addend -= dst_ptr - dst_base_ptr;
791 break;
792 case RELOCATION_TYPE_COM:
793 BFD_FAIL ();
796 *dst_ptr++ = *src++;
801 break;
802 case oasys_record_is_local_enum:
803 case oasys_record_is_symbol_enum:
804 case oasys_record_is_section_enum:
805 break;
806 default:
807 loop = FALSE;
811 return TRUE;
815 static bfd_boolean
816 oasys_new_section_hook (abfd, newsect)
817 bfd *abfd;
818 asection *newsect;
820 newsect->used_by_bfd = (PTR)
821 bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
822 if (!newsect->used_by_bfd)
823 return FALSE;
824 oasys_per_section (newsect)->data = (bfd_byte *) NULL;
825 oasys_per_section (newsect)->section = newsect;
826 oasys_per_section (newsect)->offset = 0;
827 oasys_per_section (newsect)->initialized = FALSE;
828 newsect->alignment_power = 1;
829 /* Turn the section string into an index */
831 sscanf (newsect->name, "%u", &newsect->target_index);
833 return TRUE;
837 static long
838 oasys_get_reloc_upper_bound (abfd, asect)
839 bfd *abfd;
840 sec_ptr asect;
842 if (! oasys_slurp_section_data (abfd))
843 return -1;
844 return (asect->reloc_count + 1) * sizeof (arelent *);
847 static bfd_boolean
848 oasys_get_section_contents (abfd, section, location, offset, count)
849 bfd *abfd;
850 sec_ptr section;
851 PTR location;
852 file_ptr offset;
853 bfd_size_type count;
855 oasys_per_section_type *p = oasys_per_section (section);
856 oasys_slurp_section_data (abfd);
857 if (! p->initialized)
859 (void) memset (location, 0, (size_t) count);
861 else
863 (void) memcpy (location, (PTR) (p->data + offset), (size_t) count);
865 return TRUE;
869 long
870 oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
871 bfd *ignore_abfd ATTRIBUTE_UNUSED;
872 sec_ptr section;
873 arelent **relptr;
874 asymbol **symbols ATTRIBUTE_UNUSED;
876 unsigned int reloc_count = 0;
877 oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
878 while (src != (oasys_reloc_type *) NULL)
880 abort ();
882 *relptr++ = &src->relent;
883 src = src->next;
884 reloc_count++;
886 *relptr = (arelent *) NULL;
887 return section->reloc_count = reloc_count;
893 /* Writing */
896 /* Calculate the checksum and write one record */
897 static bfd_boolean
898 oasys_write_record (abfd, type, record, size)
899 bfd *abfd;
900 oasys_record_enum_type type;
901 oasys_record_union_type *record;
902 size_t size;
904 int checksum;
905 size_t i;
906 unsigned char *ptr;
908 record->header.length = size;
909 record->header.type = (int) type;
910 record->header.check_sum = 0;
911 record->header.fill = 0;
912 ptr = (unsigned char *) &record->pad[0];
913 checksum = 0;
914 for (i = 0; i < size; i++)
916 checksum += *ptr++;
918 record->header.check_sum = 0xff & (-checksum);
919 if (bfd_bwrite ((PTR) record, (bfd_size_type) size, abfd) != size)
920 return FALSE;
921 return TRUE;
925 /* Write out all the symbols */
926 static bfd_boolean
927 oasys_write_syms (abfd)
928 bfd *abfd;
930 unsigned int count;
931 asymbol **generic = bfd_get_outsymbols (abfd);
932 unsigned int index = 0;
933 for (count = 0; count < bfd_get_symcount (abfd); count++)
936 oasys_symbol_record_type symbol;
937 asymbol *const g = generic[count];
939 const char *src = g->name;
940 char *dst = symbol.name;
941 unsigned int l = 0;
943 if (bfd_is_com_section (g->section))
945 symbol.relb = RELOCATION_TYPE_COM;
946 H_PUT_16 (abfd, index, symbol.refno);
947 index++;
949 else if (bfd_is_abs_section (g->section))
951 symbol.relb = RELOCATION_TYPE_ABS;
952 H_PUT_16 (abfd, 0, symbol.refno);
955 else if (bfd_is_und_section (g->section))
957 symbol.relb = RELOCATION_TYPE_UND;
958 H_PUT_16 (abfd, index, symbol.refno);
959 /* Overload the value field with the output index number */
960 index++;
962 else if (g->flags & BSF_DEBUGGING)
964 /* throw it away */
965 continue;
967 else
969 if (g->section == (asection *) NULL)
971 /* Sometime, the oasys tools give out a symbol with illegal
972 bits in it, we'll output it in the same broken way */
974 symbol.relb = RELOCATION_TYPE_REL | 0;
976 else
978 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
980 H_PUT_16 (abfd, 0, symbol.refno);
982 #ifdef UNDERSCORE_HACK
983 if (src[l] == '_')
984 dst[l++] = '.';
985 #endif
986 while (src[l])
988 dst[l] = src[l];
989 l++;
992 H_PUT_32 (abfd, g->value, symbol.value);
995 if (g->flags & BSF_LOCAL)
997 if (! oasys_write_record (abfd,
998 oasys_record_is_local_enum,
999 (oasys_record_union_type *) & symbol,
1000 offsetof (oasys_symbol_record_type,
1001 name[0]) + l))
1002 return FALSE;
1004 else
1006 if (! oasys_write_record (abfd,
1007 oasys_record_is_symbol_enum,
1008 (oasys_record_union_type *) & symbol,
1009 offsetof (oasys_symbol_record_type,
1010 name[0]) + l))
1011 return FALSE;
1013 g->value = index - 1;
1016 return TRUE;
1020 /* Write a section header for each section */
1021 static bfd_boolean
1022 oasys_write_sections (abfd)
1023 bfd *abfd;
1025 asection *s;
1026 static oasys_section_record_type out;
1028 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
1030 if (!ISDIGIT (s->name[0]))
1032 (*_bfd_error_handler)
1033 (_("%s: can not represent section `%s' in oasys"),
1034 bfd_get_filename (abfd), s->name);
1035 bfd_set_error (bfd_error_nonrepresentable_section);
1036 return FALSE;
1038 out.relb = RELOCATION_TYPE_REL | s->target_index;
1039 H_PUT_32 (abfd, s->size, out.value);
1040 H_PUT_32 (abfd, s->vma, out.vma);
1042 if (! oasys_write_record (abfd,
1043 oasys_record_is_section_enum,
1044 (oasys_record_union_type *) & out,
1045 sizeof (out)))
1046 return FALSE;
1048 return TRUE;
1051 static bfd_boolean
1052 oasys_write_header (abfd)
1053 bfd *abfd;
1055 /* Create and write the header */
1056 oasys_header_record_type r;
1057 size_t length = strlen (abfd->filename);
1058 if (length > (size_t) sizeof (r.module_name))
1060 length = sizeof (r.module_name);
1063 (void) memcpy (r.module_name,
1064 abfd->filename,
1065 length);
1066 (void) memset (r.module_name + length,
1067 ' ',
1068 sizeof (r.module_name) - length);
1070 r.version_number = OASYS_VERSION_NUMBER;
1071 r.rev_number = OASYS_REV_NUMBER;
1072 if (! oasys_write_record (abfd,
1073 oasys_record_is_header_enum,
1074 (oasys_record_union_type *) & r,
1075 offsetof (oasys_header_record_type,
1076 description[0])))
1077 return FALSE;
1079 return TRUE;
1082 static bfd_boolean
1083 oasys_write_end (abfd)
1084 bfd *abfd;
1086 oasys_end_record_type end;
1087 unsigned char null = 0;
1088 end.relb = RELOCATION_TYPE_ABS;
1089 H_PUT_32 (abfd, abfd->start_address, end.entry);
1090 H_PUT_16 (abfd, 0, end.fill);
1091 end.zero = 0;
1092 if (! oasys_write_record (abfd,
1093 oasys_record_is_end_enum,
1094 (oasys_record_union_type *) & end,
1095 sizeof (end)))
1096 return FALSE;
1097 if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
1098 return FALSE;
1099 return TRUE;
1102 static int
1103 comp (ap, bp)
1104 const PTR ap;
1105 const PTR bp;
1107 arelent *a = *((arelent **) ap);
1108 arelent *b = *((arelent **) bp);
1109 return a->address - b->address;
1113 Writing data..
1116 static bfd_boolean
1117 oasys_write_data (abfd)
1118 bfd *abfd;
1120 asection *s;
1121 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
1123 if (s->flags & SEC_LOAD)
1125 bfd_byte *raw_data = oasys_per_section (s)->data;
1126 oasys_data_record_type processed_data;
1127 bfd_size_type current_byte_index = 0;
1128 unsigned int relocs_to_go = s->reloc_count;
1129 arelent **p = s->orelocation;
1130 if (s->reloc_count != 0)
1132 /* Sort the reloc records so it's easy to insert the relocs into the
1133 data */
1135 qsort (s->orelocation,
1136 s->reloc_count,
1137 sizeof (arelent **),
1138 comp);
1140 current_byte_index = 0;
1141 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
1143 while (current_byte_index < s->size)
1145 /* Scan forwards by eight bytes or however much is left and see if
1146 there are any relocations going on */
1147 bfd_byte *mod = &processed_data.data[0];
1148 bfd_byte *dst = &processed_data.data[1];
1150 unsigned int i = 0;
1151 *mod = 0;
1154 H_PUT_32 (abfd, s->vma + current_byte_index,
1155 processed_data.addr);
1157 /* Don't start a relocation unless you're sure you can finish it
1158 within the same data record. The worst case relocation is a
1159 4-byte relocatable value which is split across two modification
1160 bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
1161 1 modification byte + 2 data = 8 bytes total). That's where
1162 the magic number 8 comes from.
1164 while (current_byte_index < s->size && dst <=
1165 &processed_data.data[sizeof (processed_data.data) - 8])
1169 if (relocs_to_go != 0)
1171 arelent *r = *p;
1172 reloc_howto_type *const how = r->howto;
1173 /* There is a relocation, is it for this byte ? */
1174 if (r->address == current_byte_index)
1176 unsigned char rel_byte;
1178 p++;
1179 relocs_to_go--;
1181 *mod |= (1 << i);
1182 if (how->pc_relative)
1184 rel_byte = RELOCATION_PCREL_BIT;
1186 /* Also patch the raw data so that it doesn't have
1187 the -ve stuff any more */
1188 if (how->size != 2)
1190 bfd_put_16 (abfd,
1191 bfd_get_16 (abfd, raw_data) +
1192 current_byte_index, raw_data);
1195 else
1197 bfd_put_32 (abfd,
1198 bfd_get_32 (abfd, raw_data) +
1199 current_byte_index, raw_data);
1202 else
1204 rel_byte = 0;
1206 if (how->size == 2)
1208 rel_byte |= RELOCATION_32BIT_BIT;
1211 /* Is this a section relative relocation, or a symbol
1212 relative relocation ? */
1213 abort ();
1216 asymbol *sym = *(r->sym_ptr_ptr);
1218 /* If this symbol has a section attached, then it
1219 has already been resolved. Change from a symbol
1220 ref to a section ref */
1221 if (sym->section != (asection *) NULL)
1223 rel_byte |= RELOCATION_TYPE_REL;
1224 rel_byte |=
1225 sym->section->output_section->target_index;
1226 *dst++ = rel_byte;
1228 else
1230 rel_byte |= RELOCATION_TYPE_UND;
1231 *dst++ = rel_byte;
1232 /* Next two bytes are a symbol index - we can get
1233 this from the symbol value which has been zapped
1234 into the symbol index in the table when the
1235 symbol table was written
1237 *dst++ = sym->value >> 8;
1238 *dst++ = sym->value;
1241 #define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
1242 /* relocations never occur from an unloadable section,
1243 so we can assume that raw_data is not NULL
1245 *dst++ = *raw_data++;
1246 ADVANCE
1247 * dst++ = *raw_data++;
1248 ADVANCE
1249 if (how->size == 2)
1251 *dst++ = *raw_data++;
1252 ADVANCE
1253 * dst++ = *raw_data++;
1254 ADVANCE
1256 continue;
1259 /* If this is coming from an unloadable section then copy
1260 zeros */
1261 if (raw_data == NULL)
1263 *dst++ = 0;
1265 else
1267 *dst++ = *raw_data++;
1269 ADVANCE
1272 /* Don't write a useless null modification byte */
1273 if (dst == mod + 1)
1275 --dst;
1278 if (! (oasys_write_record
1279 (abfd, oasys_record_is_data_enum,
1280 ((oasys_record_union_type *) &processed_data),
1281 (size_t) (dst - (bfd_byte *) &processed_data))))
1282 return FALSE;
1287 return TRUE;
1290 static bfd_boolean
1291 oasys_write_object_contents (abfd)
1292 bfd *abfd;
1294 if (! oasys_write_header (abfd))
1295 return FALSE;
1296 if (! oasys_write_syms (abfd))
1297 return FALSE;
1298 if (! oasys_write_sections (abfd))
1299 return FALSE;
1300 if (! oasys_write_data (abfd))
1301 return FALSE;
1302 if (! oasys_write_end (abfd))
1303 return FALSE;
1304 return TRUE;
1310 /** exec and core file sections */
1312 /* set section contents is complicated with OASYS since the format is
1313 * not a byte image, but a record stream.
1315 static bfd_boolean
1316 oasys_set_section_contents (abfd, section, location, offset, count)
1317 bfd *abfd;
1318 sec_ptr section;
1319 const PTR location;
1320 file_ptr offset;
1321 bfd_size_type count;
1323 if (count != 0)
1325 if (oasys_per_section (section)->data == (bfd_byte *) NULL)
1327 oasys_per_section (section)->data =
1328 (bfd_byte *) (bfd_alloc (abfd, section->size));
1329 if (!oasys_per_section (section)->data)
1330 return FALSE;
1332 (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
1333 location,
1334 (size_t) count);
1336 return TRUE;
1341 /* Native-level interface to symbols. */
1343 /* We read the symbols into a buffer, which is discarded when this
1344 function exits. We read the strings into a buffer large enough to
1345 hold them all plus all the cached symbol entries. */
1347 static asymbol *
1348 oasys_make_empty_symbol (abfd)
1349 bfd *abfd;
1351 bfd_size_type amt = sizeof (oasys_symbol_type);
1352 oasys_symbol_type *new = (oasys_symbol_type *) bfd_zalloc (abfd, amt);
1353 if (!new)
1354 return NULL;
1355 new->symbol.the_bfd = abfd;
1356 return &new->symbol;
1362 /* User should have checked the file flags; perhaps we should return
1363 BFD_NO_MORE_SYMBOLS if there are none? */
1365 static bfd *
1366 oasys_openr_next_archived_file (arch, prev)
1367 bfd *arch;
1368 bfd *prev;
1370 oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
1371 oasys_module_info_type *p;
1372 /* take the next one from the arch state, or reset */
1373 if (prev == (bfd *) NULL)
1375 /* Reset the index - the first two entries are bogus*/
1376 ar->module_index = 0;
1379 p = ar->module + ar->module_index;
1380 ar->module_index++;
1382 if (ar->module_index <= ar->module_count)
1384 if (p->abfd == (bfd *) NULL)
1386 p->abfd = _bfd_create_empty_archive_element_shell (arch);
1387 p->abfd->origin = p->pos;
1388 p->abfd->filename = p->name;
1390 /* Fixup a pointer to this element for the member */
1391 p->abfd->arelt_data = (PTR) p;
1393 return p->abfd;
1395 else
1397 bfd_set_error (bfd_error_no_more_archived_files);
1398 return (bfd *) NULL;
1402 static bfd_boolean
1403 oasys_find_nearest_line (abfd, section, symbols, offset,
1404 filename_ptr, functionname_ptr, line_ptr)
1405 bfd *abfd ATTRIBUTE_UNUSED;
1406 asection *section ATTRIBUTE_UNUSED;
1407 asymbol **symbols ATTRIBUTE_UNUSED;
1408 bfd_vma offset ATTRIBUTE_UNUSED;
1409 const char **filename_ptr ATTRIBUTE_UNUSED;
1410 const char **functionname_ptr ATTRIBUTE_UNUSED;
1411 unsigned int *line_ptr ATTRIBUTE_UNUSED;
1413 return FALSE;
1417 static int
1418 oasys_generic_stat_arch_elt (abfd, buf)
1419 bfd *abfd;
1420 struct stat *buf;
1422 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1423 if (mod == (oasys_module_info_type *) NULL)
1425 bfd_set_error (bfd_error_invalid_operation);
1426 return -1;
1428 else
1430 buf->st_size = mod->size;
1431 buf->st_mode = 0666;
1432 return 0;
1436 static int
1437 oasys_sizeof_headers (abfd, exec)
1438 bfd *abfd ATTRIBUTE_UNUSED;
1439 bfd_boolean exec ATTRIBUTE_UNUSED;
1441 return 0;
1444 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
1445 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1447 #define oasys_slurp_armap bfd_true
1448 #define oasys_slurp_extended_name_table bfd_true
1449 #define oasys_construct_extended_name_table \
1450 ((bfd_boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
1451 bfd_true)
1452 #define oasys_truncate_arname bfd_dont_truncate_arname
1453 #define oasys_write_armap \
1454 ((bfd_boolean (*) \
1455 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
1456 bfd_true)
1457 #define oasys_read_ar_hdr bfd_nullvoidptr
1458 #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
1459 #define oasys_update_armap_timestamp bfd_true
1461 #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
1462 #define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1463 #define oasys_get_lineno _bfd_nosymbols_get_lineno
1464 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1465 #define oasys_read_minisymbols _bfd_generic_read_minisymbols
1466 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1468 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1470 #define oasys_set_arch_mach bfd_default_set_arch_mach
1472 #define oasys_get_section_contents_in_window \
1473 _bfd_generic_get_section_contents_in_window
1475 #define oasys_bfd_get_relocated_section_contents \
1476 bfd_generic_get_relocated_section_contents
1477 #define oasys_bfd_relax_section bfd_generic_relax_section
1478 #define oasys_bfd_gc_sections bfd_generic_gc_sections
1479 #define oasys_bfd_merge_sections bfd_generic_merge_sections
1480 #define oasys_bfd_is_group_section bfd_generic_is_group_section
1481 #define oasys_bfd_discard_group bfd_generic_discard_group
1482 #define oasys_section_already_linked \
1483 _bfd_generic_section_already_linked
1484 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1485 #define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1486 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1487 #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
1488 #define oasys_bfd_final_link _bfd_generic_final_link
1489 #define oasys_bfd_link_split_section _bfd_generic_link_split_section
1491 /*SUPPRESS 460 */
1492 const bfd_target oasys_vec =
1494 "oasys", /* name */
1495 bfd_target_oasys_flavour,
1496 BFD_ENDIAN_BIG, /* target byte order */
1497 BFD_ENDIAN_BIG, /* target headers byte order */
1498 (HAS_RELOC | EXEC_P | /* object flags */
1499 HAS_LINENO | HAS_DEBUG |
1500 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1501 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1502 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1503 0, /* leading underscore */
1504 ' ', /* ar_pad_char */
1505 16, /* ar_max_namelen */
1506 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1507 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1508 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1509 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1510 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1511 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1513 {_bfd_dummy_target,
1514 oasys_object_p, /* bfd_check_format */
1515 oasys_archive_p,
1516 _bfd_dummy_target,
1518 { /* bfd_set_format */
1519 bfd_false,
1520 oasys_mkobject,
1521 _bfd_generic_mkarchive,
1522 bfd_false
1524 { /* bfd_write_contents */
1525 bfd_false,
1526 oasys_write_object_contents,
1527 _bfd_write_archive_contents,
1528 bfd_false,
1531 BFD_JUMP_TABLE_GENERIC (oasys),
1532 BFD_JUMP_TABLE_COPY (_bfd_generic),
1533 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1534 BFD_JUMP_TABLE_ARCHIVE (oasys),
1535 BFD_JUMP_TABLE_SYMBOLS (oasys),
1536 BFD_JUMP_TABLE_RELOCS (oasys),
1537 BFD_JUMP_TABLE_WRITE (oasys),
1538 BFD_JUMP_TABLE_LINK (oasys),
1539 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1541 NULL,
1543 (PTR) 0