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