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