*** empty log message ***
[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 oasys_external_archive_header_type header_ext;
218 unsigned int i;
219
220 bfd_seek(abfd, (file_ptr) 0, false);
221
222
223 bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);
224
225
226 header.version = bfd_h_get_x(abfd, header_ext.version);
227 header.mod_count = bfd_h_get_x(abfd, header_ext.mod_count);
228 header.mod_tbl_offset = bfd_h_get_x(abfd, header_ext.mod_tbl_offset);
229 header.sym_tbl_size = bfd_h_get_x(abfd, header_ext.sym_tbl_size);
230 header.sym_count = bfd_h_get_x(abfd, header_ext.sym_count);
231 header.sym_tbl_offset = bfd_h_get_x(abfd, header_ext.sym_tbl_offset);
232 header.xref_count = bfd_h_get_x(abfd, header_ext.xref_count);
233 header.xref_lst_offset = bfd_h_get_x(abfd, header_ext.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 oasys_external_module_table_type record_ext;
261
262 set_tdata(abfd, ar);
263 ar->module = module;
264 ar->module_count = header.mod_count;
265
266 bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
267 for (i = 0; i < header.mod_count; i++) {
268 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
269
270 record.mod_size = bfd_h_get_x(abfd, record_ext.mod_size);
271 record.file_offset = bfd_h_get_x(abfd, record_ext.file_offset);
272 record.mod_name_length = bfd_h_get_x(abfd, record_ext.mod_name_length);
273
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 oasys_data_type *save = oasys_data(abfd);
308 boolean loop = true;
309 boolean had_usefull = false;
310
311 set_tdata (abfd, 0);
312 oasys_mkobject(abfd);
313 oasys = oasys_data(abfd);
314 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
315
316 /* Point to the start of the file */
317 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
318 oasys->symbol_string_length = 0;
319 /* Inspect the records, but only keep the section info -
320 remember the size of the symbols
321 */
322 oasys->first_data_record = 0;
323 while (loop) {
324 oasys_record_union_type record;
325 oasys_read_record(abfd, &record);
326 if ((size_t)record.header.length < (size_t)sizeof(record.header))
327 goto fail;
328
329
330 switch ((oasys_record_enum_type)(record.header.type)) {
331 case oasys_record_is_header_enum:
332 had_usefull = true;
333 break;
334 case oasys_record_is_symbol_enum:
335 case oasys_record_is_local_enum:
336 /* Count symbols and remember their size for a future malloc */
337 abfd->symcount++;
338 oasys->symbol_string_length += 1 + oasys_string_length(&record);
339 had_usefull = true;
340 break;
341 case oasys_record_is_section_enum:
342 {
343 asection *s;
344 char *buffer;
345 unsigned int section_number;
346 if (record.section.header.length != sizeof(record.section))
347 {
348 goto fail;
349 }
350 buffer = bfd_alloc(abfd, 3);
351 section_number= record.section.relb & RELOCATION_SECT_BITS;
352 sprintf(buffer,"%u", section_number);
353 s = bfd_make_section(abfd,buffer);
354 oasys->sections[section_number] = s;
355 switch (record.section.relb & RELOCATION_TYPE_BITS) {
356 case RELOCATION_TYPE_ABS:
357 case RELOCATION_TYPE_REL:
358 break;
359 case RELOCATION_TYPE_UND:
360 case RELOCATION_TYPE_COM:
361 BFD_FAIL();
362 }
363
364 s->size = bfd_h_getlong(abfd, & record.section.value[0]) ;
365 s->vma = bfd_h_getlong(abfd, &record.section.vma[0]);
366 s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
367 had_usefull = true;
368 }
369 break;
370 case oasys_record_is_data_enum:
371 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
372 case oasys_record_is_debug_enum:
373 case oasys_record_is_module_enum:
374 case oasys_record_is_named_section_enum:
375 case oasys_record_is_end_enum:
376 if (had_usefull == false) goto fail;
377 loop = false;
378 break;
379 default:
380 goto fail;
381 }
382 }
383 oasys->symbols = (asymbol *)NULL;
384 /*
385 Oasys support several architectures, but I can't see a simple way
386 to discover which one is in a particular file - we'll guess
387 */
388 abfd->obj_arch = bfd_arch_m68k;
389 abfd->obj_machine =0;
390 if (abfd->symcount != 0) {
391 abfd->flags |= HAS_SYMS;
392 }
393 return abfd->xvec;
394
395 fail:
396 (void) bfd_release(abfd, oasys);
397 oasys_data(abfd) = save;
398 return (bfd_target *)NULL;
399 }
400
401
402 static void
403 DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),
404 bfd *ignore_abfd AND
405 PTR afile AND
406 asymbol *symbol AND
407 bfd_print_symbol_enum_type how)
408 {
409 FILE *file = (FILE *)afile;
410
411 switch (how) {
412 case bfd_print_symbol_name_enum:
413 case bfd_print_symbol_type_enum:
414 fprintf(file,"%s", symbol->name);
415 break;
416 case bfd_print_symbol_all_enum:
417 {
418 CONST char *section_name = symbol->section == (asection *)NULL ?
419 "*abs" : symbol->section->name;
420
421 bfd_print_symbol_vandf((PTR)file,symbol);
422
423 fprintf(file," %-5s %s",
424 section_name,
425 symbol->name);
426 }
427 break;
428 }
429 }
430 /*
431 The howto table is build using the top two bits of a reloc byte to
432 index into it. The bits are PCREL,WORD/LONG
433 */
434 static reloc_howto_type howto_table[]=
435 {
436
437 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
438 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
439 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
440 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
441 };
442
443 /* Read in all the section data and relocation stuff too */
444 static boolean
445 DEFUN(oasys_slurp_section_data,(abfd),
446 bfd *CONST abfd)
447 {
448 oasys_record_union_type record;
449 oasys_data_type *data = oasys_data(abfd);
450 boolean loop = true;
451
452 oasys_per_section_type *per ;
453
454 asection *s;
455
456 /* Buy enough memory for all the section data and relocations */
457 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
458 per = oasys_per_section(s);
459 if (per->data != (bfd_byte*)NULL) return true;
460 per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
461 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
462 per->had_vma = false;
463 s->reloc_count = 0;
464 }
465
466 if (data->first_data_record == 0) return true;
467 bfd_seek(abfd, data->first_data_record, SEEK_SET);
468 while (loop) {
469 oasys_read_record(abfd, &record);
470 switch (record.header.type) {
471 case oasys_record_is_header_enum:
472 break;
473 case oasys_record_is_data_enum:
474 {
475
476 uint8e_type *src = record.data.data;
477 uint8e_type *end_src = ((uint8e_type *)&record) +
478 record.header.length;
479 unsigned int relbit;
480 bfd_byte *dst_ptr ;
481 bfd_byte *dst_base_ptr ;
482 unsigned int count;
483 asection * section =
484 data->sections[record.data.relb & RELOCATION_SECT_BITS];
485 bfd_vma dst_offset ;
486 per = oasys_per_section(section);
487 dst_offset = bfd_h_getlong(abfd, record.data.addr) ;
488 if (per->had_vma == false) {
489 /* Take the first vma we see as the base */
490
491 section->vma = dst_offset;
492 per->had_vma = true;
493 }
494
495
496 dst_offset -= section->vma;
497
498
499 dst_base_ptr = oasys_per_section(section)->data;
500 dst_ptr = oasys_per_section(section)->data +
501 dst_offset;
502
503 while (src < end_src) {
504 uint32_type gap = end_src - src -1;
505 uint8e_type mod_byte = *src++;
506 count = 8;
507 if (mod_byte == 0 && gap >= 8) {
508 dst_ptr[0] = src[0];
509 dst_ptr[1] = src[1];
510 dst_ptr[2] = src[2];
511 dst_ptr[3] = src[3];
512 dst_ptr[4] = src[4];
513 dst_ptr[5] = src[5];
514 dst_ptr[6] = src[6];
515 dst_ptr[7] = src[7];
516 dst_ptr+= 8;
517 src += 8;
518 }
519 else {
520 for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
521 {
522 if (relbit & mod_byte)
523 {
524 uint8e_type reloc = *src;
525 /* This item needs to be relocated */
526 switch (reloc & RELOCATION_TYPE_BITS) {
527 case RELOCATION_TYPE_ABS:
528
529 break;
530
531 case RELOCATION_TYPE_REL:
532 {
533 /* Relocate the item relative to the section */
534 oasys_reloc_type *r =
535 (oasys_reloc_type *)
536 bfd_alloc(abfd,
537 sizeof(oasys_reloc_type));
538 *(per->reloc_tail_ptr) = r;
539 per->reloc_tail_ptr = &r->next;
540 r->next= (oasys_reloc_type *)NULL;
541 /* Reference to undefined symbol */
542 src++;
543 /* There is no symbol */
544 r->symbol = 0;
545 /* Work out the howto */
546 r->relent.section =
547 data->sections[reloc & RELOCATION_SECT_BITS];
548 r->relent.addend = - r->relent.section->vma;
549 r->relent.address = dst_ptr - dst_base_ptr;
550 r->relent.howto = &howto_table[reloc>>6];
551 r->relent.sym_ptr_ptr = (asymbol **)NULL;
552 section->reloc_count++;
553
554 /* Fake up the data to look like it's got the -ve pc in it, this makes
555 it much easier to convert into other formats. This is done by
556 hitting the addend.
557 */
558 if (r->relent.howto->pc_relative == true) {
559 r->relent.addend -= dst_ptr - dst_base_ptr;
560 }
561
562
563 }
564 break;
565
566
567 case RELOCATION_TYPE_UND:
568 {
569 oasys_reloc_type *r =
570 (oasys_reloc_type *)
571 bfd_alloc(abfd,
572 sizeof(oasys_reloc_type));
573 *(per->reloc_tail_ptr) = r;
574 per->reloc_tail_ptr = &r->next;
575 r->next= (oasys_reloc_type *)NULL;
576 /* Reference to undefined symbol */
577 src++;
578 /* Get symbol number */
579 r->symbol = (src[0]<<8) | src[1];
580 /* Work out the howto */
581 r->relent.section = (asection *)NULL;
582 r->relent.addend = 0;
583 r->relent.address = dst_ptr - dst_base_ptr;
584 r->relent.howto = &howto_table[reloc>>6];
585 r->relent.sym_ptr_ptr = (asymbol **)NULL;
586 section->reloc_count++;
587
588 src+=2;
589 /* Fake up the data to look like it's got the -ve pc in it, this makes
590 it much easier to convert into other formats. This is done by
591 hitting the addend.
592 */
593 if (r->relent.howto->pc_relative == true) {
594 r->relent.addend -= dst_ptr - dst_base_ptr;
595 }
596
597
598
599 }
600 break;
601 case RELOCATION_TYPE_COM:
602 BFD_FAIL();
603 }
604 }
605 *dst_ptr++ = *src++;
606 }
607 }
608 }
609 }
610 break;
611 case oasys_record_is_local_enum:
612 case oasys_record_is_symbol_enum:
613 case oasys_record_is_section_enum:
614 break;
615 default:
616 loop = false;
617 }
618 }
619 return true;
620
621 }
622
623
624
625 bfd_error_vector_type bfd_error_vector;
626
627 static boolean
628 DEFUN(oasys_new_section_hook,(abfd, newsect),
629 bfd *abfd AND
630 asection *newsect)
631 {
632 newsect->used_by_bfd = (PTR)
633 bfd_alloc(abfd, sizeof(oasys_per_section_type));
634 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
635 oasys_per_section(newsect)->section = newsect;
636 oasys_per_section(newsect)->offset = 0;
637 newsect->alignment_power = 3;
638 /* Turn the section string into an index */
639
640 sscanf(newsect->name,"%u", &newsect->target_index);
641
642 return true;
643 }
644
645
646 static unsigned int
647 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
648 bfd *abfd AND
649 sec_ptr asect)
650 {
651 oasys_slurp_section_data(abfd);
652 return (asect->reloc_count+1) * sizeof(arelent *);
653 }
654
655 static boolean
656 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
657 bfd *abfd AND
658 sec_ptr section AND
659 PTR location AND
660 file_ptr offset AND
661 int count)
662 {
663 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
664 oasys_slurp_section_data(abfd);
665 (void) memcpy(location, p->data + offset, count);
666 return true;
667 }
668
669
670 unsigned int
671 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
672 bfd *abfd AND
673 sec_ptr section AND
674 arelent **relptr AND
675 asymbol **symbols)
676 {
677 unsigned int reloc_count = 0;
678 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
679 while (src != (oasys_reloc_type *)NULL) {
680 if (src->relent.section == (asection *)NULL)
681 {
682 src->relent.sym_ptr_ptr = symbols + src->symbol;
683 }
684 *relptr ++ = &src->relent;
685 src = src->next;
686 reloc_count++;
687 }
688 *relptr = (arelent *)NULL;
689 return section->reloc_count = reloc_count;
690 }
691
692
693 boolean
694 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
695 bfd *abfd AND
696 enum bfd_architecture arch AND
697 unsigned long machine)
698 {
699 abfd->obj_arch = arch;
700 abfd->obj_machine = machine;
701 return true;
702 }
703
704
705
706 /* Writing */
707
708
709 /* Calculate the checksum and write one record */
710 static void
711 DEFUN(oasys_write_record,(abfd, type, record, size),
712 bfd *CONST abfd AND
713 CONST oasys_record_enum_type type AND
714 oasys_record_union_type *record AND
715 CONST size_t size)
716 {
717 int checksum;
718 size_t i;
719 uint8e_type *ptr;
720 record->header.length = size;
721 record->header.type = type;
722 record->header.check_sum = 0;
723 record->header.fill = 0;
724 ptr = &record->pad[0];
725 checksum = 0;
726 for (i = 0; i < size; i++) {
727 checksum += *ptr++;
728 }
729 record->header.check_sum = 0xff & (- checksum);
730 bfd_write((PTR)record, 1, size, abfd);
731 }
732
733
734 /* Write out all the symbols */
735 static void
736 DEFUN(oasys_write_syms, (abfd),
737 bfd * CONST abfd)
738 {
739 unsigned int count;
740 asymbol **generic = bfd_get_outsymbols(abfd);
741 unsigned int index = 0;
742 for (count = 0; count < bfd_get_symcount(abfd); count++) {
743
744 oasys_symbol_record_type symbol;
745 asymbol * CONST g = generic[count];
746
747 CONST char *src = g->name;
748 char *dst = symbol.name;
749 unsigned int l = 0;
750
751 if (g->flags & BSF_FORT_COMM) {
752 symbol.relb = RELOCATION_TYPE_COM;
753 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
754 index++;
755 }
756 else if (g->flags & BSF_ABSOLUTE) {
757 symbol.relb = RELOCATION_TYPE_ABS;
758 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
759
760 }
761 else if (g->flags & BSF_UNDEFINED) {
762 symbol.relb = RELOCATION_TYPE_UND ;
763 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
764 /* Overload the value field with the output index number */
765 index++;
766 }
767 else if (g->flags & BSF_DEBUGGING) {
768 /* throw it away */
769 continue;
770 }
771 else {
772 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
773 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
774 }
775 while (src[l]) {
776 dst[l] = src[l];
777 l++;
778 }
779
780 bfd_h_putlong(abfd, g->value, symbol.value);
781
782
783 if (g->flags & BSF_LOCAL) {
784 oasys_write_record(abfd,
785 oasys_record_is_local_enum,
786 (oasys_record_union_type *) &symbol,
787 offsetof(oasys_symbol_record_type, name[0]) + l);
788 }
789 else {
790 oasys_write_record(abfd,
791 oasys_record_is_symbol_enum,
792 (oasys_record_union_type *) &symbol,
793 offsetof(oasys_symbol_record_type, name[0]) + l);
794 }
795 g->value = index-1;
796 }
797 }
798
799
800 /* Write a section header for each section */
801 static void
802 DEFUN(oasys_write_sections, (abfd),
803 bfd *CONST abfd)
804 {
805 asection *s;
806 static oasys_section_record_type out = {0};
807
808 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
809 if (!isdigit(s->name[0]))
810 {
811 bfd_error_vector.nonrepresentable_section(abfd,
812 s->name);
813 }
814 out.relb = RELOCATION_TYPE_REL | s->target_index;
815 bfd_h_putlong(abfd, s->size, out.value);
816 bfd_h_putlong(abfd, s->vma, out.vma);
817
818 oasys_write_record(abfd,
819 oasys_record_is_section_enum,
820 (oasys_record_union_type *) &out,
821 sizeof(out));
822 }
823 }
824
825 static void
826 DEFUN(oasys_write_header, (abfd),
827 bfd *CONST abfd)
828 {
829 /* Create and write the header */
830 oasys_header_record_type r;
831 size_t length = strlen(abfd->filename);
832 if (length > (size_t)sizeof(r.module_name)) {
833 length = sizeof(r.module_name);
834 }
835
836 (void)memcpy(r.module_name,
837 abfd->filename,
838 length);
839 (void)memset(r.module_name + length,
840 ' ',
841 sizeof(r.module_name) - length);
842
843 r.version_number = OASYS_VERSION_NUMBER;
844 r.rev_number = OASYS_REV_NUMBER;
845 oasys_write_record(abfd,
846 oasys_record_is_header_enum,
847 (oasys_record_union_type *)&r,
848 offsetof(oasys_header_record_type, description[0]));
849
850
851
852 }
853
854 static void
855 DEFUN(oasys_write_end,(abfd),
856 bfd *CONST abfd)
857 {
858 oasys_end_record_type end;
859 uint8e_type null = 0;
860 end.relb = RELOCATION_TYPE_ABS;
861 bfd_h_putlong(abfd, abfd->start_address, end.entry);
862 bfd_h_putshort(abfd, 0, end.fill);
863 end.zero =0;
864 oasys_write_record(abfd,
865 oasys_record_is_end_enum,
866 (oasys_record_union_type *)&end,
867 sizeof(end));
868 bfd_write((PTR)&null, 1, 1, abfd);
869 }
870
871 static int
872 DEFUN(comp,(ap, bp),
873 CONST PTR ap AND
874 CONST PTR bp)
875 {
876 arelent *a = *((arelent **)ap);
877 arelent *b = *((arelent **)bp);
878 return a->address - b->address;
879 }
880
881 /*
882 Writing data..
883
884 */
885 static void
886 DEFUN(oasys_write_data, (abfd),
887 bfd *CONST abfd)
888 {
889 asection *s;
890 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
891 uint8e_type *raw_data = oasys_per_section(s)->data;
892 oasys_data_record_type processed_data;
893 unsigned int current_byte_index = 0;
894 unsigned int relocs_to_go = s->reloc_count;
895 arelent **p = s->orelocation;
896 if (s->reloc_count != 0) {
897 /* Sort the reloc records so it's easy to insert the relocs into the
898 data */
899
900 qsort(s->orelocation,
901 s->reloc_count,
902 sizeof(arelent **),
903 comp);
904 }
905 current_byte_index = 0;
906 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
907
908 while ((size_t)current_byte_index < s->size)
909 {
910 /* Scan forwards by eight bytes or however much is left and see if
911 there are any relocations going on */
912 uint8e_type *mod = &processed_data.data[0];
913 uint8e_type *dst = &processed_data.data[1];
914
915 unsigned int i;
916 unsigned int long_length = 128;
917
918
919 bfd_h_putlong(abfd, s->vma + current_byte_index, processed_data.addr);
920 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
921 long_length = s->size - current_byte_index;
922 }
923 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
924
925 unsigned int length = long_length;
926 *mod =0;
927 if (length > 8)
928 length = 8;
929
930 for (i = 0; i < length; i++) {
931 if (relocs_to_go != 0) {
932 arelent *r = *p;
933 reloc_howto_type *CONST how=r->howto;
934 /* There is a relocation, is it for this byte ? */
935 if (r->address == current_byte_index) {
936 uint8e_type rel_byte;
937 p++;
938 relocs_to_go--;
939
940 *mod |= (1<<i);
941 if(how->pc_relative) {
942 rel_byte = 0x80;
943
944 /* Also patch the raw data so that it doesn't have
945 the -ve stuff any more */
946 if (how->size != 2) {
947 bfd_putshort(abfd,
948 bfd_getshort(abfd,raw_data) +
949 current_byte_index, raw_data);
950 }
951
952 else {
953 bfd_putlong(abfd,
954 bfd_getlong(abfd,raw_data) +
955 current_byte_index, raw_data);
956 }
957 }
958 else {
959 rel_byte = 0;
960 }
961 if (how->size ==2) {
962 rel_byte |= 0x40;
963 }
964
965 /* Is this a section relative relocation, or a symbol
966 relative relocation ? */
967 if (r->section != (asection*)NULL)
968 {
969 /* The relent has a section attatched, so it must be section
970 relative */
971 rel_byte |= RELOCATION_TYPE_REL;
972 rel_byte |= r->section->output_section->target_index;
973 *dst++ = rel_byte;
974 }
975 else
976 {
977 asymbol *p = *(r->sym_ptr_ptr);
978
979 /* If this symbol has a section attatched, then it
980 has already been resolved. Change from a symbol
981 ref to a section ref */
982 if(p->section != (asection *)NULL) {
983 rel_byte |= RELOCATION_TYPE_REL;
984 rel_byte |=
985 p->section->output_section->target_index;
986 *dst++ = rel_byte;
987 }
988 else {
989 rel_byte |= RELOCATION_TYPE_UND;
990
991
992 *dst++ = rel_byte;
993 /* Next two bytes are a symbol index - we can get
994 this from the symbol value which has been zapped
995 into the symbol index in the table when the
996 symbol table was written
997 */
998 *dst++ = p->value >> 8;
999 *dst++ = p->value;
1000 }
1001
1002 }
1003 }
1004 }
1005 /* If this is coming from an unloadable section then copy
1006 zeros */
1007 if (raw_data == (uint8e_type *)NULL) {
1008 *dst++ = 0;
1009 }
1010 else {
1011 *dst++ = *raw_data++;
1012 }
1013 current_byte_index++;
1014 }
1015 mod = dst++;
1016 long_length -= length;
1017 }
1018
1019 oasys_write_record(abfd,
1020 oasys_record_is_data_enum,
1021 (oasys_record_union_type *)&processed_data,
1022 dst - (uint8e_type*)&processed_data);
1023
1024 }
1025 }
1026 }
1027 static boolean
1028 DEFUN(oasys_write_object_contents, (abfd),
1029 bfd * CONST abfd)
1030 {
1031 oasys_write_header(abfd);
1032 oasys_write_syms(abfd);
1033 oasys_write_sections(abfd);
1034 oasys_write_data(abfd);
1035 oasys_write_end(abfd);
1036 return true;
1037 }
1038
1039
1040
1041
1042 /** exec and core file sections */
1043
1044 /* set section contents is complicated with OASYS since the format is
1045 * not a byte image, but a record stream.
1046 */
1047 static boolean
1048 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1049 bfd *abfd AND
1050 sec_ptr section AND
1051 PTR location AND
1052 file_ptr offset AND
1053 int count)
1054 {
1055 if (count != 0) {
1056 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1057 {
1058 oasys_per_section(section)->data =
1059 (bfd_byte *)(bfd_alloc(abfd,section->size));
1060 }
1061 (void) memcpy(oasys_per_section(section)->data + offset,
1062 location,
1063 count);
1064 }
1065 return true;
1066 }
1067
1068
1069
1070 /* Native-level interface to symbols. */
1071
1072 /* We read the symbols into a buffer, which is discarded when this
1073 function exits. We read the strings into a buffer large enough to
1074 hold them all plus all the cached symbol entries. */
1075
1076 static asymbol *
1077 DEFUN(oasys_make_empty_symbol,(abfd),
1078 bfd *abfd)
1079 {
1080
1081 oasys_symbol_type *new =
1082 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1083 new->symbol.the_bfd = abfd;
1084 return &new->symbol;
1085
1086 }
1087
1088
1089 \f
1090
1091 /* User should have checked the file flags; perhaps we should return
1092 BFD_NO_MORE_SYMBOLS if there are none? */
1093
1094 static bfd *
1095 oasys_openr_next_archived_file(arch, prev)
1096 bfd *arch;
1097 bfd *prev;
1098 {
1099 oasys_ar_data_type *ar = oasys_ar_data(arch);
1100 oasys_module_info_type *p;
1101 /* take the next one from the arch state, or reset */
1102 if (prev == (bfd *)NULL) {
1103 /* Reset the index - the first two entries are bogus*/
1104 ar->module_index = 0;
1105 }
1106
1107 p = ar->module + ar->module_index;
1108 ar->module_index++;
1109
1110 if (ar->module_index <= ar->module_count) {
1111 if (p->abfd == (bfd *)NULL) {
1112 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1113 p->abfd->origin = p->pos;
1114 p->abfd->filename = p->name;
1115
1116 /* Fixup a pointer to this element for the member */
1117 p->abfd->arelt_data = (PTR)p;
1118 }
1119 return p->abfd;
1120 }
1121 else {
1122 bfd_error = no_more_archived_files;
1123 return (bfd *)NULL;
1124 }
1125 }
1126
1127 static boolean
1128 oasys_find_nearest_line(abfd,
1129 section,
1130 symbols,
1131 offset,
1132 filename_ptr,
1133 functionname_ptr,
1134 line_ptr)
1135 bfd *abfd;
1136 asection *section;
1137 asymbol **symbols;
1138 bfd_vma offset;
1139 char **filename_ptr;
1140 char **functionname_ptr;
1141 unsigned int *line_ptr;
1142 {
1143 return false;
1144
1145 }
1146
1147 static int
1148 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1149 bfd *abfd AND
1150 struct stat *buf)
1151 {
1152 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1153 if (mod == (oasys_module_info_type *)NULL) {
1154 bfd_error = invalid_operation;
1155 return -1;
1156 }
1157 else {
1158 buf->st_size = mod->size;
1159 buf->st_mode = 0666;
1160 return 0;
1161 }
1162 }
1163
1164 static int
1165 DEFUN(oasys_sizeof_headers,(abfd, exec),
1166 bfd *abfd AND
1167 boolean exec)
1168 {
1169 return 0;
1170 }
1171
1172 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1173 #define oasys_core_file_failing_signal (int (*)())bfd_0
1174 #define oasys_core_file_matches_executable_p 0 /*(PROTO(boolean, (*),(bfd*, bfd*)))bfd_false*/
1175 #define oasys_slurp_armap bfd_true
1176 #define oasys_slurp_extended_name_table bfd_true
1177 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1178 #define oasys_write_armap 0 /* (PROTO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr*/
1179 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1180 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1181
1182
1183
1184 /*SUPPRESS 460 */
1185 bfd_target oasys_vec =
1186 {
1187 "oasys", /* name */
1188 bfd_target_oasys_flavour_enum,
1189 true, /* target byte order */
1190 true, /* target headers byte order */
1191 (HAS_RELOC | EXEC_P | /* object flags */
1192 HAS_LINENO | HAS_DEBUG |
1193 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1194 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1195 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1196 ' ', /* ar_pad_char */
1197 16, /* ar_max_namelen */
1198
1199 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1200 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1201
1202 {_bfd_dummy_target,
1203 oasys_object_p, /* bfd_check_format */
1204 oasys_archive_p,
1205 _bfd_dummy_target,
1206 },
1207 { /* bfd_set_format */
1208 bfd_false,
1209 oasys_mkobject,
1210 _bfd_generic_mkarchive,
1211 bfd_false
1212 },
1213 { /* bfd_write_contents */
1214 bfd_false,
1215 oasys_write_object_contents,
1216 _bfd_write_archive_contents,
1217 bfd_false,
1218 },
1219 JUMP_TABLE(oasys)
1220 };
This page took 0.055179 seconds and 5 git commands to generate.