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