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