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