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