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