bfd/
[deliverable/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,
157090f7 3 2002, 2003, 2004, 2005, 2006, 2007 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
252b5132 23#include "sysdep.h"
3db64b00 24#include "bfd.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 {
6edfbbad
DJ
387 arelent **relpp;
388
116c20d2 389 per->data = bfd_zalloc (abfd, section->size);
252b5132 390 if (!per->data)
b34976b6 391 return FALSE;
6edfbbad
DJ
392 relpp = &section->relocation;
393 per->reloc_tail_ptr = (oasys_reloc_type **) relpp;
b34976b6
AM
394 per->had_vma = FALSE;
395 per->initialized = TRUE;
252b5132
RH
396 section->reloc_count = 0;
397 section->flags = SEC_ALLOC;
398 }
399
dc810e39 400 dst_offset = H_GET_32 (abfd, record.data.addr);
82e51918 401 if (! per->had_vma)
252b5132 402 {
116c20d2 403 /* Take the first vma we see as the base. */
252b5132 404 section->vma = dst_offset;
b34976b6 405 per->had_vma = TRUE;
252b5132
RH
406 }
407
408 dst_offset -= section->vma;
409
410 dst_base_ptr = oasys_per_section (section)->data;
411 dst_ptr = oasys_per_section (section)->data +
412 dst_offset;
413
414 if (src < end_src)
116c20d2
NC
415 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
416
252b5132
RH
417 while (src < end_src)
418 {
419 unsigned char mod_byte = *src++;
420 size_t gap = end_src - src;
421
422 count = 8;
423 if (mod_byte == 0 && gap >= 8)
424 {
425 dst_ptr[0] = src[0];
426 dst_ptr[1] = src[1];
427 dst_ptr[2] = src[2];
428 dst_ptr[3] = src[3];
429 dst_ptr[4] = src[4];
430 dst_ptr[5] = src[5];
431 dst_ptr[6] = src[6];
432 dst_ptr[7] = src[7];
433 dst_ptr += 8;
434 src += 8;
435 }
436 else
437 {
438 for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
439 {
440 if (relbit & mod_byte)
441 {
442 unsigned char reloc = *src;
116c20d2 443 /* This item needs to be relocated. */
252b5132
RH
444 switch (reloc & RELOCATION_TYPE_BITS)
445 {
446 case RELOCATION_TYPE_ABS:
252b5132
RH
447 break;
448
449 case RELOCATION_TYPE_REL:
450 {
116c20d2 451 /* Relocate the item relative to the section. */
dc810e39
AM
452 oasys_reloc_type *r;
453
454 amt = sizeof (oasys_reloc_type);
116c20d2 455 r = bfd_alloc (abfd, amt);
252b5132 456 if (!r)
b34976b6 457 return FALSE;
252b5132
RH
458 *(per->reloc_tail_ptr) = r;
459 per->reloc_tail_ptr = &r->next;
116c20d2
NC
460 r->next = NULL;
461 /* Reference to undefined symbol. */
252b5132 462 src++;
116c20d2 463 /* There is no symbol. */
252b5132 464 r->symbol = 0;
116c20d2 465 /* Work out the howto. */
252b5132 466 abort ();
252b5132
RH
467 r->relent.address = dst_ptr - dst_base_ptr;
468 r->relent.howto = &howto_table[reloc >> 6];
116c20d2 469 r->relent.sym_ptr_ptr = NULL;
252b5132
RH
470 section->reloc_count++;
471
82e51918
AM
472 /* Fake up the data to look like
473 it's got the -ve pc in it, this
474 makes it much easier to convert
475 into other formats. This is done
476 by hitting the addend. */
477 if (r->relent.howto->pc_relative)
478 r->relent.addend -= dst_ptr - dst_base_ptr;
252b5132
RH
479 }
480 break;
481
252b5132
RH
482 case RELOCATION_TYPE_UND:
483 {
dc810e39
AM
484 oasys_reloc_type *r;
485
486 amt = sizeof (oasys_reloc_type);
116c20d2 487 r = bfd_alloc (abfd, amt);
252b5132 488 if (!r)
b34976b6 489 return FALSE;
252b5132
RH
490 *(per->reloc_tail_ptr) = r;
491 per->reloc_tail_ptr = &r->next;
116c20d2
NC
492 r->next = NULL;
493 /* Reference to undefined symbol. */
252b5132 494 src++;
116c20d2 495 /* Get symbol number. */
252b5132 496 r->symbol = (src[0] << 8) | src[1];
116c20d2 497 /* Work out the howto. */
252b5132
RH
498 abort ();
499
252b5132
RH
500 r->relent.addend = 0;
501 r->relent.address = dst_ptr - dst_base_ptr;
502 r->relent.howto = &howto_table[reloc >> 6];
116c20d2 503 r->relent.sym_ptr_ptr = NULL;
252b5132
RH
504 section->reloc_count++;
505
506 src += 2;
82e51918
AM
507 /* Fake up the data to look like
508 it's got the -ve pc in it, this
509 makes it much easier to convert
510 into other formats. This is done
511 by hitting the addend. */
512 if (r->relent.howto->pc_relative)
513 r->relent.addend -= dst_ptr - dst_base_ptr;
252b5132
RH
514 }
515 break;
516 case RELOCATION_TYPE_COM:
517 BFD_FAIL ();
518 }
519 }
520 *dst_ptr++ = *src++;
521 }
522 }
523 }
524 }
525 break;
526 case oasys_record_is_local_enum:
527 case oasys_record_is_symbol_enum:
528 case oasys_record_is_section_enum:
529 break;
530 default:
b34976b6 531 loop = FALSE;
252b5132
RH
532 }
533 }
534
b34976b6 535 return TRUE;
252b5132
RH
536
537}
538
116c20d2
NC
539#define MAX_SECS 16
540
541static const bfd_target *
542oasys_object_p (bfd *abfd)
543{
544 oasys_data_type *oasys;
545 oasys_data_type *save = OASYS_DATA (abfd);
546 bfd_boolean loop = TRUE;
547 bfd_boolean had_usefull = FALSE;
548
549 abfd->tdata.oasys_obj_data = 0;
550 oasys_mkobject (abfd);
551 oasys = OASYS_DATA (abfd);
552 memset ((void *) oasys->sections, 0xff, sizeof (oasys->sections));
553
554 /* Point to the start of the file. */
555 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
556 goto fail;
557 oasys->symbol_string_length = 0;
558
559 /* Inspect the records, but only keep the section info -
560 remember the size of the symbols. */
561 oasys->first_data_record = 0;
562 while (loop)
563 {
564 oasys_record_union_type record;
565 if (! oasys_read_record (abfd, &record))
566 goto fail;
567 if ((size_t) record.header.length < (size_t) sizeof (record.header))
568 goto fail;
569
570 switch ((oasys_record_enum_type) (record.header.type))
571 {
572 case oasys_record_is_header_enum:
573 had_usefull = TRUE;
574 break;
575 case oasys_record_is_symbol_enum:
576 case oasys_record_is_local_enum:
577 /* Count symbols and remember their size for a future malloc. */
578 abfd->symcount++;
579 oasys->symbol_string_length += 1 + oasys_string_length (&record);
580 had_usefull = TRUE;
581 break;
582 case oasys_record_is_section_enum:
583 {
584 asection *s;
585 char *buffer;
586 unsigned int section_number;
587
588 if (record.section.header.length != sizeof (record.section))
589 goto fail;
590
591 buffer = bfd_alloc (abfd, (bfd_size_type) 3);
592 if (!buffer)
593 goto fail;
594 section_number = record.section.relb & RELOCATION_SECT_BITS;
595 sprintf (buffer, "%u", section_number);
596 s = bfd_make_section (abfd, buffer);
597 oasys->sections[section_number] = s;
598 switch (record.section.relb & RELOCATION_TYPE_BITS)
599 {
600 case RELOCATION_TYPE_ABS:
601 case RELOCATION_TYPE_REL:
602 break;
603 case RELOCATION_TYPE_UND:
604 case RELOCATION_TYPE_COM:
605 BFD_FAIL ();
606 }
607
608 s->size = H_GET_32 (abfd, record.section.value);
609 s->vma = H_GET_32 (abfd, record.section.vma);
610 s->flags = 0;
611 had_usefull = TRUE;
612 }
613 break;
614 case oasys_record_is_data_enum:
615 oasys->first_data_record = bfd_tell (abfd) - record.header.length;
616 case oasys_record_is_debug_enum:
617 case oasys_record_is_module_enum:
618 case oasys_record_is_named_section_enum:
619 case oasys_record_is_end_enum:
620 if (! had_usefull)
621 goto fail;
622 loop = FALSE;
623 break;
624 default:
625 goto fail;
626 }
627 }
628 oasys->symbols = NULL;
629
630 /* Oasys support several architectures, but I can't see a simple way
631 to discover which one is in a particular file - we'll guess. */
632 bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
633 if (abfd->symcount != 0)
634 abfd->flags |= HAS_SYMS;
635
636 /* We don't know if a section has data until we've read it. */
637 oasys_slurp_section_data (abfd);
638
639 return abfd->xvec;
640
641fail:
642 (void) bfd_release (abfd, oasys);
643 abfd->tdata.oasys_obj_data = save;
644 return NULL;
645}
646
647
648static void
649oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
650 asymbol *symbol,
651 symbol_info *ret)
652{
653 bfd_symbol_info (symbol, ret);
654
655 if (!symbol->section)
656 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
657}
658
659static void
660oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how)
661{
662 FILE *file = (FILE *) afile;
663
664 switch (how)
665 {
666 case bfd_print_symbol_name:
667 case bfd_print_symbol_more:
668 fprintf (file, "%s", symbol->name);
669 break;
670 case bfd_print_symbol_all:
671 {
672 const char *section_name = symbol->section == NULL ?
673 (const char *) "*abs" : symbol->section->name;
674
675 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
676
677 fprintf (file, " %-5s %s",
678 section_name,
679 symbol->name);
680 }
681 break;
682 }
683}
684
b34976b6 685static bfd_boolean
116c20d2 686oasys_new_section_hook (bfd *abfd, asection *newsect)
252b5132 687{
252b5132 688 if (!newsect->used_by_bfd)
f592407e
AM
689 {
690 newsect->used_by_bfd
691 = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
692 if (!newsect->used_by_bfd)
693 return FALSE;
694 }
116c20d2 695 oasys_per_section (newsect)->data = NULL;
252b5132
RH
696 oasys_per_section (newsect)->section = newsect;
697 oasys_per_section (newsect)->offset = 0;
b34976b6 698 oasys_per_section (newsect)->initialized = FALSE;
252b5132 699 newsect->alignment_power = 1;
252b5132 700
116c20d2 701 /* Turn the section string into an index. */
252b5132
RH
702 sscanf (newsect->name, "%u", &newsect->target_index);
703
f592407e 704 return _bfd_generic_new_section_hook (abfd, newsect);
252b5132
RH
705}
706
707
708static long
116c20d2 709oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
252b5132
RH
710{
711 if (! oasys_slurp_section_data (abfd))
712 return -1;
713 return (asect->reloc_count + 1) * sizeof (arelent *);
714}
715
b34976b6 716static bfd_boolean
116c20d2
NC
717oasys_get_section_contents (bfd *abfd,
718 sec_ptr section,
719 void * location,
720 file_ptr offset,
721 bfd_size_type count)
252b5132 722{
68bfbfcc 723 oasys_per_section_type *p = oasys_per_section (section);
116c20d2 724
252b5132 725 oasys_slurp_section_data (abfd);
116c20d2 726
82e51918 727 if (! p->initialized)
116c20d2 728 (void) memset (location, 0, (size_t) count);
252b5132 729 else
116c20d2
NC
730 (void) memcpy (location, (void *) (p->data + offset), (size_t) count);
731
b34976b6 732 return TRUE;
252b5132
RH
733}
734
116c20d2
NC
735static long
736oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
737 sec_ptr section,
738 arelent **relptr,
739 asymbol **symbols ATTRIBUTE_UNUSED)
252b5132
RH
740{
741 unsigned int reloc_count = 0;
742 oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
252b5132 743
116c20d2
NC
744 if (src != NULL)
745 abort ();
746
747 *relptr = NULL;
252b5132
RH
748 return section->reloc_count = reloc_count;
749}
750
751
116c20d2 752/* Writing. */
252b5132 753
116c20d2 754/* Calculate the checksum and write one record. */
252b5132 755
b34976b6 756static bfd_boolean
116c20d2
NC
757oasys_write_record (bfd *abfd,
758 oasys_record_enum_type type,
759 oasys_record_union_type *record,
760 size_t size)
252b5132
RH
761{
762 int checksum;
763 size_t i;
764 unsigned char *ptr;
765
766 record->header.length = size;
767 record->header.type = (int) type;
768 record->header.check_sum = 0;
769 record->header.fill = 0;
770 ptr = (unsigned char *) &record->pad[0];
771 checksum = 0;
772 for (i = 0; i < size; i++)
116c20d2 773 checksum += *ptr++;
252b5132 774 record->header.check_sum = 0xff & (-checksum);
116c20d2 775 if (bfd_bwrite ((void *) record, (bfd_size_type) size, abfd) != size)
b34976b6
AM
776 return FALSE;
777 return TRUE;
252b5132
RH
778}
779
780
116c20d2
NC
781/* Write out all the symbols. */
782
b34976b6 783static bfd_boolean
116c20d2 784oasys_write_syms (bfd *abfd)
252b5132
RH
785{
786 unsigned int count;
787 asymbol **generic = bfd_get_outsymbols (abfd);
788 unsigned int index = 0;
116c20d2 789
252b5132
RH
790 for (count = 0; count < bfd_get_symcount (abfd); count++)
791 {
252b5132 792 oasys_symbol_record_type symbol;
dc810e39 793 asymbol *const g = generic[count];
dc810e39 794 const char *src = g->name;
252b5132
RH
795 char *dst = symbol.name;
796 unsigned int l = 0;
797
798 if (bfd_is_com_section (g->section))
799 {
800 symbol.relb = RELOCATION_TYPE_COM;
dc810e39 801 H_PUT_16 (abfd, index, symbol.refno);
252b5132
RH
802 index++;
803 }
804 else if (bfd_is_abs_section (g->section))
805 {
806 symbol.relb = RELOCATION_TYPE_ABS;
dc810e39 807 H_PUT_16 (abfd, 0, symbol.refno);
252b5132
RH
808 }
809 else if (bfd_is_und_section (g->section))
810 {
811 symbol.relb = RELOCATION_TYPE_UND;
dc810e39 812 H_PUT_16 (abfd, index, symbol.refno);
252b5132
RH
813 /* Overload the value field with the output index number */
814 index++;
815 }
816 else if (g->flags & BSF_DEBUGGING)
116c20d2
NC
817 /* Throw it away. */
818 continue;
252b5132
RH
819 else
820 {
116c20d2
NC
821 if (g->section == NULL)
822 /* Sometime, the oasys tools give out a symbol with illegal
823 bits in it, we'll output it in the same broken way. */
824 symbol.relb = RELOCATION_TYPE_REL | 0;
252b5132 825 else
116c20d2
NC
826 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
827
dc810e39 828 H_PUT_16 (abfd, 0, symbol.refno);
252b5132 829 }
116c20d2 830
252b5132
RH
831#ifdef UNDERSCORE_HACK
832 if (src[l] == '_')
833 dst[l++] = '.';
834#endif
835 while (src[l])
836 {
837 dst[l] = src[l];
838 l++;
839 }
840
dc810e39 841 H_PUT_32 (abfd, g->value, symbol.value);
252b5132 842
252b5132
RH
843 if (g->flags & BSF_LOCAL)
844 {
845 if (! oasys_write_record (abfd,
846 oasys_record_is_local_enum,
847 (oasys_record_union_type *) & symbol,
848 offsetof (oasys_symbol_record_type,
849 name[0]) + l))
b34976b6 850 return FALSE;
252b5132
RH
851 }
852 else
853 {
854 if (! oasys_write_record (abfd,
855 oasys_record_is_symbol_enum,
856 (oasys_record_union_type *) & symbol,
857 offsetof (oasys_symbol_record_type,
858 name[0]) + l))
b34976b6 859 return FALSE;
252b5132
RH
860 }
861 g->value = index - 1;
862 }
863
b34976b6 864 return TRUE;
252b5132
RH
865}
866
116c20d2 867/* Write a section header for each section. */
252b5132 868
b34976b6 869static bfd_boolean
116c20d2 870oasys_write_sections (bfd *abfd)
252b5132
RH
871{
872 asection *s;
873 static oasys_section_record_type out;
874
116c20d2 875 for (s = abfd->sections; s != NULL; s = s->next)
252b5132 876 {
3882b010 877 if (!ISDIGIT (s->name[0]))
252b5132
RH
878 {
879 (*_bfd_error_handler)
880 (_("%s: can not represent section `%s' in oasys"),
881 bfd_get_filename (abfd), s->name);
882 bfd_set_error (bfd_error_nonrepresentable_section);
b34976b6 883 return FALSE;
252b5132
RH
884 }
885 out.relb = RELOCATION_TYPE_REL | s->target_index;
eea6121a 886 H_PUT_32 (abfd, s->size, out.value);
dc810e39 887 H_PUT_32 (abfd, s->vma, out.vma);
252b5132
RH
888
889 if (! oasys_write_record (abfd,
890 oasys_record_is_section_enum,
891 (oasys_record_union_type *) & out,
892 sizeof (out)))
b34976b6 893 return FALSE;
252b5132 894 }
b34976b6 895 return TRUE;
252b5132
RH
896}
897
b34976b6 898static bfd_boolean
116c20d2 899oasys_write_header (bfd *abfd)
252b5132 900{
116c20d2 901 /* Create and write the header. */
252b5132
RH
902 oasys_header_record_type r;
903 size_t length = strlen (abfd->filename);
116c20d2 904
252b5132 905 if (length > (size_t) sizeof (r.module_name))
116c20d2 906 length = sizeof (r.module_name);
252b5132 907
116c20d2
NC
908 (void) memcpy (r.module_name, abfd->filename, length);
909 (void) memset (r.module_name + length, ' ', sizeof (r.module_name) - length);
252b5132
RH
910
911 r.version_number = OASYS_VERSION_NUMBER;
912 r.rev_number = OASYS_REV_NUMBER;
252b5132 913
116c20d2
NC
914 return oasys_write_record (abfd, oasys_record_is_header_enum,
915 (oasys_record_union_type *) & r,
916 offsetof (oasys_header_record_type,
917 description[0]));
252b5132
RH
918}
919
b34976b6 920static bfd_boolean
116c20d2 921oasys_write_end (bfd *abfd)
252b5132
RH
922{
923 oasys_end_record_type end;
924 unsigned char null = 0;
116c20d2 925
252b5132 926 end.relb = RELOCATION_TYPE_ABS;
dc810e39
AM
927 H_PUT_32 (abfd, abfd->start_address, end.entry);
928 H_PUT_16 (abfd, 0, end.fill);
252b5132
RH
929 end.zero = 0;
930 if (! oasys_write_record (abfd,
931 oasys_record_is_end_enum,
932 (oasys_record_union_type *) & end,
933 sizeof (end)))
b34976b6 934 return FALSE;
116c20d2
NC
935
936 return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1;
252b5132
RH
937}
938
939static int
116c20d2 940comp (const void * ap, const void * bp)
252b5132
RH
941{
942 arelent *a = *((arelent **) ap);
943 arelent *b = *((arelent **) bp);
116c20d2 944
252b5132
RH
945 return a->address - b->address;
946}
947
b34976b6 948static bfd_boolean
116c20d2 949oasys_write_data (bfd *abfd)
252b5132
RH
950{
951 asection *s;
116c20d2
NC
952
953 for (s = abfd->sections; s != NULL; s = s->next)
252b5132
RH
954 {
955 if (s->flags & SEC_LOAD)
956 {
957 bfd_byte *raw_data = oasys_per_section (s)->data;
958 oasys_data_record_type processed_data;
959 bfd_size_type current_byte_index = 0;
960 unsigned int relocs_to_go = s->reloc_count;
961 arelent **p = s->orelocation;
116c20d2 962
252b5132 963 if (s->reloc_count != 0)
116c20d2
NC
964 /* Sort the reloc records so it's easy to insert the relocs into the
965 data. */
966 qsort (s->orelocation, s->reloc_count, sizeof (arelent **), comp);
252b5132 967
252b5132
RH
968 current_byte_index = 0;
969 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
970
eea6121a 971 while (current_byte_index < s->size)
252b5132
RH
972 {
973 /* Scan forwards by eight bytes or however much is left and see if
116c20d2 974 there are any relocations going on. */
252b5132
RH
975 bfd_byte *mod = &processed_data.data[0];
976 bfd_byte *dst = &processed_data.data[1];
977
978 unsigned int i = 0;
979 *mod = 0;
980
dc810e39
AM
981 H_PUT_32 (abfd, s->vma + current_byte_index,
982 processed_data.addr);
252b5132
RH
983
984 /* Don't start a relocation unless you're sure you can finish it
116c20d2
NC
985 within the same data record. The worst case relocation is a
986 4-byte relocatable value which is split across two modification
987 bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
988 1 modification byte + 2 data = 8 bytes total). That's where
989 the magic number 8 comes from. */
eea6121a 990 while (current_byte_index < s->size && dst <=
116c20d2 991 & processed_data.data[sizeof (processed_data.data) - 8])
252b5132 992 {
252b5132
RH
993 if (relocs_to_go != 0)
994 {
995 arelent *r = *p;
252b5132 996
116c20d2
NC
997 /* There is a relocation, is it for this byte ? */
998 if (r->address == current_byte_index)
999 abort ();
252b5132 1000 }
116c20d2 1001
252b5132 1002 /* If this is coming from an unloadable section then copy
116c20d2 1003 zeros. */
252b5132 1004 if (raw_data == NULL)
116c20d2 1005 *dst++ = 0;
252b5132 1006 else
116c20d2
NC
1007 *dst++ = *raw_data++;
1008
1009 if (++i >= 8)
252b5132 1010 {
116c20d2
NC
1011 i = 0;
1012 mod = dst++;
1013 *mod = 0;
252b5132 1014 }
116c20d2 1015 current_byte_index++;
252b5132
RH
1016 }
1017
116c20d2 1018 /* Don't write a useless null modification byte. */
252b5132 1019 if (dst == mod + 1)
116c20d2 1020 --dst;
252b5132 1021
dc810e39
AM
1022 if (! (oasys_write_record
1023 (abfd, oasys_record_is_data_enum,
1024 ((oasys_record_union_type *) &processed_data),
1025 (size_t) (dst - (bfd_byte *) &processed_data))))
b34976b6 1026 return FALSE;
252b5132
RH
1027 }
1028 }
1029 }
1030
b34976b6 1031 return TRUE;
252b5132
RH
1032}
1033
b34976b6 1034static bfd_boolean
116c20d2 1035oasys_write_object_contents (bfd *abfd)
252b5132
RH
1036{
1037 if (! oasys_write_header (abfd))
b34976b6 1038 return FALSE;
252b5132 1039 if (! oasys_write_syms (abfd))
b34976b6 1040 return FALSE;
252b5132 1041 if (! oasys_write_sections (abfd))
b34976b6 1042 return FALSE;
252b5132 1043 if (! oasys_write_data (abfd))
b34976b6 1044 return FALSE;
252b5132 1045 if (! oasys_write_end (abfd))
b34976b6
AM
1046 return FALSE;
1047 return TRUE;
252b5132
RH
1048}
1049
116c20d2
NC
1050/* Set section contents is complicated with OASYS since the format is
1051 not a byte image, but a record stream. */
252b5132 1052
b34976b6 1053static bfd_boolean
116c20d2
NC
1054oasys_set_section_contents (bfd *abfd,
1055 sec_ptr section,
1056 const void * location,
1057 file_ptr offset,
1058 bfd_size_type count)
252b5132
RH
1059{
1060 if (count != 0)
1061 {
116c20d2 1062 if (oasys_per_section (section)->data == NULL)
252b5132 1063 {
116c20d2 1064 oasys_per_section (section)->data = bfd_alloc (abfd, section->size);
252b5132 1065 if (!oasys_per_section (section)->data)
b34976b6 1066 return FALSE;
252b5132 1067 }
116c20d2
NC
1068 (void) memcpy ((void *) (oasys_per_section (section)->data + offset),
1069 location, (size_t) count);
252b5132 1070 }
b34976b6 1071 return TRUE;
252b5132
RH
1072}
1073
1074
1075
116c20d2 1076/* Native-level interface to symbols. */
252b5132
RH
1077
1078/* We read the symbols into a buffer, which is discarded when this
116c20d2
NC
1079 function exits. We read the strings into a buffer large enough to
1080 hold them all plus all the cached symbol entries. */
252b5132
RH
1081
1082static asymbol *
116c20d2 1083oasys_make_empty_symbol (bfd *abfd)
252b5132 1084{
dc810e39 1085 bfd_size_type amt = sizeof (oasys_symbol_type);
116c20d2
NC
1086 oasys_symbol_type *new = bfd_zalloc (abfd, amt);
1087
252b5132
RH
1088 if (!new)
1089 return NULL;
1090 new->symbol.the_bfd = abfd;
1091 return &new->symbol;
1092}
252b5132
RH
1093
1094/* User should have checked the file flags; perhaps we should return
116c20d2 1095 BFD_NO_MORE_SYMBOLS if there are none? */
252b5132
RH
1096
1097static bfd *
116c20d2 1098oasys_openr_next_archived_file (bfd *arch, bfd *prev)
252b5132
RH
1099{
1100 oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
1101 oasys_module_info_type *p;
116c20d2
NC
1102
1103 /* Take the next one from the arch state, or reset. */
1104 if (prev == NULL)
1105 /* Reset the index - the first two entries are bogus. */
1106 ar->module_index = 0;
252b5132
RH
1107
1108 p = ar->module + ar->module_index;
1109 ar->module_index++;
1110
1111 if (ar->module_index <= ar->module_count)
1112 {
116c20d2 1113 if (p->abfd == NULL)
252b5132
RH
1114 {
1115 p->abfd = _bfd_create_empty_archive_element_shell (arch);
1116 p->abfd->origin = p->pos;
1117 p->abfd->filename = p->name;
1118
116c20d2
NC
1119 /* Fixup a pointer to this element for the member. */
1120 p->abfd->arelt_data = (void *) p;
252b5132
RH
1121 }
1122 return p->abfd;
1123 }
116c20d2
NC
1124
1125 bfd_set_error (bfd_error_no_more_archived_files);
1126 return NULL;
252b5132
RH
1127}
1128
b34976b6 1129static bfd_boolean
116c20d2
NC
1130oasys_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED,
1131 asection *section ATTRIBUTE_UNUSED,
1132 asymbol **symbols ATTRIBUTE_UNUSED,
1133 bfd_vma offset ATTRIBUTE_UNUSED,
1134 const char **filename_ptr ATTRIBUTE_UNUSED,
1135 const char **functionname_ptr ATTRIBUTE_UNUSED,
1136 unsigned int *line_ptr ATTRIBUTE_UNUSED)
252b5132 1137{
b34976b6 1138 return FALSE;
252b5132
RH
1139}
1140
4ab527b0
FF
1141static bfd_boolean
1142oasys_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
1143 const char **filename_ptr ATTRIBUTE_UNUSED,
1144 const char **functionname_ptr ATTRIBUTE_UNUSED,
1145 unsigned int *line_ptr ATTRIBUTE_UNUSED)
1146{
1147 return FALSE;
1148}
1149
252b5132 1150static int
116c20d2 1151oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
252b5132
RH
1152{
1153 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
116c20d2
NC
1154
1155 if (mod == NULL)
252b5132
RH
1156 {
1157 bfd_set_error (bfd_error_invalid_operation);
1158 return -1;
1159 }
116c20d2
NC
1160
1161 buf->st_size = mod->size;
1162 buf->st_mode = 0666;
1163 return 0;
252b5132
RH
1164}
1165
1166static int
a6b96beb
AM
1167oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
1168 struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132
RH
1169{
1170 return 0;
1171}
1172
116c20d2
NC
1173#define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
1174#define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1175#define oasys_slurp_armap bfd_true
1176#define oasys_slurp_extended_name_table bfd_true
1177#define oasys_construct_extended_name_table ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true)
1178#define oasys_truncate_arname bfd_dont_truncate_arname
1179#define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true)
1180#define oasys_read_ar_hdr bfd_nullvoidptr
1181#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
1182#define oasys_update_armap_timestamp bfd_true
1183#define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
1184#define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1185#define oasys_get_lineno _bfd_nosymbols_get_lineno
1186#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1187#define oasys_read_minisymbols _bfd_generic_read_minisymbols
1188#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1189#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
157090f7 1190#define oasys_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
116c20d2
NC
1191#define oasys_set_arch_mach bfd_default_set_arch_mach
1192#define oasys_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1193#define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1194#define oasys_bfd_relax_section bfd_generic_relax_section
1195#define oasys_bfd_gc_sections bfd_generic_gc_sections
1196#define oasys_bfd_merge_sections bfd_generic_merge_sections
1197#define oasys_bfd_is_group_section bfd_generic_is_group_section
1198#define oasys_bfd_discard_group bfd_generic_discard_group
1199#define oasys_section_already_linked _bfd_generic_section_already_linked
1200#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1201#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1202#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1203#define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
1204#define oasys_bfd_final_link _bfd_generic_final_link
1205#define oasys_bfd_link_split_section _bfd_generic_link_split_section
1206
252b5132
RH
1207const bfd_target oasys_vec =
1208{
116c20d2 1209 "oasys", /* Name. */
252b5132 1210 bfd_target_oasys_flavour,
116c20d2
NC
1211 BFD_ENDIAN_BIG, /* Target byte order. */
1212 BFD_ENDIAN_BIG, /* Target headers byte order. */
1213 (HAS_RELOC | EXEC_P | /* Object flags. */
252b5132
RH
1214 HAS_LINENO | HAS_DEBUG |
1215 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1216 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
116c20d2
NC
1217 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
1218 0, /* Leading underscore. */
1219 ' ', /* AR_pad_char. */
1220 16, /* AR_max_namelen. */
252b5132
RH
1221 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1222 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
116c20d2 1223 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
252b5132
RH
1224 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1225 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
116c20d2 1226 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
252b5132
RH
1227
1228 {_bfd_dummy_target,
116c20d2 1229 oasys_object_p, /* bfd_check_format. */
252b5132
RH
1230 oasys_archive_p,
1231 _bfd_dummy_target,
1232 },
116c20d2 1233 { /* bfd_set_format. */
252b5132
RH
1234 bfd_false,
1235 oasys_mkobject,
1236 _bfd_generic_mkarchive,
1237 bfd_false
1238 },
116c20d2 1239 { /* bfd_write_contents. */
252b5132
RH
1240 bfd_false,
1241 oasys_write_object_contents,
1242 _bfd_write_archive_contents,
1243 bfd_false,
1244 },
1245
1246 BFD_JUMP_TABLE_GENERIC (oasys),
1247 BFD_JUMP_TABLE_COPY (_bfd_generic),
1248 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1249 BFD_JUMP_TABLE_ARCHIVE (oasys),
1250 BFD_JUMP_TABLE_SYMBOLS (oasys),
1251 BFD_JUMP_TABLE_RELOCS (oasys),
1252 BFD_JUMP_TABLE_WRITE (oasys),
1253 BFD_JUMP_TABLE_LINK (oasys),
1254 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1255
c3c89269 1256 NULL,
dc810e39 1257
116c20d2 1258 NULL
252b5132 1259};
This page took 0.67127 seconds and 4 git commands to generate.