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