Change PAGE_SIZE to TARGET_PAGE_SIZE
[platform/upstream/binutils.git] / bfd / oasys.c
1 /* BFD back-end for oasys objects.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3    Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #define UNDERSCORE_HACK 1
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include <ctype.h>
25 #include "libbfd.h"
26 #include "oasys.h"
27 #include "liboasys.h"
28
29 /* XXX - FIXME.  offsetof belongs in the system-specific files in
30    ../include/sys. */
31 /* Define offsetof for those systems which lack it */
32
33 #ifndef offsetof
34 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
35 #endif
36
37 static boolean oasys_read_record PARAMS ((bfd *,
38                                           oasys_record_union_type *));
39 static boolean oasys_write_sections PARAMS ((bfd *));
40 static boolean oasys_write_record PARAMS ((bfd *,
41                                            oasys_record_enum_type,
42                                            oasys_record_union_type *,
43                                            size_t));
44 static boolean oasys_write_syms PARAMS ((bfd *));
45 static boolean oasys_write_header PARAMS ((bfd *));
46 static boolean oasys_write_end PARAMS ((bfd *));
47 static boolean oasys_write_data PARAMS ((bfd *));
48
49 /* Read in all the section data and relocation stuff too */
50 PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd));
51
52 static boolean
53 oasys_read_record (abfd, record)
54      bfd *abfd;
55      oasys_record_union_type *record;
56 {
57   if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd)
58       != sizeof (record->header))
59     return false;
60
61   if ((size_t) record->header.length <= (size_t) sizeof (record->header))
62     return true;
63   if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)),
64                 1, record->header.length - sizeof (record->header),
65                 abfd)
66       != record->header.length - sizeof (record->header))
67     return false;
68   return true;
69 }
70 static size_t
71 oasys_string_length (record)
72      oasys_record_union_type *record;
73 {
74   return record->header.length
75     - ((char *) record->symbol.name - (char *) record);
76 }
77
78 /*****************************************************************************/
79
80 /*
81
82 Slurp the symbol table by reading in all the records at the start file
83 till we get to the first section record.
84
85 We'll sort the symbolss into  two lists, defined and undefined. The
86 undefined symbols will be placed into the table according to their
87 refno.
88
89 We do this by placing all undefined symbols at the front of the table
90 moving in, and the defined symbols at the end of the table moving back.
91
92 */
93
94 static boolean
95 oasys_slurp_symbol_table (abfd)
96      bfd *CONST abfd;
97 {
98   oasys_record_union_type record;
99   oasys_data_type *data = OASYS_DATA (abfd);
100   boolean loop = true;
101   asymbol *dest_defined;
102   asymbol *dest;
103   char *string_ptr;
104
105
106   if (data->symbols != (asymbol *) NULL)
107     {
108       return true;
109     }
110   /* Buy enough memory for all the symbols and all the names */
111   data->symbols =
112     (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount);
113 #ifdef UNDERSCORE_HACK
114   /* buy 1 more char for each symbol to keep the underscore in*/
115   data->strings = bfd_alloc (abfd, data->symbol_string_length +
116                              abfd->symcount);
117 #else
118   data->strings = bfd_alloc (abfd, data->symbol_string_length);
119 #endif
120   if (!data->symbols || !data->strings)
121     {
122       bfd_set_error (bfd_error_no_memory);
123       return false;
124     }
125
126   dest_defined = data->symbols + abfd->symcount - 1;
127
128   string_ptr = data->strings;
129   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
130     return false;
131   while (loop)
132     {
133
134       if (! oasys_read_record (abfd, &record))
135         return false;
136       switch (record.header.type)
137         {
138         case oasys_record_is_header_enum:
139           break;
140         case oasys_record_is_local_enum:
141         case oasys_record_is_symbol_enum:
142           {
143             int flag = record.header.type == (int) oasys_record_is_local_enum ?
144             (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
145
146
147             size_t length = oasys_string_length (&record);
148             switch (record.symbol.relb & RELOCATION_TYPE_BITS)
149               {
150               case RELOCATION_TYPE_ABS:
151                 dest = dest_defined--;
152                 dest->section = bfd_abs_section_ptr;
153                 dest->flags = 0;
154
155                 break;
156               case RELOCATION_TYPE_REL:
157                 dest = dest_defined--;
158                 dest->section =
159                   OASYS_DATA (abfd)->sections[record.symbol.relb &
160                                               RELOCATION_SECT_BITS];
161                 if (record.header.type == (int) oasys_record_is_local_enum)
162                   {
163                     dest->flags = BSF_LOCAL;
164                     if (dest->section == (asection *) (~0))
165                       {
166                         /* It seems that sometimes internal symbols are tied up, but
167                        still get output, even though there is no
168                        section */
169                         dest->section = 0;
170                       }
171                   }
172                 else
173                   {
174
175                     dest->flags = flag;
176                   }
177                 break;
178               case RELOCATION_TYPE_UND:
179                 dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno);
180                 dest->section = bfd_und_section_ptr;
181                 break;
182               case RELOCATION_TYPE_COM:
183                 dest = dest_defined--;
184                 dest->name = string_ptr;
185                 dest->the_bfd = abfd;
186
187                 dest->section = bfd_com_section_ptr;
188
189                 break;
190               default:
191                 dest = dest_defined--;
192                 BFD_ASSERT (0);
193                 break;
194               }
195             dest->name = string_ptr;
196             dest->the_bfd = abfd;
197             dest->udata.p = (PTR) NULL;
198             dest->value = bfd_h_get_32 (abfd, record.symbol.value);
199
200 #ifdef UNDERSCORE_HACK
201             if (record.symbol.name[0] != '_')
202               {
203                 string_ptr[0] = '_';
204                 string_ptr++;
205               }
206 #endif
207             memcpy (string_ptr, record.symbol.name, length);
208
209
210             string_ptr[length] = 0;
211             string_ptr += length + 1;
212           }
213           break;
214         default:
215           loop = false;
216         }
217     }
218   return true;
219 }
220
221 static long
222 oasys_get_symtab_upper_bound (abfd)
223      bfd *CONST abfd;
224 {
225   if (! oasys_slurp_symbol_table (abfd))
226     return -1;
227
228   return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
229 }
230
231 /*
232 */
233
234 extern const bfd_target oasys_vec;
235
236 long
237 oasys_get_symtab (abfd, location)
238      bfd *abfd;
239      asymbol **location;
240 {
241   asymbol *symbase;
242   unsigned int counter;
243   if (oasys_slurp_symbol_table (abfd) == false)
244     {
245       return -1;
246     }
247   symbase = OASYS_DATA (abfd)->symbols;
248   for (counter = 0; counter < abfd->symcount; counter++)
249     {
250       *(location++) = symbase++;
251     }
252   *location = 0;
253   return abfd->symcount;
254 }
255
256 /***********************************************************************
257 *  archive stuff
258 */
259
260 static const bfd_target *
261 oasys_archive_p (abfd)
262      bfd *abfd;
263 {
264   oasys_archive_header_type header;
265   oasys_extarchive_header_type header_ext;
266   unsigned int i;
267   file_ptr filepos;
268
269   if (bfd_seek (abfd, (file_ptr) 0, false) != 0
270       || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd)
271           != sizeof (header_ext)))
272     {
273       if (bfd_get_error () != bfd_error_system_call)
274         bfd_set_error (bfd_error_wrong_format);
275       return NULL;
276     }
277
278   header.version = bfd_h_get_32 (abfd, header_ext.version);
279   header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count);
280   header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset);
281   header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size);
282   header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count);
283   header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset);
284   header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count);
285   header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset);
286
287   /*
288     There isn't a magic number in an Oasys archive, so the best we
289     can do to verify reasnableness is to make sure that the values in
290     the header are too weird
291     */
292
293   if (header.version > 10000 ||
294       header.mod_count > 10000 ||
295       header.sym_count > 100000 ||
296       header.xref_count > 100000)
297     return (const bfd_target *) NULL;
298
299   /*
300     That all worked, let's buy the space for the header and read in
301     the headers.
302     */
303   {
304     oasys_ar_data_type *ar =
305     (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type));
306
307     oasys_module_info_type *module =
308     (oasys_module_info_type *)
309     bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count);
310     oasys_module_table_type record;
311
312     if (!ar || !module)
313       {
314         bfd_set_error (bfd_error_no_memory);
315         return NULL;
316       }
317
318     abfd->tdata.oasys_ar_data = ar;
319     ar->module = module;
320     ar->module_count = header.mod_count;
321
322     filepos = header.mod_tbl_offset;
323     for (i = 0; i < header.mod_count; i++)
324       {
325         if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
326           return NULL;
327
328         /* There are two ways of specifying the archive header */
329
330         if (0)
331           {
332             oasys_extmodule_table_type_a_type record_ext;
333             if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
334                 != sizeof (record_ext))
335               return NULL;
336
337             record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
338             record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);
339
340             record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
341             record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
342             record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);
343
344             module[i].name = bfd_alloc (abfd, 33);
345             if (!module[i].name)
346               {
347                 bfd_set_error (bfd_error_no_memory);
348                 return NULL;
349               }
350
351             memcpy (module[i].name, record_ext.mod_name, 33);
352             filepos +=
353               sizeof (record_ext) +
354               record.dep_count * 4 +
355               record.depee_count * 4 +
356               record.sect_count * 8 + 187;
357           }
358         else
359           {
360             oasys_extmodule_table_type_b_type record_ext;
361             if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
362                 != sizeof (record_ext))
363               return NULL;
364
365             record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
366             record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);
367
368             record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
369             record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
370             record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);
371             record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length);
372
373             module[i].name = bfd_alloc (abfd, record.module_name_size + 1);
374             if (!module[i].name)
375               {
376                 bfd_set_error (bfd_error_no_memory);
377                 return NULL;
378               }
379             if (bfd_read ((PTR) module[i].name, 1, record.module_name_size,
380                           abfd)
381                 != record.module_name_size)
382               return NULL;
383             module[i].name[record.module_name_size] = 0;
384             filepos +=
385               sizeof (record_ext) +
386               record.dep_count * 4 +
387               record.module_name_size + 1;
388
389           }
390
391
392         module[i].size = record.mod_size;
393         module[i].pos = record.file_offset;
394         module[i].abfd = 0;
395       }
396
397   }
398   return abfd->xvec;
399 }
400
401 static boolean
402 oasys_mkobject (abfd)
403      bfd *abfd;
404 {
405
406   abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type));
407   return abfd->tdata.oasys_obj_data ? true : false;
408 }
409
410 #define MAX_SECS 16
411 static const bfd_target *
412 oasys_object_p (abfd)
413      bfd *abfd;
414 {
415   oasys_data_type *oasys;
416   oasys_data_type *save = OASYS_DATA (abfd);
417   boolean loop = true;
418   boolean had_usefull = false;
419
420   abfd->tdata.oasys_obj_data = 0;
421   oasys_mkobject (abfd);
422   oasys = OASYS_DATA (abfd);
423   memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));
424
425   /* Point to the start of the file */
426   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
427     goto fail;
428   oasys->symbol_string_length = 0;
429   /* Inspect the records, but only keep the section info -
430      remember the size of the symbols
431      */
432   oasys->first_data_record = 0;
433   while (loop)
434     {
435       oasys_record_union_type record;
436       if (! oasys_read_record (abfd, &record))
437         goto fail;
438       if ((size_t) record.header.length < (size_t) sizeof (record.header))
439         goto fail;
440
441
442       switch ((oasys_record_enum_type) (record.header.type))
443         {
444         case oasys_record_is_header_enum:
445           had_usefull = true;
446           break;
447         case oasys_record_is_symbol_enum:
448         case oasys_record_is_local_enum:
449           /* Count symbols and remember their size for a future malloc   */
450           abfd->symcount++;
451           oasys->symbol_string_length += 1 + oasys_string_length (&record);
452           had_usefull = true;
453           break;
454         case oasys_record_is_section_enum:
455           {
456             asection *s;
457             char *buffer;
458             unsigned int section_number;
459             if (record.section.header.length != sizeof (record.section))
460               {
461                 goto fail;
462               }
463             buffer = bfd_alloc (abfd, 3);
464             if (!buffer)
465               {
466                 bfd_set_error (bfd_error_no_memory);
467                 goto fail;
468               }
469             section_number = record.section.relb & RELOCATION_SECT_BITS;
470             sprintf (buffer, "%u", section_number);
471             s = bfd_make_section (abfd, buffer);
472             oasys->sections[section_number] = s;
473             switch (record.section.relb & RELOCATION_TYPE_BITS)
474               {
475               case RELOCATION_TYPE_ABS:
476               case RELOCATION_TYPE_REL:
477                 break;
478               case RELOCATION_TYPE_UND:
479               case RELOCATION_TYPE_COM:
480                 BFD_FAIL ();
481               }
482
483             s->_raw_size = bfd_h_get_32 (abfd, record.section.value);
484             s->vma = bfd_h_get_32 (abfd, record.section.vma);
485             s->flags = 0;
486             had_usefull = true;
487           }
488           break;
489         case oasys_record_is_data_enum:
490           oasys->first_data_record = bfd_tell (abfd) - record.header.length;
491         case oasys_record_is_debug_enum:
492         case oasys_record_is_module_enum:
493         case oasys_record_is_named_section_enum:
494         case oasys_record_is_end_enum:
495           if (had_usefull == false)
496             goto fail;
497           loop = false;
498           break;
499         default:
500           goto fail;
501         }
502     }
503   oasys->symbols = (asymbol *) NULL;
504   /*
505     Oasys support several architectures, but I can't see a simple way
506     to discover which one is in a particular file - we'll guess
507     */
508   bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
509   if (abfd->symcount != 0)
510     {
511       abfd->flags |= HAS_SYMS;
512     }
513
514   /*
515     We don't know if a section has data until we've read it..
516     */
517
518   oasys_slurp_section_data (abfd);
519
520
521   return abfd->xvec;
522
523 fail:
524   (void) bfd_release (abfd, oasys);
525   abfd->tdata.oasys_obj_data = save;
526   return (const bfd_target *) NULL;
527 }
528
529
530 static void
531 oasys_get_symbol_info (ignore_abfd, symbol, ret)
532      bfd *ignore_abfd;
533      asymbol *symbol;
534      symbol_info *ret;
535 {
536   bfd_symbol_info (symbol, ret);
537   if (!symbol->section)
538     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
539 }
540
541 static void
542 oasys_print_symbol (ignore_abfd, afile, symbol, how)
543      bfd *ignore_abfd;
544      PTR afile;
545      asymbol *symbol;
546      bfd_print_symbol_type how;
547 {
548   FILE *file = (FILE *) afile;
549
550   switch (how)
551     {
552     case bfd_print_symbol_name:
553     case bfd_print_symbol_more:
554       fprintf (file, "%s", symbol->name);
555       break;
556     case bfd_print_symbol_all:
557       {
558         CONST char *section_name = symbol->section == (asection *) NULL ?
559         (CONST char *) "*abs" : symbol->section->name;
560
561         bfd_print_symbol_vandf ((PTR) file, symbol);
562
563         fprintf (file, " %-5s %s",
564                  section_name,
565                  symbol->name);
566       }
567       break;
568     }
569 }
570 /*
571  The howto table is build using the top two bits of a reloc byte to
572  index into it. The bits are PCREL,WORD/LONG
573 */
574 static reloc_howto_type howto_table[] =
575 {
576
577   HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false),
578   HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false),
579   HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false),
580   HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false)
581 };
582
583 /* Read in all the section data and relocation stuff too */
584 static boolean
585 oasys_slurp_section_data (abfd)
586      bfd *CONST abfd;
587 {
588   oasys_record_union_type record;
589   oasys_data_type *data = OASYS_DATA (abfd);
590   boolean loop = true;
591
592   oasys_per_section_type *per;
593
594   asection *s;
595
596   /* See if the data has been slurped already .. */
597   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
598     {
599       per = oasys_per_section (s);
600       if (per->initialized == true)
601         return true;
602     }
603
604   if (data->first_data_record == 0)
605     return true;
606
607   if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
608     return false;
609   while (loop)
610     {
611       if (! oasys_read_record (abfd, &record))
612         return false;
613       switch (record.header.type)
614         {
615         case oasys_record_is_header_enum:
616           break;
617         case oasys_record_is_data_enum:
618           {
619
620             bfd_byte *src = record.data.data;
621             bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
622             bfd_byte *dst_ptr;
623             bfd_byte *dst_base_ptr;
624             unsigned int relbit;
625             unsigned int count;
626             asection *section =
627             data->sections[record.data.relb & RELOCATION_SECT_BITS];
628             bfd_vma dst_offset;
629
630             per = oasys_per_section (section);
631
632             if (per->initialized == false)
633               {
634                 per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size);
635                 if (!per->data)
636                   {
637                     bfd_set_error (bfd_error_no_memory);
638                     return false;
639                   }
640                 per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation);
641                 per->had_vma = false;
642                 per->initialized = true;
643                 section->reloc_count = 0;
644                 section->flags = SEC_ALLOC;
645               }
646
647             dst_offset = bfd_h_get_32 (abfd, record.data.addr);
648             if (per->had_vma == false)
649               {
650                 /* Take the first vma we see as the base */
651                 section->vma = dst_offset;
652                 per->had_vma = true;
653               }
654
655             dst_offset -= section->vma;
656
657             dst_base_ptr = oasys_per_section (section)->data;
658             dst_ptr = oasys_per_section (section)->data +
659               dst_offset;
660
661             if (src < end_src)
662               {
663                 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
664               }
665             while (src < end_src)
666               {
667                 unsigned char mod_byte = *src++;
668                 size_t gap = end_src - src;
669
670                 count = 8;
671                 if (mod_byte == 0 && gap >= 8)
672                   {
673                     dst_ptr[0] = src[0];
674                     dst_ptr[1] = src[1];
675                     dst_ptr[2] = src[2];
676                     dst_ptr[3] = src[3];
677                     dst_ptr[4] = src[4];
678                     dst_ptr[5] = src[5];
679                     dst_ptr[6] = src[6];
680                     dst_ptr[7] = src[7];
681                     dst_ptr += 8;
682                     src += 8;
683                   }
684                 else
685                   {
686                     for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
687                       {
688                         if (relbit & mod_byte)
689                           {
690                             unsigned char reloc = *src;
691                             /* This item needs to be relocated */
692                             switch (reloc & RELOCATION_TYPE_BITS)
693                               {
694                               case RELOCATION_TYPE_ABS:
695
696                                 break;
697
698                               case RELOCATION_TYPE_REL:
699                                 {
700                                   /* Relocate the item relative to the section */
701                                   oasys_reloc_type *r =
702                                   (oasys_reloc_type *)
703                                   bfd_alloc (abfd,
704                                              sizeof (oasys_reloc_type));
705                                   if (!r)
706                                     {
707                                       bfd_set_error (bfd_error_no_memory);
708                                       return false;
709                                     }
710                                   *(per->reloc_tail_ptr) = r;
711                                   per->reloc_tail_ptr = &r->next;
712                                   r->next = (oasys_reloc_type *) NULL;
713                                   /* Reference to undefined symbol */
714                                   src++;
715                                   /* There is no symbol */
716                                   r->symbol = 0;
717                                   /* Work out the howto */
718                                   abort ();
719 #if 0
720                                   r->relent.section =
721                                     data->sections[reloc &
722                                                    RELOCATION_SECT_BITS];
723
724                                   r->relent.addend = -
725                                     r->relent.section->vma;
726 #endif
727                                   r->relent.address = dst_ptr - dst_base_ptr;
728                                   r->relent.howto = &howto_table[reloc >> 6];
729                                   r->relent.sym_ptr_ptr = (asymbol **) NULL;
730                                   section->reloc_count++;
731
732                                   /* Fake up the data to look like it's got the -ve pc in it, this makes
733                                        it much easier to convert into other formats. This is done by
734                                        hitting the addend.
735                                        */
736                                   if (r->relent.howto->pc_relative == true)
737                                     {
738                                       r->relent.addend -= dst_ptr - dst_base_ptr;
739                                     }
740
741
742                                 }
743                                 break;
744
745
746                               case RELOCATION_TYPE_UND:
747                                 {
748                                   oasys_reloc_type *r =
749                                   (oasys_reloc_type *)
750                                   bfd_alloc (abfd,
751                                              sizeof (oasys_reloc_type));
752                                   if (!r)
753                                     {
754                                       bfd_set_error (bfd_error_no_memory);
755                                       return false;
756                                     }
757                                   *(per->reloc_tail_ptr) = r;
758                                   per->reloc_tail_ptr = &r->next;
759                                   r->next = (oasys_reloc_type *) NULL;
760                                   /* Reference to undefined symbol */
761                                   src++;
762                                   /* Get symbol number */
763                                   r->symbol = (src[0] << 8) | src[1];
764                                   /* Work out the howto */
765                                   abort ();
766
767 #if 0
768                                   r->relent.section = (asection
769                                                        *) NULL;
770 #endif
771                                   r->relent.addend = 0;
772                                   r->relent.address = dst_ptr - dst_base_ptr;
773                                   r->relent.howto = &howto_table[reloc >> 6];
774                                   r->relent.sym_ptr_ptr = (asymbol **) NULL;
775                                   section->reloc_count++;
776
777                                   src += 2;
778                                   /* Fake up the data to look like it's got the -ve pc in it, this makes
779                                        it much easier to convert into other formats. This is done by
780                                        hitting the addend.
781                                        */
782                                   if (r->relent.howto->pc_relative == true)
783                                     {
784                                       r->relent.addend -= dst_ptr - dst_base_ptr;
785                                     }
786
787
788
789                                 }
790                                 break;
791                               case RELOCATION_TYPE_COM:
792                                 BFD_FAIL ();
793                               }
794                           }
795                         *dst_ptr++ = *src++;
796                       }
797                   }
798               }
799           }
800           break;
801         case oasys_record_is_local_enum:
802         case oasys_record_is_symbol_enum:
803         case oasys_record_is_section_enum:
804           break;
805         default:
806           loop = false;
807         }
808     }
809
810   return true;
811
812 }
813
814 static boolean
815 oasys_new_section_hook (abfd, newsect)
816      bfd *abfd;
817      asection *newsect;
818 {
819   newsect->used_by_bfd = (PTR)
820     bfd_alloc (abfd, sizeof (oasys_per_section_type));
821   if (!newsect->used_by_bfd)
822     {
823       bfd_set_error (bfd_error_no_memory);
824       return false;
825     }
826   oasys_per_section (newsect)->data = (bfd_byte *) NULL;
827   oasys_per_section (newsect)->section = newsect;
828   oasys_per_section (newsect)->offset = 0;
829   oasys_per_section (newsect)->initialized = false;
830   newsect->alignment_power = 1;
831   /* Turn the section string into an index */
832
833   sscanf (newsect->name, "%u", &newsect->target_index);
834
835   return true;
836 }
837
838
839 static long
840 oasys_get_reloc_upper_bound (abfd, asect)
841      bfd *abfd;
842      sec_ptr asect;
843 {
844   if (! oasys_slurp_section_data (abfd))
845     return -1;
846   return (asect->reloc_count + 1) * sizeof (arelent *);
847 }
848
849 static boolean
850 oasys_get_section_contents (abfd, section, location, offset, count)
851      bfd *abfd;
852      sec_ptr section;
853      PTR location;
854      file_ptr offset;
855      bfd_size_type count;
856 {
857   oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
858   oasys_slurp_section_data (abfd);
859   if (p->initialized == false)
860     {
861       (void) memset (location, 0, (int) count);
862     }
863   else
864     {
865       (void) memcpy (location, (PTR) (p->data + offset), (int) count);
866     }
867   return true;
868 }
869
870
871 long
872 oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
873      bfd *ignore_abfd;
874      sec_ptr section;
875      arelent **relptr;
876      asymbol **symbols;
877 {
878   unsigned int reloc_count = 0;
879   oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
880   while (src != (oasys_reloc_type *) NULL)
881     {
882       abort ();
883
884 #if 0
885       if (src->relent.section == (asection *) NULL)
886         {
887           src->relent.sym_ptr_ptr = symbols + src->symbol;
888         }
889 #endif
890
891       *relptr++ = &src->relent;
892       src = src->next;
893       reloc_count++;
894     }
895   *relptr = (arelent *) NULL;
896   return section->reloc_count = reloc_count;
897 }
898
899
900
901
902 /* Writing */
903
904
905 /* Calculate the checksum and write one record */
906 static boolean
907 oasys_write_record (abfd, type, record, size)
908      bfd *abfd;
909      oasys_record_enum_type type;
910      oasys_record_union_type *record;
911      size_t size;
912 {
913   int checksum;
914   size_t i;
915   unsigned char *ptr;
916
917   record->header.length = size;
918   record->header.type = (int) type;
919   record->header.check_sum = 0;
920   record->header.fill = 0;
921   ptr = (unsigned char *) &record->pad[0];
922   checksum = 0;
923   for (i = 0; i < size; i++)
924     {
925       checksum += *ptr++;
926     }
927   record->header.check_sum = 0xff & (-checksum);
928   if (bfd_write ((PTR) record, 1, size, abfd) != size)
929     return false;
930   return true;
931 }
932
933
934 /* Write out all the symbols */
935 static boolean
936 oasys_write_syms (abfd)
937      bfd *abfd;
938 {
939   unsigned int count;
940   asymbol **generic = bfd_get_outsymbols (abfd);
941   unsigned int index = 0;
942   for (count = 0; count < bfd_get_symcount (abfd); count++)
943     {
944
945       oasys_symbol_record_type symbol;
946       asymbol *CONST g = generic[count];
947
948       CONST char *src = g->name;
949       char *dst = symbol.name;
950       unsigned int l = 0;
951
952       if (bfd_is_com_section (g->section))
953         {
954           symbol.relb = RELOCATION_TYPE_COM;
955           bfd_h_put_16 (abfd, index, symbol.refno);
956           index++;
957         }
958       else if (bfd_is_abs_section (g->section))
959         {
960           symbol.relb = RELOCATION_TYPE_ABS;
961           bfd_h_put_16 (abfd, 0, symbol.refno);
962
963         }
964       else if (bfd_is_und_section (g->section))
965         {
966           symbol.relb = RELOCATION_TYPE_UND;
967           bfd_h_put_16 (abfd, index, symbol.refno);
968           /* Overload the value field with the output index number */
969           index++;
970         }
971       else if (g->flags & BSF_DEBUGGING)
972         {
973           /* throw it away */
974           continue;
975         }
976       else
977         {
978           if (g->section == (asection *) NULL)
979             {
980               /* Sometime, the oasys tools give out a symbol with illegal
981            bits in it, we'll output it in the same broken way */
982
983               symbol.relb = RELOCATION_TYPE_REL | 0;
984             }
985           else
986             {
987               symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
988             }
989           bfd_h_put_16 (abfd, 0, symbol.refno);
990         }
991 #ifdef UNDERSCORE_HACK
992       if (src[l] == '_')
993         dst[l++] = '.';
994 #endif
995       while (src[l])
996         {
997           dst[l] = src[l];
998           l++;
999         }
1000
1001       bfd_h_put_32 (abfd, g->value, symbol.value);
1002
1003
1004       if (g->flags & BSF_LOCAL)
1005         {
1006           if (! oasys_write_record (abfd,
1007                                     oasys_record_is_local_enum,
1008                                     (oasys_record_union_type *) & symbol,
1009                                     offsetof (oasys_symbol_record_type,
1010                                               name[0]) + l))
1011             return false;
1012         }
1013       else
1014         {
1015           if (! oasys_write_record (abfd,
1016                                     oasys_record_is_symbol_enum,
1017                                     (oasys_record_union_type *) & symbol,
1018                                     offsetof (oasys_symbol_record_type,
1019                                               name[0]) + l))
1020             return false;
1021         }
1022       g->value = index - 1;
1023     }
1024
1025   return true;
1026 }
1027
1028
1029  /* Write a section header for each section */
1030 static boolean
1031 oasys_write_sections (abfd)
1032      bfd *abfd;
1033 {
1034   asection *s;
1035   static oasys_section_record_type out;
1036
1037   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
1038     {
1039       if (!isdigit (s->name[0]))
1040         {
1041           bfd_set_error (bfd_error_nonrepresentable_section);
1042           return false;
1043         }
1044       out.relb = RELOCATION_TYPE_REL | s->target_index;
1045       bfd_h_put_32 (abfd, s->_cooked_size, out.value);
1046       bfd_h_put_32 (abfd, s->vma, out.vma);
1047
1048       if (! oasys_write_record (abfd,
1049                                 oasys_record_is_section_enum,
1050                                 (oasys_record_union_type *) & out,
1051                                 sizeof (out)))
1052         return false;
1053     }
1054   return true;
1055 }
1056
1057 static boolean
1058 oasys_write_header (abfd)
1059      bfd *abfd;
1060 {
1061   /* Create and write the header */
1062   oasys_header_record_type r;
1063   size_t length = strlen (abfd->filename);
1064   if (length > (size_t) sizeof (r.module_name))
1065     {
1066       length = sizeof (r.module_name);
1067     }
1068
1069   (void) memcpy (r.module_name,
1070                  abfd->filename,
1071                  length);
1072   (void) memset (r.module_name + length,
1073                  ' ',
1074                  sizeof (r.module_name) - length);
1075
1076   r.version_number = OASYS_VERSION_NUMBER;
1077   r.rev_number = OASYS_REV_NUMBER;
1078   if (! oasys_write_record (abfd,
1079                             oasys_record_is_header_enum,
1080                             (oasys_record_union_type *) & r,
1081                             offsetof (oasys_header_record_type,
1082                                       description[0])))
1083     return false;
1084
1085   return true;
1086 }
1087
1088 static boolean
1089 oasys_write_end (abfd)
1090      bfd *abfd;
1091 {
1092   oasys_end_record_type end;
1093   unsigned char null = 0;
1094   end.relb = RELOCATION_TYPE_ABS;
1095   bfd_h_put_32 (abfd, abfd->start_address, end.entry);
1096   bfd_h_put_16 (abfd, 0, end.fill);
1097   end.zero = 0;
1098   if (! oasys_write_record (abfd,
1099                             oasys_record_is_end_enum,
1100                             (oasys_record_union_type *) & end,
1101                             sizeof (end)))
1102     return false;
1103   if (bfd_write ((PTR) & null, 1, 1, abfd) != 1)
1104     return false;
1105   return true;
1106 }
1107
1108 static int
1109 comp (ap, bp)
1110      CONST PTR ap;
1111      CONST PTR bp;
1112 {
1113   arelent *a = *((arelent **) ap);
1114   arelent *b = *((arelent **) bp);
1115   return a->address - b->address;
1116 }
1117
1118 /*
1119  Writing data..
1120
1121 */
1122 static boolean
1123 oasys_write_data (abfd)
1124      bfd *abfd;
1125 {
1126   asection *s;
1127   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
1128     {
1129       if (s->flags & SEC_LOAD)
1130         {
1131           bfd_byte *raw_data = oasys_per_section (s)->data;
1132           oasys_data_record_type processed_data;
1133           bfd_size_type current_byte_index = 0;
1134           unsigned int relocs_to_go = s->reloc_count;
1135           arelent **p = s->orelocation;
1136           if (s->reloc_count != 0)
1137             {
1138 /* Sort the reloc records so it's easy to insert the relocs into the
1139            data */
1140
1141               qsort (s->orelocation,
1142                      s->reloc_count,
1143                      sizeof (arelent **),
1144                      comp);
1145             }
1146           current_byte_index = 0;
1147           processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
1148
1149           while (current_byte_index < s->_cooked_size)
1150             {
1151               /* Scan forwards by eight bytes or however much is left and see if
1152                there are any relocations going on */
1153               bfd_byte *mod = &processed_data.data[0];
1154               bfd_byte *dst = &processed_data.data[1];
1155
1156               unsigned int i = 0;
1157               *mod = 0;
1158
1159
1160               bfd_h_put_32 (abfd, s->vma + current_byte_index,
1161                             processed_data.addr);
1162
1163               /* Don't start a relocation unless you're sure you can finish it
1164                within the same data record.  The worst case relocation is a
1165                4-byte relocatable value which is split across two modification
1166                bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
1167                1 modification byte + 2 data = 8 bytes total).  That's where
1168                the magic number 8 comes from.
1169             */
1170               while (current_byte_index < s->_raw_size && dst <=
1171                      &processed_data.data[sizeof (processed_data.data) - 8])
1172                 {
1173
1174
1175                   if (relocs_to_go != 0)
1176                     {
1177                       arelent *r = *p;
1178                       reloc_howto_type *const how = r->howto;
1179                       /* There is a relocation, is it for this byte ? */
1180                       if (r->address == current_byte_index)
1181                         {
1182                           unsigned char rel_byte;
1183
1184                           p++;
1185                           relocs_to_go--;
1186
1187                           *mod |= (1 << i);
1188                           if (how->pc_relative)
1189                             {
1190                               rel_byte = RELOCATION_PCREL_BIT;
1191
1192                               /* Also patch the raw data so that it doesn't have
1193                          the -ve stuff any more */
1194                               if (how->size != 2)
1195                                 {
1196                                   bfd_put_16 (abfd,
1197                                               bfd_get_16 (abfd, raw_data) +
1198                                               current_byte_index, raw_data);
1199                                 }
1200
1201                               else
1202                                 {
1203                                   bfd_put_32 (abfd,
1204                                               bfd_get_32 (abfd, raw_data) +
1205                                               current_byte_index, raw_data);
1206                                 }
1207                             }
1208                           else
1209                             {
1210                               rel_byte = 0;
1211                             }
1212                           if (how->size == 2)
1213                             {
1214                               rel_byte |= RELOCATION_32BIT_BIT;
1215                             }
1216
1217                           /* Is this a section relative relocation, or a symbol
1218                        relative relocation ? */
1219                           abort ();
1220
1221 #if 0
1222                           if (r->section != (asection *) NULL)
1223                             {
1224                               /* The relent has a section attached, so it must be section
1225                              relative */
1226                               rel_byte |= RELOCATION_TYPE_REL;
1227                               rel_byte |= r->section->output_section->target_index;
1228                               *dst++ = rel_byte;
1229                             }
1230                           else
1231 #endif
1232                             {
1233                               asymbol *p = *(r->sym_ptr_ptr);
1234
1235                               /* If this symbol has a section attached, then it
1236                              has already been resolved.  Change from a symbol
1237                              ref to a section ref */
1238                               if (p->section != (asection *) NULL)
1239                                 {
1240                                   rel_byte |= RELOCATION_TYPE_REL;
1241                                   rel_byte |=
1242                                     p->section->output_section->target_index;
1243                                   *dst++ = rel_byte;
1244                                 }
1245                               else
1246                                 {
1247                                   rel_byte |= RELOCATION_TYPE_UND;
1248                                   *dst++ = rel_byte;
1249                                   /* Next two bytes are a symbol index - we can get
1250                                this from the symbol value which has been zapped
1251                                into the symbol index in the table when the
1252                                symbol table was written
1253                                */
1254                                   *dst++ = p->value >> 8;
1255                                   *dst++ = p->value;
1256                                 }
1257                             }
1258 #define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
1259                           /* relocations never occur from an unloadable section,
1260                        so we can assume that raw_data is not NULL
1261                      */
1262                           *dst++ = *raw_data++;
1263                           ADVANCE
1264                             * dst++ = *raw_data++;
1265                           ADVANCE
1266                             if (how->size == 2)
1267                             {
1268                               *dst++ = *raw_data++;
1269                               ADVANCE
1270                                 * dst++ = *raw_data++;
1271                               ADVANCE
1272                             }
1273                           continue;
1274                         }
1275                     }
1276                   /* If this is coming from an unloadable section then copy
1277                    zeros */
1278                   if (raw_data == NULL)
1279                     {
1280                       *dst++ = 0;
1281                     }
1282                   else
1283                     {
1284                       *dst++ = *raw_data++;
1285                     }
1286                   ADVANCE
1287                 }
1288
1289               /* Don't write a useless null modification byte */
1290               if (dst == mod + 1)
1291                 {
1292                   --dst;
1293                 }
1294
1295               if (! oasys_write_record (abfd,
1296                                         oasys_record_is_data_enum,
1297                                         ((oasys_record_union_type *)
1298                                          & processed_data),
1299                                         dst - (bfd_byte *) & processed_data))
1300                 return false;
1301             }
1302         }
1303     }
1304
1305   return true;
1306 }
1307
1308 static boolean
1309 oasys_write_object_contents (abfd)
1310      bfd *abfd;
1311 {
1312   if (! oasys_write_header (abfd))
1313     return false;
1314   if (! oasys_write_syms (abfd))
1315     return false;
1316   if (! oasys_write_sections (abfd))
1317     return false;
1318   if (! oasys_write_data (abfd))
1319     return false;
1320   if (! oasys_write_end (abfd))
1321     return false;
1322   return true;
1323 }
1324
1325
1326
1327
1328 /** exec and core file sections */
1329
1330 /* set section contents is complicated with OASYS since the format is
1331 * not a byte image, but a record stream.
1332 */
1333 static boolean
1334 oasys_set_section_contents (abfd, section, location, offset, count)
1335      bfd *abfd;
1336      sec_ptr section;
1337      PTR location;
1338      file_ptr offset;
1339      bfd_size_type count;
1340 {
1341   if (count != 0)
1342     {
1343       if (oasys_per_section (section)->data == (bfd_byte *) NULL)
1344         {
1345           oasys_per_section (section)->data =
1346             (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size));
1347           if (!oasys_per_section (section)->data)
1348             {
1349               bfd_set_error (bfd_error_no_memory);
1350               return false;
1351             }
1352         }
1353       (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
1354                      location,
1355                      (size_t) count);
1356     }
1357   return true;
1358 }
1359
1360
1361
1362 /* Native-level interface to symbols. */
1363
1364 /* We read the symbols into a buffer, which is discarded when this
1365 function exits.  We read the strings into a buffer large enough to
1366 hold them all plus all the cached symbol entries. */
1367
1368 static asymbol *
1369 oasys_make_empty_symbol (abfd)
1370      bfd *abfd;
1371 {
1372
1373   oasys_symbol_type *new =
1374   (oasys_symbol_type *) bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1375   if (!new)
1376     {
1377       bfd_set_error (bfd_error_no_memory);
1378       return NULL;
1379     }
1380   new->symbol.the_bfd = abfd;
1381   return &new->symbol;
1382 }
1383 \f
1384
1385
1386
1387 /* User should have checked the file flags; perhaps we should return
1388 BFD_NO_MORE_SYMBOLS if there are none? */
1389
1390 static bfd *
1391 oasys_openr_next_archived_file (arch, prev)
1392      bfd *arch;
1393      bfd *prev;
1394 {
1395   oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
1396   oasys_module_info_type *p;
1397   /* take the next one from the arch state, or reset */
1398   if (prev == (bfd *) NULL)
1399     {
1400       /* Reset the index - the first two entries are bogus*/
1401       ar->module_index = 0;
1402     }
1403
1404   p = ar->module + ar->module_index;
1405   ar->module_index++;
1406
1407   if (ar->module_index <= ar->module_count)
1408     {
1409       if (p->abfd == (bfd *) NULL)
1410         {
1411           p->abfd = _bfd_create_empty_archive_element_shell (arch);
1412           p->abfd->origin = p->pos;
1413           p->abfd->filename = p->name;
1414
1415           /* Fixup a pointer to this element for the member */
1416           p->abfd->arelt_data = (PTR) p;
1417         }
1418       return p->abfd;
1419     }
1420   else
1421     {
1422       bfd_set_error (bfd_error_no_more_archived_files);
1423       return (bfd *) NULL;
1424     }
1425 }
1426
1427 static boolean
1428 oasys_find_nearest_line (abfd,
1429                          section,
1430                          symbols,
1431                          offset,
1432                          filename_ptr,
1433                          functionname_ptr,
1434                          line_ptr)
1435      bfd *abfd;
1436      asection *section;
1437      asymbol **symbols;
1438      bfd_vma offset;
1439      char **filename_ptr;
1440      char **functionname_ptr;
1441      unsigned int *line_ptr;
1442 {
1443   return false;
1444
1445 }
1446
1447 static int
1448 oasys_generic_stat_arch_elt (abfd, buf)
1449      bfd *abfd;
1450      struct stat *buf;
1451 {
1452   oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1453   if (mod == (oasys_module_info_type *) NULL)
1454     {
1455       bfd_set_error (bfd_error_invalid_operation);
1456       return -1;
1457     }
1458   else
1459     {
1460       buf->st_size = mod->size;
1461       buf->st_mode = 0666;
1462       return 0;
1463     }
1464 }
1465
1466 static int
1467 oasys_sizeof_headers (abfd, exec)
1468      bfd *abfd;
1469      boolean exec;
1470 {
1471   return 0;
1472 }
1473
1474 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
1475 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1476
1477 #define oasys_slurp_armap bfd_true
1478 #define oasys_slurp_extended_name_table bfd_true
1479 #define oasys_construct_extended_name_table \
1480   ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
1481    bfd_true)
1482 #define oasys_truncate_arname bfd_dont_truncate_arname
1483 #define oasys_write_armap \
1484   ((boolean (*) \
1485     PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
1486    bfd_true)
1487 #define oasys_update_armap_timestamp bfd_true
1488
1489 #define oasys_bfd_is_local_label bfd_generic_is_local_label
1490 #define oasys_get_lineno _bfd_nosymbols_get_lineno
1491 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1492 #define oasys_read_minisymbols _bfd_generic_read_minisymbols
1493 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1494
1495 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1496
1497 #define oasys_set_arch_mach bfd_default_set_arch_mach
1498
1499 #define oasys_bfd_get_relocated_section_contents \
1500   bfd_generic_get_relocated_section_contents
1501 #define oasys_bfd_relax_section bfd_generic_relax_section
1502 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1503 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1504 #define oasys_bfd_final_link _bfd_generic_final_link
1505 #define oasys_bfd_link_split_section _bfd_generic_link_split_section
1506
1507 /*SUPPRESS 460 */
1508 const bfd_target oasys_vec =
1509 {
1510   "oasys",                      /* name */
1511   bfd_target_oasys_flavour,
1512   true,                         /* target byte order */
1513   true,                         /* target headers byte order */
1514   (HAS_RELOC | EXEC_P |         /* object flags */
1515    HAS_LINENO | HAS_DEBUG |
1516    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1517   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1518    | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1519   0,                            /* leading underscore */
1520   ' ',                          /* ar_pad_char */
1521   16,                           /* ar_max_namelen */
1522   1,                            /* minimum alignment */
1523   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1524   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1525   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
1526   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1527   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1528   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
1529
1530   {_bfd_dummy_target,
1531    oasys_object_p,              /* bfd_check_format */
1532    oasys_archive_p,
1533    _bfd_dummy_target,
1534   },
1535   {                             /* bfd_set_format */
1536     bfd_false,
1537     oasys_mkobject,
1538     _bfd_generic_mkarchive,
1539     bfd_false
1540   },
1541   {                             /* bfd_write_contents */
1542     bfd_false,
1543     oasys_write_object_contents,
1544     _bfd_write_archive_contents,
1545     bfd_false,
1546   },
1547
1548   BFD_JUMP_TABLE_GENERIC (oasys),
1549   BFD_JUMP_TABLE_COPY (_bfd_generic),
1550   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1551   BFD_JUMP_TABLE_ARCHIVE (oasys),
1552   BFD_JUMP_TABLE_SYMBOLS (oasys),
1553   BFD_JUMP_TABLE_RELOCS (oasys),
1554   BFD_JUMP_TABLE_WRITE (oasys),
1555   BFD_JUMP_TABLE_LINK (oasys),
1556   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1557
1558   (PTR) 0
1559 };