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