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