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