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