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