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