61db3838339134c68f9e19c3fab603f2acf147af
[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
27 #include <ansidecl.h>
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "libbfd.h"
31 #include "obstack.h"
32 #include "oasys.h"
33 #include "liboasys.h"
34
35 static void
36 DEFUN(oasys_read_record,(abfd, record),
37 bfd *CONST abfd AND
38 oasys_record_union_type *record)
39 {
40
41 bfd_read(record, 1, sizeof(record->header), abfd);
42
43 bfd_read(((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_undefined;
79 asymbol *dest_defined;
80 asymbol *dest;
81 char *string_ptr;
82
83
84 if (data->symbols != (asymbol *)NULL) {
85 return true;
86 }
87 /* Buy enough memory for all the symbols and all the names */
88 data->symbols =
89 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
90 #ifdef UNDERSCORE_HACK
91 /* buy 1 more char for each symbol to keep the underscore in*/
92 data->strings = bfd_alloc(abfd, data->symbol_string_length +
93 abfd->symcount);
94 #else
95 data->strings = bfd_alloc(abfd, data->symbol_string_length);
96 #endif
97
98 dest_undefined = data->symbols;
99 dest_defined = data->symbols + abfd->symcount -1;
100
101 string_ptr = data->strings;
102 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
103 while (loop) {
104
105 oasys_read_record(abfd, &record);
106 switch (record.header.type) {
107 case oasys_record_is_header_enum:
108 break;
109 case oasys_record_is_local_enum:
110 case oasys_record_is_symbol_enum:
111 {
112 int flag = record.header.type == oasys_record_is_local_enum ?
113 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
114
115
116 size_t length = oasys_string_length(&record);
117 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
118 case RELOCATION_TYPE_ABS:
119 dest = dest_defined--;
120 dest->section = 0;
121 dest->flags = BSF_ABSOLUTE | flag;
122 break;
123 case RELOCATION_TYPE_REL:
124 dest = dest_defined--;
125 dest->section =
126 oasys_data(abfd)->sections[record.symbol.relb &
127 RELOCATION_SECT_BITS];
128 if (record.header.type == oasys_record_is_local_enum)
129 {
130 dest->flags = BSF_LOCAL;
131 }
132 else {
133
134 dest->flags = flag;
135 }
136 break;
137 case RELOCATION_TYPE_UND:
138 dest = data->symbols + bfd_h_getshort(abfd, &record.symbol.refno[0]);
139 dest->section = (asection *)NULL;
140 dest->flags = BSF_UNDEFINED;
141 break;
142 case RELOCATION_TYPE_COM:
143 dest = dest_defined--;
144 dest->name = string_ptr;
145 dest->the_bfd = abfd;
146
147 dest->section = (asection *)NULL;
148 dest->flags = BSF_FORT_COMM;
149 break;
150 }
151 dest->name = string_ptr;
152 dest->the_bfd = abfd;
153 dest->udata = (PTR)NULL;
154 dest->value = bfd_h_getlong(abfd, &record.symbol.value[0]);
155
156 #ifdef UNDERSCORE_HACK
157 if (record.symbol.name[0] != '_') {
158 string_ptr[0] = '_';
159 string_ptr++;
160 }
161 #endif
162 memcpy(string_ptr, record.symbol.name, length);
163
164
165 string_ptr[length] =0;
166 string_ptr += length +1;
167 }
168 break;
169 default:
170 loop = false;
171 }
172 }
173 return true;
174
175 }
176
177 static size_t
178 DEFUN(oasys_get_symtab_upper_bound,(abfd),
179 bfd *CONST abfd)
180 {
181 oasys_slurp_symbol_table (abfd);
182
183 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
184 }
185
186 /*
187 */
188
189 extern bfd_target oasys_vec;
190
191 unsigned int
192 DEFUN(oasys_get_symtab,(abfd, location),
193 bfd *abfd AND
194 asymbol **location)
195 {
196 asymbol *symbase ;
197 unsigned int counter ;
198 if (oasys_slurp_symbol_table(abfd) == false) {
199 return 0;
200 }
201 symbase = oasys_data(abfd)->symbols;
202 for (counter = 0; counter < abfd->symcount; counter++) {
203 *(location++) = symbase++;
204 }
205 *location = 0;
206 return abfd->symcount;
207 }
208
209 /***********************************************************************
210 * archive stuff
211 */
212 #define swap(x) x = bfd_h_get_x(abfd, &x);
213 static bfd_target *
214 DEFUN(oasys_archive_p,(abfd),
215 bfd *abfd)
216 {
217 oasys_archive_header_type header;
218 unsigned int i;
219
220 bfd_seek(abfd, (file_ptr) 0, false);
221
222
223 bfd_read(&header, 1, sizeof(header), abfd);
224
225
226 swap(header.version);
227 swap(header.mod_count);
228 swap(header.mod_tbl_offset);
229 swap(header.sym_tbl_size);
230 swap(header.sym_count);
231 swap(header.sym_tbl_offset);
232 swap(header.xref_count);
233 swap(header.xref_lst_offset);
234
235 /*
236 There isn't a magic number in an Oasys archive, so the best we
237 can do to verify reasnableness is to make sure that the values in
238 the header are too weird
239 */
240
241 if (header.version>10000 ||
242 header.mod_count>10000 ||
243 header.sym_count>100000 ||
244 header.xref_count > 100000) return (bfd_target *)NULL;
245
246 /*
247 That all worked, lets buy the space for the header and read in
248 the headers.
249 */
250 {
251 oasys_ar_data_type *ar =
252 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
253
254
255 oasys_module_info_type *module =
256 (oasys_module_info_type*)
257 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
258
259 oasys_module_table_type record;
260
261 set_tdata(abfd, ar);
262 ar->module = module;
263 ar->module_count = header.mod_count;
264
265 bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
266 for (i = 0; i < header.mod_count; i++) {
267
268 bfd_read(&record, 1, sizeof(record), abfd);
269 swap(record.mod_size);
270 swap(record.file_offset);
271 swap(record.mod_name_length);
272 module[i].name = bfd_alloc(abfd,record.mod_name_length+1);
273
274 bfd_read(module[i].name, 1, record.mod_name_length +1, abfd);
275 /* SKip some stuff */
276 bfd_seek(abfd, record.dep_count * sizeof(int32_type),
277 SEEK_CUR);
278
279 module[i].size = record.mod_size;
280 module[i].pos = record.file_offset;
281 }
282
283 }
284 return abfd->xvec;
285 }
286
287 static boolean
288 DEFUN(oasys_mkobject,(abfd),
289 bfd *abfd)
290 {
291 oasys_data_type *oasys;
292
293 set_tdata (abfd,
294 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type)));
295 oasys = oasys_data(abfd);
296 return true;
297 }
298
299 #define MAX_SECS 16
300 static bfd_target *
301 DEFUN(oasys_object_p,(abfd),
302 bfd *abfd)
303 {
304 oasys_data_type *oasys;
305 boolean loop = true;
306 boolean had_usefull = false;
307
308 set_tdata (abfd, 0);
309 oasys_mkobject(abfd);
310 oasys = oasys_data(abfd);
311 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
312
313 /* Point to the start of the file */
314 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
315 oasys->symbol_string_length = 0;
316 /* Inspect the records, but only keep the section info -
317 remember the size of the symbols
318 */
319 oasys->first_data_record = 0;
320 while (loop) {
321 oasys_record_union_type record;
322 oasys_read_record(abfd, &record);
323 if ((size_t)record.header.length < (size_t)sizeof(record.header))
324 goto fail;
325
326
327 switch ((oasys_record_enum_type)(record.header.type)) {
328 case oasys_record_is_header_enum:
329 had_usefull = true;
330 break;
331 case oasys_record_is_symbol_enum:
332 case oasys_record_is_local_enum:
333 /* Count symbols and remember their size for a future malloc */
334 abfd->symcount++;
335 oasys->symbol_string_length += 1 + oasys_string_length(&record);
336 had_usefull = true;
337 break;
338 case oasys_record_is_section_enum:
339 {
340 asection *s;
341 char *buffer;
342 unsigned int section_number;
343 if (record.section.header.length != sizeof(record.section))
344 {
345 goto fail;
346 }
347 buffer = bfd_alloc(abfd, 3);
348 section_number= record.section.relb & RELOCATION_SECT_BITS;
349 sprintf(buffer,"%u", section_number);
350 s = bfd_make_section(abfd,buffer);
351 oasys->sections[section_number] = s;
352 switch (record.section.relb & RELOCATION_TYPE_BITS) {
353 case RELOCATION_TYPE_ABS:
354 case RELOCATION_TYPE_REL:
355 break;
356 case RELOCATION_TYPE_UND:
357 case RELOCATION_TYPE_COM:
358 BFD_FAIL();
359 }
360
361 s->size = bfd_h_getlong(abfd, & record.section.value[0]) ;
362 s->vma = bfd_h_getlong(abfd, &record.section.vma[0]);
363 s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
364 had_usefull = true;
365 }
366 break;
367 case oasys_record_is_data_enum:
368 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
369 case oasys_record_is_debug_enum:
370 case oasys_record_is_module_enum:
371 case oasys_record_is_named_section_enum:
372 case oasys_record_is_end_enum:
373 if (had_usefull == false) goto fail;
374 loop = false;
375 break;
376 default:
377 goto fail;
378 }
379 }
380 oasys->symbols = (asymbol *)NULL;
381 /*
382 Oasys support several architectures, but I can't see a simple way
383 to discover which one is in a particular file - we'll guess
384 */
385 abfd->obj_arch = bfd_arch_m68k;
386 abfd->obj_machine =0;
387 if (abfd->symcount != 0) {
388 abfd->flags |= HAS_SYMS;
389 }
390 return abfd->xvec;
391
392 fail:
393 (void) bfd_release(abfd, oasys);
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 break;
549
550
551 case RELOCATION_TYPE_UND:
552 {
553 oasys_reloc_type *r =
554 (oasys_reloc_type *)
555 bfd_alloc(abfd,
556 sizeof(oasys_reloc_type));
557 *(per->reloc_tail_ptr) = r;
558 per->reloc_tail_ptr = &r->next;
559 r->next= (oasys_reloc_type *)NULL;
560 /* Reference to undefined symbol */
561 src++;
562 /* Get symbol number */
563 r->symbol = (src[0]<<8) | src[1];
564 /* Work out the howto */
565 r->relent.section = (asection *)NULL;
566 r->relent.addend = 0;
567 r->relent.address = dst_ptr - dst_base_ptr;
568 r->relent.howto = &howto_table[reloc>>6];
569 r->relent.sym_ptr_ptr = (asymbol **)NULL;
570 section->reloc_count++;
571
572 src+=2;
573 }
574 break;
575 case RELOCATION_TYPE_COM:
576 BFD_FAIL();
577 }
578 }
579 *dst_ptr++ = *src++;
580 }
581 }
582 }
583 }
584 break;
585 case oasys_record_is_local_enum:
586 case oasys_record_is_symbol_enum:
587 case oasys_record_is_section_enum:
588 break;
589 default:
590 loop = false;
591 }
592 }
593 return true;
594
595 }
596
597
598
599 bfd_error_vector_type bfd_error_vector;
600
601 static boolean
602 DEFUN(oasys_new_section_hook,(abfd, newsect),
603 bfd *abfd AND
604 asection *newsect)
605 {
606 newsect->used_by_bfd = (PTR)
607 bfd_alloc(abfd, sizeof(oasys_per_section_type));
608 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
609 oasys_per_section(newsect)->section = newsect;
610 oasys_per_section(newsect)->offset = 0;
611 newsect->alignment_power = 3;
612 /* Turn the section string into an index */
613
614 sscanf(newsect->name,"%u", &newsect->target_index);
615
616 return true;
617 }
618
619
620 static unsigned int
621 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
622 bfd *abfd AND
623 sec_ptr asect)
624 {
625 oasys_slurp_section_data(abfd);
626 return (asect->reloc_count+1) * sizeof(arelent *);
627 }
628
629 static boolean
630 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
631 bfd *abfd AND
632 sec_ptr section AND
633 void *location AND
634 file_ptr offset AND
635 unsigned int count)
636 {
637 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
638 oasys_slurp_section_data(abfd);
639 (void) memcpy(location, p->data + offset, count);
640 return true;
641 }
642
643
644 unsigned int
645 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
646 bfd *abfd AND
647 sec_ptr section AND
648 arelent **relptr AND
649 asymbol **symbols)
650 {
651 unsigned int reloc_count = 0;
652 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
653 while (src != (oasys_reloc_type *)NULL) {
654 if (src->relent.section == (asection *)NULL)
655 {
656 src->relent.sym_ptr_ptr = symbols + src->symbol;
657 }
658 *relptr ++ = &src->relent;
659 src = src->next;
660 reloc_count++;
661 }
662 *relptr = (arelent *)NULL;
663 return section->reloc_count = reloc_count;
664 }
665
666
667 boolean
668 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
669 bfd *abfd AND
670 enum bfd_architecture arch AND
671 unsigned long machine)
672 {
673 abfd->obj_arch = arch;
674 abfd->obj_machine = machine;
675 return true;
676 }
677
678
679
680 /* Writing */
681
682
683 /* Calculate the checksum and write one record */
684 static void
685 DEFUN(oasys_write_record,(abfd, type, record, size),
686 bfd *CONST abfd AND
687 CONST oasys_record_enum_type type AND
688 oasys_record_union_type *record AND
689 CONST size_t size)
690 {
691 int checksum;
692 size_t i;
693 uint8e_type *ptr;
694 record->header.length = size;
695 record->header.type = type;
696 record->header.check_sum = 0;
697 record->header.fill = 0;
698 ptr = &record->pad[0];
699 checksum = 0;
700 for (i = 0; i < size; i++) {
701 checksum += *ptr++;
702 }
703 record->header.check_sum = 0xff & (- checksum);
704 bfd_write((PTR)record, 1, size, abfd);
705 }
706
707
708 /* Write out all the symbols */
709 static void
710 DEFUN(oasys_write_syms, (abfd),
711 bfd * CONST abfd)
712 {
713 unsigned int count;
714 asymbol **generic = bfd_get_outsymbols(abfd);
715 unsigned int index = 0;
716 for (count = 0; count < bfd_get_symcount(abfd); count++) {
717
718 oasys_symbol_record_type symbol;
719 asymbol * CONST g = generic[count];
720
721 CONST char *src = g->name;
722 char *dst = symbol.name;
723 unsigned int l = 0;
724
725 if (g->flags & BSF_FORT_COMM) {
726 symbol.relb = RELOCATION_TYPE_COM;
727 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
728 index++;
729 }
730 else if (g->flags & BSF_ABSOLUTE) {
731 symbol.relb = RELOCATION_TYPE_ABS;
732 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
733
734 }
735 else if (g->flags & BSF_UNDEFINED) {
736 symbol.relb = RELOCATION_TYPE_UND ;
737 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
738 /* Overload the value field with the output index number */
739 index++;
740 }
741 else if (g->flags & BSF_DEBUGGING) {
742 /* throw it away */
743 continue;
744 }
745 else {
746 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
747 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
748 }
749 while (src[l]) {
750 dst[l] = src[l];
751 l++;
752 }
753
754 bfd_h_putlong(abfd, g->value, symbol.value);
755
756
757 if (g->flags & BSF_LOCAL) {
758 oasys_write_record(abfd,
759 oasys_record_is_local_enum,
760 (oasys_record_union_type *) &symbol,
761 offsetof(oasys_symbol_record_type, name[0]) + l);
762 }
763 else {
764 oasys_write_record(abfd,
765 oasys_record_is_symbol_enum,
766 (oasys_record_union_type *) &symbol,
767 offsetof(oasys_symbol_record_type, name[0]) + l);
768 }
769 g->value = index-1;
770 }
771 }
772
773
774 /* Write a section header for each section */
775 static void
776 DEFUN(oasys_write_sections, (abfd),
777 bfd *CONST abfd)
778 {
779 asection *s;
780 static oasys_section_record_type out = {0};
781
782 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
783 if (!isdigit(s->name[0]))
784 {
785 bfd_error_vector.nonrepresentable_section(abfd,
786 s->name);
787 }
788 out.relb = RELOCATION_TYPE_REL | s->target_index;
789 bfd_h_putlong(abfd, s->size, out.value);
790 bfd_h_putlong(abfd, s->vma, out.vma);
791
792 oasys_write_record(abfd,
793 oasys_record_is_section_enum,
794 (oasys_record_union_type *) &out,
795 sizeof(out));
796 }
797 }
798
799 static void
800 DEFUN(oasys_write_header, (abfd),
801 bfd *CONST abfd)
802 {
803 /* Create and write the header */
804 oasys_header_record_type r;
805 size_t length = strlen(abfd->filename);
806 if (length > (size_t)sizeof(r.module_name)) {
807 length = sizeof(r.module_name);
808 }
809
810 (void)memcpy(r.module_name,
811 abfd->filename,
812 length);
813 (void)memset(r.module_name + length,
814 ' ',
815 sizeof(r.module_name) - length);
816
817 r.version_number = OASYS_VERSION_NUMBER;
818 r.rev_number = OASYS_REV_NUMBER;
819 oasys_write_record(abfd,
820 oasys_record_is_header_enum,
821 (oasys_record_union_type *)&r,
822 offsetof(oasys_header_record_type, description[0]));
823
824
825
826 }
827
828 static void
829 DEFUN(oasys_write_end,(abfd),
830 bfd *CONST abfd)
831 {
832 oasys_end_record_type end;
833 end.relb = RELOCATION_TYPE_ABS;
834 bfd_h_putlong(abfd, abfd->start_address, end.entry);
835 bfd_h_putshort(abfd, 0, end.fill);
836 end.zero =0;
837 oasys_write_record(abfd,
838 oasys_record_is_end_enum,
839 (oasys_record_union_type *)&end,
840 sizeof(end));
841 }
842
843 static int
844 DEFUN(comp,(ap, bp),
845 CONST PTR ap AND
846 CONST PTR bp)
847 {
848 arelent *a = *((arelent **)ap);
849 arelent *b = *((arelent **)bp);
850 return a->address - b->address;
851 }
852
853 /*
854 Writing data..
855
856 */
857 static void
858 DEFUN(oasys_write_data, (abfd),
859 bfd *CONST abfd)
860 {
861 asection *s;
862 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
863 uint8e_type *raw_data = oasys_per_section(s)->data;
864 oasys_data_record_type processed_data;
865 unsigned int current_byte_index = 0;
866 unsigned int relocs_to_go = s->reloc_count;
867 arelent **p = s->orelocation;
868 if (s->reloc_count != 0) {
869 /* Sort the reloc records so it's easy to insert the relocs into the
870 data */
871
872 qsort(s->orelocation,
873 s->reloc_count,
874 sizeof(arelent **),
875 comp);
876 }
877 current_byte_index = 0;
878 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
879
880 while ((size_t)current_byte_index < s->size)
881 {
882 /* Scan forwards by eight bytes or however much is left and see if
883 there are any relocations going on */
884 uint8e_type *mod = &processed_data.data[0];
885 uint8e_type *dst = &processed_data.data[1];
886
887 unsigned int i;
888 unsigned int long_length = 128;
889
890
891 bfd_h_putlong(abfd, s->vma + current_byte_index, processed_data.addr);
892 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
893 long_length = s->size - current_byte_index;
894 }
895 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
896
897 unsigned int length = long_length;
898 *mod =0;
899 if (length > 8)
900 length = 8;
901
902 for (i = 0; i < length; i++) {
903 if (relocs_to_go != 0) {
904 arelent *r = *p;
905 reloc_howto_type *CONST how=r->howto;
906 /* There is a relocation, is it for this byte ? */
907 if (r->address == current_byte_index) {
908 uint8e_type rel_byte;
909 p++;
910 relocs_to_go--;
911
912 *mod |= (1<<i);
913 if(how->pc_relative) {
914 rel_byte = 0x80;
915 }
916 else {
917 rel_byte = 0;
918 }
919 if (how->size ==2) {
920 rel_byte |= 0x40;
921 }
922
923 /* Is this a section relative relocation, or a symbol
924 relative relocation ? */
925 if (r->section != (asection*)NULL)
926 {
927 /* The relent has a section attatched, so it must be section
928 relative */
929 rel_byte |= RELOCATION_TYPE_REL;
930 rel_byte |= r->section->output_section->target_index;
931 *dst++ = rel_byte;
932 }
933 else
934 {
935 asymbol *p = *(r->sym_ptr_ptr);
936
937 /* If this symbol has a section attatched, then it
938 has already been resolved. Change from a symbol
939 ref to a section ref */
940 if(p->section != (asection *)NULL) {
941 rel_byte |= RELOCATION_TYPE_REL;
942 rel_byte |=
943 p->section->output_section->target_index;
944 *dst++ = rel_byte;
945 }
946 else {
947 rel_byte |= RELOCATION_TYPE_UND;
948
949
950 *dst++ = rel_byte;
951 /* Next two bytes are a symbol index - we can get
952 this from the symbol value which has been zapped
953 into the symbol index in the table when the
954 symbol table was written
955 */
956 *dst++ = p->value >> 8;
957 *dst++ = p->value;
958 }
959
960 }
961 }
962 }
963 /* If this is coming from an unloadable section then copy
964 zeros */
965 if (raw_data == (uint8e_type *)NULL) {
966 *dst++ = 0;
967 }
968 else {
969 *dst++ = *raw_data++;
970 }
971 current_byte_index++;
972 }
973 mod = dst++;
974 long_length -= length;
975 }
976
977 oasys_write_record(abfd,
978 oasys_record_is_data_enum,
979 (oasys_record_union_type *)&processed_data,
980 dst - (uint8e_type*)&processed_data);
981
982 }
983 }
984 }
985 static boolean
986 DEFUN(oasys_write_object_contents, (abfd),
987 bfd * CONST abfd)
988 {
989 oasys_write_header(abfd);
990 oasys_write_syms(abfd);
991 oasys_write_sections(abfd);
992 oasys_write_data(abfd);
993 oasys_write_end(abfd);
994 return true;
995 }
996
997
998
999
1000 /** exec and core file sections */
1001
1002 /* set section contents is complicated with OASYS since the format is
1003 * not a byte image, but a record stream.
1004 */
1005 static boolean
1006 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1007 bfd *abfd AND
1008 sec_ptr section AND
1009 unsigned char *location AND
1010 file_ptr offset AND
1011 int count)
1012 {
1013 if (count != 0) {
1014 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1015 {
1016 oasys_per_section(section)->data =
1017 (bfd_byte *)(bfd_alloc(abfd,section->size));
1018 }
1019 (void) memcpy(oasys_per_section(section)->data + offset,
1020 location,
1021 count);
1022 }
1023 return true;
1024 }
1025
1026
1027
1028 /* Native-level interface to symbols. */
1029
1030 /* We read the symbols into a buffer, which is discarded when this
1031 function exits. We read the strings into a buffer large enough to
1032 hold them all plus all the cached symbol entries. */
1033
1034 static asymbol *
1035 DEFUN(oasys_make_empty_symbol,(abfd),
1036 bfd *abfd)
1037 {
1038
1039 oasys_symbol_type *new =
1040 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1041 new->symbol.the_bfd = abfd;
1042 return &new->symbol;
1043
1044 }
1045
1046
1047 \f
1048 /* Obsbolete procedural interface; better to look at the cache directly */
1049
1050 /* User should have checked the file flags; perhaps we should return
1051 BFD_NO_MORE_SYMBOLS if there are none? */
1052
1053
1054
1055 boolean
1056 oasys_close_and_cleanup (abfd)
1057 bfd *abfd;
1058 {
1059 if (bfd_read_p (abfd) == false)
1060 switch (abfd->format) {
1061 case bfd_archive:
1062 if (!_bfd_write_archive_contents (abfd)) {
1063 return false;
1064 }
1065 break;
1066 case bfd_object:
1067 if (!oasys_write_object_contents (abfd)) {
1068 return false;
1069 }
1070 break;
1071 default:
1072 bfd_error = invalid_operation;
1073 return false;
1074 }
1075
1076
1077
1078 return true;
1079 }
1080
1081 static bfd *
1082 oasys_openr_next_archived_file(arch, prev)
1083 bfd *arch;
1084 bfd *prev;
1085 {
1086 oasys_ar_data_type *ar = oasys_ar_data(arch);
1087 oasys_module_info_type *p;
1088 /* take the next one from the arch state, or reset */
1089 if (prev == (bfd *)NULL) {
1090 /* Reset the index - the first two entries are bogus*/
1091 ar->module_index = 0;
1092 }
1093
1094 p = ar->module + ar->module_index;
1095 ar->module_index++;
1096
1097 if (ar->module_index <= ar->module_count) {
1098 if (p->abfd == (bfd *)NULL) {
1099 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1100 p->abfd->origin = p->pos;
1101 p->abfd->filename = p->name;
1102
1103 /* Fixup a pointer to this element for the member */
1104 p->abfd->arelt_data = (PTR)p;
1105 }
1106 return p->abfd;
1107 }
1108 else {
1109 bfd_error = no_more_archived_files;
1110 return (bfd *)NULL;
1111 }
1112 }
1113
1114 static boolean
1115 oasys_find_nearest_line(abfd,
1116 section,
1117 symbols,
1118 offset,
1119 filename_ptr,
1120 functionname_ptr,
1121 line_ptr)
1122 bfd *abfd;
1123 asection *section;
1124 asymbol **symbols;
1125 bfd_vma offset;
1126 char **filename_ptr;
1127 char **functionname_ptr;
1128 unsigned int *line_ptr;
1129 {
1130 return false;
1131
1132 }
1133
1134 static int
1135 oasys_generic_stat_arch_elt(abfd, buf)
1136 bfd *abfd;
1137 struct stat *buf;
1138 {
1139 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1140 if (mod == (oasys_module_info_type *)NULL) {
1141 bfd_error = invalid_operation;
1142 return -1;
1143 }
1144 else {
1145 buf->st_size = mod->size;
1146 buf->st_mode = 0666;
1147 return 0;
1148 }
1149 }
1150
1151 static int
1152 DEFUN(oasys_sizeof_headers,(abfd),
1153 bfd *abfd)
1154 {
1155 return 0;
1156 }
1157
1158 #define oasys_core_file_failing_command bfd_false
1159 #define oasys_core_file_failing_signal bfd_false
1160 #define oasys_core_file_matches_executable_p bfd_false
1161 #define oasys_slurp_armap bfd_false
1162 #define oasys_slurp_extended_name_table bfd_false
1163 #define oasys_truncate_arname bfd_false
1164 #define oasys_write_armap bfd_false
1165 #define oasys_get_lineno bfd_false
1166
1167
1168
1169 /*SUPPRESS 460 */
1170 bfd_target oasys_vec =
1171 {
1172 "oasys", /* name */
1173 bfd_target_oasys_flavour_enum,
1174 true, /* target byte order */
1175 true, /* target headers byte order */
1176 (HAS_RELOC | EXEC_P | /* object flags */
1177 HAS_LINENO | HAS_DEBUG |
1178 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1179 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1180 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1181 ' ', /* ar_pad_char */
1182 16, /* ar_max_namelen */
1183
1184 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1185 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1186
1187 {_bfd_dummy_target,
1188 oasys_object_p, /* bfd_check_format */
1189 oasys_archive_p,
1190 bfd_false
1191 },
1192 {
1193 bfd_false,
1194 oasys_mkobject,
1195 _bfd_generic_mkarchive,
1196 bfd_false
1197 },
1198 JUMP_TABLE(oasys)
1199 };
This page took 0.053146 seconds and 4 git commands to generate.