1/* BFD back-end for oasys objects.
2   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
3   2002, 2003, 2004 Free Software Foundation, Inc.
4   Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
5
6   This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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.  */
21
22#define UNDERSCORE_HACK 1
23#include "bfd.h"
24#include "sysdep.h"
25#include "safe-ctype.h"
26#include "libbfd.h"
27#include "oasys.h"
28#include "liboasys.h"
29
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
37  PARAMS ((bfd *, oasys_record_enum_type, oasys_record_union_type *, size_t));
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 *));
60static void oasys_print_symbol
61  PARAMS ((bfd *, void *, asymbol *, bfd_print_symbol_type));
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
67  PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type));
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
73  PARAMS ((bfd *, sec_ptr, const void *, file_ptr, bfd_size_type));
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
79  PARAMS ((bfd *, asection *, asymbol **, bfd_vma,
80	   const char **, const char **, unsigned int *));
81static int oasys_generic_stat_arch_elt
82  PARAMS ((bfd *, struct stat *));
83static int oasys_sizeof_headers
84  PARAMS ((bfd *, bfd_boolean));
85
86long oasys_canonicalize_symtab
87  PARAMS ((bfd *, asymbol **));
88long oasys_canonicalize_reloc
89  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
90
91/* Read in all the section data and relocation stuff too.  */
92
93static bfd_boolean
94oasys_read_record (abfd, record)
95     bfd *abfd;
96     oasys_record_union_type *record;
97{
98  bfd_size_type amt = sizeof (record->header);
99  if (bfd_bread ((PTR) record, amt, abfd) != amt)
100    return FALSE;
101
102  amt = record->header.length - sizeof (record->header);
103  if ((long) amt <= 0)
104    return TRUE;
105  if (bfd_bread ((PTR) ((char *) record + sizeof (record->header)), amt, abfd)
106      != amt)
107    return FALSE;
108  return TRUE;
109}
110
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
135static bfd_boolean
136oasys_slurp_symbol_table (abfd)
137     bfd *const abfd;
138{
139  oasys_record_union_type record;
140  oasys_data_type *data = OASYS_DATA (abfd);
141  bfd_boolean loop = TRUE;
142  asymbol *dest_defined;
143  asymbol *dest;
144  char *string_ptr;
145  bfd_size_type amt;
146
147  if (data->symbols != (asymbol *) NULL)
148    {
149      return TRUE;
150    }
151  /* Buy enough memory for all the symbols and all the names */
152  amt = abfd->symcount;
153  amt *= sizeof (asymbol);
154  data->symbols = (asymbol *) bfd_alloc (abfd, amt);
155
156  amt = data->symbol_string_length;
157#ifdef UNDERSCORE_HACK
158  /* buy 1 more char for each symbol to keep the underscore in*/
159  amt += abfd->symcount;
160#endif
161  data->strings = bfd_alloc (abfd, amt);
162
163  if (!data->symbols || !data->strings)
164    return FALSE;
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)
170    return FALSE;
171  while (loop)
172    {
173
174      if (! oasys_read_record (abfd, &record))
175	return FALSE;
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:
219		dest = data->symbols + H_GET_16 (abfd, record.symbol.refno);
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;
238	    dest->value = H_GET_32 (abfd, record.symbol.value);
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:
255	  loop = FALSE;
256	}
257    }
258  return TRUE;
259}
260
261static long
262oasys_get_symtab_upper_bound (abfd)
263     bfd *const abfd;
264{
265  if (! oasys_slurp_symbol_table (abfd))
266    return -1;
267
268  return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
269}
270
271extern const bfd_target oasys_vec;
272
273long
274oasys_canonicalize_symtab (abfd, location)
275     bfd *abfd;
276     asymbol **location;
277{
278  asymbol *symbase;
279  unsigned int counter;
280  if (! oasys_slurp_symbol_table (abfd))
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;
305  bfd_size_type amt;
306
307  amt = sizeof (header_ext);
308  if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
309      || bfd_bread ((PTR) &header_ext, amt, abfd) != amt)
310    {
311      if (bfd_get_error () != bfd_error_system_call)
312	bfd_set_error (bfd_error_wrong_format);
313      return NULL;
314    }
315
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);
324
325  /*
326    There isn't a magic number in an Oasys archive, so the best we
327    can do to verify reasonableness is to make sure that the values in
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  {
342    oasys_ar_data_type *ar;
343    oasys_module_info_type *module;
344    oasys_module_table_type record;
345
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
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;
371
372	    amt = sizeof (record_ext);
373	    if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
374	      return NULL;
375
376	    record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
377	    record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
378
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);
382
383	    module[i].name = bfd_alloc (abfd, (bfd_size_type) 33);
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;
397
398	    amt = sizeof (record_ext);
399	    if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
400	      return NULL;
401
402	    record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
403	    record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
404
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);
410
411	    amt = record.module_name_size;
412	    module[i].name = bfd_alloc (abfd, amt + 1);
413	    if (!module[i].name)
414	      return NULL;
415	    if (bfd_bread ((PTR) module[i].name, amt, abfd) != amt)
416	      return NULL;
417	    module[i].name[record.module_name_size] = 0;
418	    filepos += (sizeof (record_ext)
419			+ record.dep_count * 4
420			+ record.module_name_size + 1);
421	  }
422
423	module[i].size = record.mod_size;
424	module[i].pos = record.file_offset;
425	module[i].abfd = 0;
426      }
427  }
428  return abfd->xvec;
429}
430
431static bfd_boolean
432oasys_mkobject (abfd)
433     bfd *abfd;
434{
435  bfd_size_type amt = sizeof (oasys_data_type);
436  abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, amt);
437  return abfd->tdata.oasys_obj_data != NULL;
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);
447  bfd_boolean loop = TRUE;
448  bfd_boolean had_usefull = FALSE;
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:
475	  had_usefull = TRUE;
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);
482	  had_usefull = TRUE;
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	      }
493	    buffer = bfd_alloc (abfd, (bfd_size_type) 3);
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
510	    s->size = H_GET_32 (abfd, record.section.value);
511	    s->vma = H_GET_32 (abfd, record.section.vma);
512	    s->flags = 0;
513	    had_usefull = TRUE;
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:
522	  if (! had_usefull)
523	    goto fail;
524	  loop = FALSE;
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)
559     bfd *ignore_abfd ATTRIBUTE_UNUSED;
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
569oasys_print_symbol (abfd, afile, symbol, how)
570     bfd *abfd;
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      {
585	const char *section_name = symbol->section == (asection *) NULL ?
586	(const char *) "*abs" : symbol->section->name;
587
588	bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
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
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)
608};
609
610/* Read in all the section data and relocation stuff too */
611static bfd_boolean
612oasys_slurp_section_data (abfd)
613     bfd *const abfd;
614{
615  oasys_record_union_type record;
616  oasys_data_type *data = OASYS_DATA (abfd);
617  bfd_boolean loop = TRUE;
618  oasys_per_section_type *per;
619  asection *s;
620  bfd_size_type amt;
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);
626      if (per->initialized)
627	return TRUE;
628    }
629
630  if (data->first_data_record == 0)
631    return TRUE;
632
633  if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
634    return FALSE;
635  while (loop)
636    {
637      if (! oasys_read_record (abfd, &record))
638	return FALSE;
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
658	    if (! per->initialized)
659	      {
660		per->data = (bfd_byte *) bfd_zalloc (abfd, section->size);
661		if (!per->data)
662		  return FALSE;
663		per->reloc_tail_ptr
664		  = (oasys_reloc_type **) &section->relocation;
665		per->had_vma = FALSE;
666		per->initialized = TRUE;
667		section->reloc_count = 0;
668		section->flags = SEC_ALLOC;
669	      }
670
671	    dst_offset = H_GET_32 (abfd, record.data.addr);
672	    if (! per->had_vma)
673	      {
674		/* Take the first vma we see as the base */
675		section->vma = dst_offset;
676		per->had_vma = TRUE;
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 */
725				  oasys_reloc_type *r;
726
727				  amt = sizeof (oasys_reloc_type);
728				  r = (oasys_reloc_type *) bfd_alloc (abfd,
729								      amt);
730				  if (!r)
731				    return FALSE;
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
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;
761				}
762				break;
763
764
765			      case RELOCATION_TYPE_UND:
766				{
767				  oasys_reloc_type *r;
768
769				  amt = sizeof (oasys_reloc_type);
770				  r = (oasys_reloc_type *) bfd_alloc (abfd,
771								      amt);
772				  if (!r)
773				    return FALSE;
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;
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;
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:
819	  loop = FALSE;
820	}
821    }
822
823  return TRUE;
824
825}
826
827static bfd_boolean
828oasys_new_section_hook (abfd, newsect)
829     bfd *abfd;
830     asection *newsect;
831{
832  newsect->used_by_bfd = (PTR)
833    bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
834  if (!newsect->used_by_bfd)
835    return FALSE;
836  oasys_per_section (newsect)->data = (bfd_byte *) NULL;
837  oasys_per_section (newsect)->section = newsect;
838  oasys_per_section (newsect)->offset = 0;
839  oasys_per_section (newsect)->initialized = FALSE;
840  newsect->alignment_power = 1;
841  /* Turn the section string into an index */
842
843  sscanf (newsect->name, "%u", &newsect->target_index);
844
845  return TRUE;
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
859static bfd_boolean
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{
867  oasys_per_section_type *p = oasys_per_section (section);
868  oasys_slurp_section_data (abfd);
869  if (! p->initialized)
870    {
871      (void) memset (location, 0, (size_t) count);
872    }
873  else
874    {
875      (void) memcpy (location, (PTR) (p->data + offset), (size_t) count);
876    }
877  return TRUE;
878}
879
880
881long
882oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
883     bfd *ignore_abfd ATTRIBUTE_UNUSED;
884     sec_ptr section;
885     arelent **relptr;
886     asymbol **symbols ATTRIBUTE_UNUSED;
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 */
916static bfd_boolean
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);
938  if (bfd_bwrite ((PTR) record, (bfd_size_type) size, abfd) != size)
939    return FALSE;
940  return TRUE;
941}
942
943
944/* Write out all the symbols */
945static bfd_boolean
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;
956      asymbol *const g = generic[count];
957
958      const char *src = g->name;
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;
965	  H_PUT_16 (abfd, index, symbol.refno);
966	  index++;
967	}
968      else if (bfd_is_abs_section (g->section))
969	{
970	  symbol.relb = RELOCATION_TYPE_ABS;
971	  H_PUT_16 (abfd, 0, symbol.refno);
972
973	}
974      else if (bfd_is_und_section (g->section))
975	{
976	  symbol.relb = RELOCATION_TYPE_UND;
977	  H_PUT_16 (abfd, index, symbol.refno);
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	    }
999	  H_PUT_16 (abfd, 0, symbol.refno);
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
1011      H_PUT_32 (abfd, g->value, symbol.value);
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))
1021	    return FALSE;
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))
1030	    return FALSE;
1031	}
1032      g->value = index - 1;
1033    }
1034
1035  return TRUE;
1036}
1037
1038
1039 /* Write a section header for each section */
1040static bfd_boolean
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    {
1049      if (!ISDIGIT (s->name[0]))
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);
1055	  return FALSE;
1056	}
1057      out.relb = RELOCATION_TYPE_REL | s->target_index;
1058      H_PUT_32 (abfd, s->size, out.value);
1059      H_PUT_32 (abfd, s->vma, out.vma);
1060
1061      if (! oasys_write_record (abfd,
1062				oasys_record_is_section_enum,
1063				(oasys_record_union_type *) & out,
1064				sizeof (out)))
1065	return FALSE;
1066    }
1067  return TRUE;
1068}
1069
1070static bfd_boolean
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])))
1096    return FALSE;
1097
1098  return TRUE;
1099}
1100
1101static bfd_boolean
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;
1108  H_PUT_32 (abfd, abfd->start_address, end.entry);
1109  H_PUT_16 (abfd, 0, end.fill);
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)))
1115    return FALSE;
1116  if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
1117    return FALSE;
1118  return TRUE;
1119}
1120
1121static int
1122comp (ap, bp)
1123     const PTR ap;
1124     const PTR bp;
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*/
1135static bfd_boolean
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
1162	  while (current_byte_index < s->size)
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
1173	      H_PUT_32 (abfd, s->vma + current_byte_index,
1174			processed_data.addr);
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 	    */
1183	      while (current_byte_index < s->size && dst <=
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			    {
1246			      asymbol *sym = *(r->sym_ptr_ptr);
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 */
1251			      if (sym->section != (asection *) NULL)
1252				{
1253				  rel_byte |= RELOCATION_TYPE_REL;
1254				  rel_byte |=
1255				    sym->section->output_section->target_index;
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			       */
1267				  *dst++ = sym->value >> 8;
1268				  *dst++ = sym->value;
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
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))))
1312		return FALSE;
1313	    }
1314	}
1315    }
1316
1317  return TRUE;
1318}
1319
1320static bfd_boolean
1321oasys_write_object_contents (abfd)
1322     bfd *abfd;
1323{
1324  if (! oasys_write_header (abfd))
1325    return FALSE;
1326  if (! oasys_write_syms (abfd))
1327    return FALSE;
1328  if (! oasys_write_sections (abfd))
1329    return FALSE;
1330  if (! oasys_write_data (abfd))
1331    return FALSE;
1332  if (! oasys_write_end (abfd))
1333    return FALSE;
1334  return TRUE;
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*/
1345static bfd_boolean
1346oasys_set_section_contents (abfd, section, location, offset, count)
1347     bfd *abfd;
1348     sec_ptr section;
1349     const PTR location;
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 =
1358	    (bfd_byte *) (bfd_alloc (abfd, section->size));
1359	  if (!oasys_per_section (section)->data)
1360	    return FALSE;
1361	}
1362      (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
1363		     location,
1364		     (size_t) count);
1365    }
1366  return TRUE;
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{
1381  bfd_size_type amt = sizeof (oasys_symbol_type);
1382  oasys_symbol_type *new = (oasys_symbol_type *) bfd_zalloc (abfd, amt);
1383  if (!new)
1384    return NULL;
1385  new->symbol.the_bfd = abfd;
1386  return &new->symbol;
1387}
1388
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
1432static bfd_boolean
1433oasys_find_nearest_line (abfd, section, symbols, offset,
1434			 filename_ptr, functionname_ptr, line_ptr)
1435     bfd *abfd ATTRIBUTE_UNUSED;
1436     asection *section ATTRIBUTE_UNUSED;
1437     asymbol **symbols ATTRIBUTE_UNUSED;
1438     bfd_vma offset ATTRIBUTE_UNUSED;
1439     const char **filename_ptr ATTRIBUTE_UNUSED;
1440     const char **functionname_ptr ATTRIBUTE_UNUSED;
1441     unsigned int *line_ptr ATTRIBUTE_UNUSED;
1442{
1443  return FALSE;
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)
1468     bfd *abfd ATTRIBUTE_UNUSED;
1469     bfd_boolean exec ATTRIBUTE_UNUSED;
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 \
1480  ((bfd_boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
1481   bfd_true)
1482#define oasys_truncate_arname bfd_dont_truncate_arname
1483#define oasys_write_armap \
1484  ((bfd_boolean (*) \
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_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1493#define oasys_get_lineno _bfd_nosymbols_get_lineno
1494#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1495#define oasys_read_minisymbols _bfd_generic_read_minisymbols
1496#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1497
1498#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1499
1500#define oasys_set_arch_mach bfd_default_set_arch_mach
1501
1502#define oasys_get_section_contents_in_window \
1503  _bfd_generic_get_section_contents_in_window
1504
1505#define oasys_bfd_get_relocated_section_contents \
1506  bfd_generic_get_relocated_section_contents
1507#define oasys_bfd_relax_section bfd_generic_relax_section
1508#define oasys_bfd_gc_sections bfd_generic_gc_sections
1509#define oasys_bfd_merge_sections bfd_generic_merge_sections
1510#define oasys_bfd_is_group_section bfd_generic_is_group_section
1511#define oasys_bfd_discard_group bfd_generic_discard_group
1512#define oasys_section_already_linked \
1513  _bfd_generic_section_already_linked
1514#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1515#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1516#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1517#define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
1518#define oasys_bfd_final_link _bfd_generic_final_link
1519#define oasys_bfd_link_split_section _bfd_generic_link_split_section
1520
1521/*SUPPRESS 460 */
1522const bfd_target oasys_vec =
1523{
1524  "oasys",			/* name */
1525  bfd_target_oasys_flavour,
1526  BFD_ENDIAN_BIG,		/* target byte order */
1527  BFD_ENDIAN_BIG,		/* target headers byte order */
1528  (HAS_RELOC | EXEC_P |		/* object flags */
1529   HAS_LINENO | HAS_DEBUG |
1530   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1531  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1532   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
1533  0,				/* leading underscore */
1534  ' ',				/* ar_pad_char */
1535  16,				/* ar_max_namelen */
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,	/* data */
1539  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1540  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1541  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
1542
1543  {_bfd_dummy_target,
1544   oasys_object_p,		/* bfd_check_format */
1545   oasys_archive_p,
1546   _bfd_dummy_target,
1547  },
1548  {				/* bfd_set_format */
1549    bfd_false,
1550    oasys_mkobject,
1551    _bfd_generic_mkarchive,
1552    bfd_false
1553  },
1554  {				/* bfd_write_contents */
1555    bfd_false,
1556    oasys_write_object_contents,
1557    _bfd_write_archive_contents,
1558    bfd_false,
1559  },
1560
1561  BFD_JUMP_TABLE_GENERIC (oasys),
1562  BFD_JUMP_TABLE_COPY (_bfd_generic),
1563  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1564  BFD_JUMP_TABLE_ARCHIVE (oasys),
1565  BFD_JUMP_TABLE_SYMBOLS (oasys),
1566  BFD_JUMP_TABLE_RELOCS (oasys),
1567  BFD_JUMP_TABLE_WRITE (oasys),
1568  BFD_JUMP_TABLE_LINK (oasys),
1569  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1570
1571  NULL,
1572
1573  (PTR) 0
1574};
1575