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