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