]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/oasys.c
Uses the new small reloc type now.
[thirdparty/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 "bfd.h"
25 #include "sysdep.h"
26 #include "libbfd.h"
27 #include "oasys.h"
28 #include "liboasys.h"
29
30 /* XXX - FIXME. offsetof belongs in the system-specific files in
31 ../include/sys. */
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 == (int)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 = &bfd_abs_section;
128 dest->flags = 0;
129
130 break;
131 case RELOCATION_TYPE_REL:
132 dest = dest_defined--;
133 dest->section =
134 OASYS_DATA(abfd)->sections[record.symbol.relb &
135 RELOCATION_SECT_BITS];
136 if (record.header.type == (int)oasys_record_is_local_enum)
137 {
138 dest->flags = BSF_LOCAL;
139 if (dest->section ==(asection *)(~0)) {
140 /* It seems that sometimes internal symbols are tied up, but
141 still get output, even though there is no
142 section */
143 dest->section = 0;
144 }
145 }
146 else {
147
148 dest->flags = flag;
149 }
150 break;
151 case RELOCATION_TYPE_UND:
152 dest = data->symbols + bfd_h_get_16(abfd, (bfd_byte *)&record.symbol.refno[0]);
153 dest->section = &bfd_und_section;
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 = &bfd_com_section;
161
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 abfd->tdata.oasys_ar_data = 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
351 abfd->tdata.oasys_obj_data = (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type));
352 return true;
353 }
354
355 #define MAX_SECS 16
356 static bfd_target *
357 DEFUN(oasys_object_p,(abfd),
358 bfd *abfd)
359 {
360 oasys_data_type *oasys;
361 oasys_data_type *save = OASYS_DATA(abfd);
362 boolean loop = true;
363 boolean had_usefull = false;
364
365 abfd->tdata.oasys_obj_data = 0;
366 oasys_mkobject(abfd);
367 oasys = OASYS_DATA(abfd);
368 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
369
370 /* Point to the start of the file */
371 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
372 oasys->symbol_string_length = 0;
373 /* Inspect the records, but only keep the section info -
374 remember the size of the symbols
375 */
376 oasys->first_data_record = 0;
377 while (loop) {
378 oasys_record_union_type record;
379 oasys_read_record(abfd, &record);
380 if ((size_t)record.header.length < (size_t)sizeof(record.header))
381 goto fail;
382
383
384 switch ((oasys_record_enum_type)(record.header.type)) {
385 case oasys_record_is_header_enum:
386 had_usefull = true;
387 break;
388 case oasys_record_is_symbol_enum:
389 case oasys_record_is_local_enum:
390 /* Count symbols and remember their size for a future malloc */
391 abfd->symcount++;
392 oasys->symbol_string_length += 1 + oasys_string_length(&record);
393 had_usefull = true;
394 break;
395 case oasys_record_is_section_enum:
396 {
397 asection *s;
398 char *buffer;
399 unsigned int section_number;
400 if (record.section.header.length != sizeof(record.section))
401 {
402 goto fail;
403 }
404 buffer = bfd_alloc(abfd, 3);
405 section_number= record.section.relb & RELOCATION_SECT_BITS;
406 sprintf(buffer,"%u", section_number);
407 s = bfd_make_section(abfd,buffer);
408 oasys->sections[section_number] = s;
409 switch (record.section.relb & RELOCATION_TYPE_BITS) {
410 case RELOCATION_TYPE_ABS:
411 case RELOCATION_TYPE_REL:
412 break;
413 case RELOCATION_TYPE_UND:
414 case RELOCATION_TYPE_COM:
415 BFD_FAIL();
416 }
417
418 s->_raw_size = bfd_h_get_32(abfd, (bfd_byte *) & record.section.value[0]) ;
419 s->vma = bfd_h_get_32(abfd, (bfd_byte *)&record.section.vma[0]);
420 s->flags= 0;
421 had_usefull = true;
422 }
423 break;
424 case oasys_record_is_data_enum:
425 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
426 case oasys_record_is_debug_enum:
427 case oasys_record_is_module_enum:
428 case oasys_record_is_named_section_enum:
429 case oasys_record_is_end_enum:
430 if (had_usefull == false) goto fail;
431 loop = false;
432 break;
433 default:
434 goto fail;
435 }
436 }
437 oasys->symbols = (asymbol *)NULL;
438 /*
439 Oasys support several architectures, but I can't see a simple way
440 to discover which one is in a particular file - we'll guess
441 */
442 bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0);
443 if (abfd->symcount != 0) {
444 abfd->flags |= HAS_SYMS;
445 }
446
447 /*
448 We don't know if a section has data until we've read it..
449 */
450
451 oasys_slurp_section_data(abfd);
452
453
454 return abfd->xvec;
455
456 fail:
457 (void) bfd_release(abfd, oasys);
458 abfd->tdata.oasys_obj_data = save;
459 return (bfd_target *)NULL;
460 }
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 case bfd_print_symbol_nm:
479 {
480 CONST char *section_name = symbol->section == (asection *)NULL ?
481 (CONST char *) "*abs" : symbol->section->name;
482
483 bfd_print_symbol_vandf((PTR)file,symbol);
484
485 fprintf(file," %-5s %s",
486 section_name,
487 symbol->name);
488 }
489 break;
490 }
491 }
492 /*
493 The howto table is build using the top two bits of a reloc byte to
494 index into it. The bits are PCREL,WORD/LONG
495 */
496 static reloc_howto_type howto_table[]=
497 {
498
499 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
500 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
501 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
502 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
503 };
504
505 /* Read in all the section data and relocation stuff too */
506 static boolean
507 DEFUN(oasys_slurp_section_data,(abfd),
508 bfd *CONST abfd)
509 {
510 oasys_record_union_type record;
511 oasys_data_type *data = OASYS_DATA(abfd);
512 boolean loop = true;
513
514 oasys_per_section_type *per ;
515
516 asection *s;
517
518 /* See if the data has been slurped already .. */
519 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
520 per = oasys_per_section(s);
521 if (per->initialized == true)
522 return true;
523 }
524
525 if (data->first_data_record == 0) return true;
526
527 bfd_seek(abfd, data->first_data_record, SEEK_SET);
528 while (loop) {
529 oasys_read_record(abfd, &record);
530 switch (record.header.type)
531 {
532 case oasys_record_is_header_enum:
533 break;
534 case oasys_record_is_data_enum:
535 {
536
537 uint8e_type *src = record.data.data;
538 uint8e_type *end_src = ((uint8e_type *)&record) +
539 record.header.length;
540 unsigned int relbit;
541 bfd_byte *dst_ptr ;
542 bfd_byte *dst_base_ptr ;
543 unsigned int count;
544 asection * section =
545 data->sections[record.data.relb & RELOCATION_SECT_BITS];
546 bfd_vma dst_offset ;
547 per = oasys_per_section(section);
548
549
550 if (per->initialized == false)
551 {
552 per->data = (bfd_byte *) bfd_zalloc(abfd, section->_raw_size);
553 per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
554 per->had_vma = false;
555 per->initialized = true;
556 section->reloc_count = 0;
557 section->flags = SEC_ALLOC;
558 }
559
560 dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
561 if (per->had_vma == false) {
562 /* Take the first vma we see as the base */
563
564 section->vma = dst_offset;
565 per->had_vma = true;
566 }
567
568
569 dst_offset -= section->vma;
570
571
572 dst_base_ptr = oasys_per_section(section)->data;
573 dst_ptr = oasys_per_section(section)->data +
574 dst_offset;
575
576 if (src < end_src) {
577 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
578 }
579 while (src < end_src) {
580 uint8e_type mod_byte = *src++;
581 uint32_type gap = end_src - src;
582
583 count = 8;
584 if (mod_byte == 0 && gap >= 8) {
585 dst_ptr[0] = src[0];
586 dst_ptr[1] = src[1];
587 dst_ptr[2] = src[2];
588 dst_ptr[3] = src[3];
589 dst_ptr[4] = src[4];
590 dst_ptr[5] = src[5];
591 dst_ptr[6] = src[6];
592 dst_ptr[7] = src[7];
593 dst_ptr+= 8;
594 src += 8;
595 }
596 else {
597 for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
598 {
599 if (relbit & mod_byte)
600 {
601 uint8e_type reloc = *src;
602 /* This item needs to be relocated */
603 switch (reloc & RELOCATION_TYPE_BITS) {
604 case RELOCATION_TYPE_ABS:
605
606 break;
607
608 case RELOCATION_TYPE_REL:
609 {
610 /* Relocate the item relative to the section */
611 oasys_reloc_type *r =
612 (oasys_reloc_type *)
613 bfd_alloc(abfd,
614 sizeof(oasys_reloc_type));
615 *(per->reloc_tail_ptr) = r;
616 per->reloc_tail_ptr = &r->next;
617 r->next= (oasys_reloc_type *)NULL;
618 /* Reference to undefined symbol */
619 src++;
620 /* There is no symbol */
621 r->symbol = 0;
622 /* Work out the howto */
623 abort();
624 #if 0
625 r->relent.section =
626 data->sections[reloc &
627 RELOCATION_SECT_BITS];
628
629 r->relent.addend = -
630 r->relent.section->vma;
631 #endif
632 r->relent.address = dst_ptr - dst_base_ptr;
633 r->relent.howto = &howto_table[reloc>>6];
634 r->relent.sym_ptr_ptr = (asymbol **)NULL;
635 section->reloc_count++;
636
637 /* Fake up the data to look like it's got the -ve pc in it, this makes
638 it much easier to convert into other formats. This is done by
639 hitting the addend.
640 */
641 if (r->relent.howto->pc_relative == true) {
642 r->relent.addend -= dst_ptr - dst_base_ptr;
643 }
644
645
646 }
647 break;
648
649
650 case RELOCATION_TYPE_UND:
651 {
652 oasys_reloc_type *r =
653 (oasys_reloc_type *)
654 bfd_alloc(abfd,
655 sizeof(oasys_reloc_type));
656 *(per->reloc_tail_ptr) = r;
657 per->reloc_tail_ptr = &r->next;
658 r->next= (oasys_reloc_type *)NULL;
659 /* Reference to undefined symbol */
660 src++;
661 /* Get symbol number */
662 r->symbol = (src[0]<<8) | src[1];
663 /* Work out the howto */
664 abort();
665
666 #if 0
667 r->relent.section = (asection
668 *)NULL;
669 #endif
670 r->relent.addend = 0;
671 r->relent.address = dst_ptr - dst_base_ptr;
672 r->relent.howto = &howto_table[reloc>>6];
673 r->relent.sym_ptr_ptr = (asymbol **)NULL;
674 section->reloc_count++;
675
676 src+=2;
677 /* Fake up the data to look like it's got the -ve pc in it, this makes
678 it much easier to convert into other formats. This is done by
679 hitting the addend.
680 */
681 if (r->relent.howto->pc_relative == true) {
682 r->relent.addend -= dst_ptr - dst_base_ptr;
683 }
684
685
686
687 }
688 break;
689 case RELOCATION_TYPE_COM:
690 BFD_FAIL();
691 }
692 }
693 *dst_ptr++ = *src++;
694 }
695 }
696 }
697 }
698 break;
699 case oasys_record_is_local_enum:
700 case oasys_record_is_symbol_enum:
701 case oasys_record_is_section_enum:
702 break;
703 default:
704 loop = false;
705 }
706 }
707
708 return true;
709
710 }
711
712
713
714 bfd_error_vector_type bfd_error_vector;
715
716 static boolean
717 DEFUN(oasys_new_section_hook,(abfd, newsect),
718 bfd *abfd AND
719 asection *newsect)
720 {
721 newsect->used_by_bfd = (PTR)
722 bfd_alloc(abfd, sizeof(oasys_per_section_type));
723 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
724 oasys_per_section(newsect)->section = newsect;
725 oasys_per_section(newsect)->offset = 0;
726 oasys_per_section(newsect)->initialized = false;
727 newsect->alignment_power = 1;
728 /* Turn the section string into an index */
729
730 sscanf(newsect->name,"%u", &newsect->target_index);
731
732 return true;
733 }
734
735
736 static unsigned int
737 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
738 bfd *abfd AND
739 sec_ptr asect)
740 {
741 oasys_slurp_section_data(abfd);
742 return (asect->reloc_count+1) * sizeof(arelent *);
743 }
744
745 static boolean
746 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
747 bfd *abfd AND
748 sec_ptr section AND
749 PTR location AND
750 file_ptr offset AND
751 bfd_size_type count)
752 {
753 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
754 oasys_slurp_section_data(abfd);
755 if (p->initialized == false)
756 {
757 (void) memset(location, 0, (int)count);
758 }
759 else
760 {
761 (void) memcpy(location,(PTR)( p->data + offset), (int)count);
762 }
763 return true;
764 }
765
766
767 unsigned int
768 DEFUN(oasys_canonicalize_reloc,(ignore_abfd, section, relptr, symbols),
769 bfd *ignore_abfd AND
770 sec_ptr section AND
771 arelent **relptr AND
772 asymbol **symbols)
773 {
774 unsigned int reloc_count = 0;
775 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
776 while (src != (oasys_reloc_type *)NULL) {
777 abort();
778
779 #if 0
780 if (src->relent.section == (asection *)NULL)
781 {
782 src->relent.sym_ptr_ptr = symbols + src->symbol;
783 }
784 #endif
785
786 *relptr ++ = &src->relent;
787 src = src->next;
788 reloc_count++;
789 }
790 *relptr = (arelent *)NULL;
791 return section->reloc_count = reloc_count;
792 }
793
794
795
796
797 /* Writing */
798
799
800 /* Calculate the checksum and write one record */
801 static void
802 DEFUN(oasys_write_record,(abfd, type, record, size),
803 bfd *CONST abfd AND
804 CONST oasys_record_enum_type type AND
805 oasys_record_union_type *record AND
806 CONST size_t size)
807 {
808 int checksum;
809 size_t i;
810 uint8e_type *ptr;
811 record->header.length = size;
812 record->header.type = (int)type;
813 record->header.check_sum = 0;
814 record->header.fill = 0;
815 ptr = &record->pad[0];
816 checksum = 0;
817 for (i = 0; i < size; i++) {
818 checksum += *ptr++;
819 }
820 record->header.check_sum = 0xff & (- checksum);
821 bfd_write((PTR)record, 1, size, abfd);
822 }
823
824
825 /* Write out all the symbols */
826 static void
827 DEFUN(oasys_write_syms, (abfd),
828 bfd * CONST abfd)
829 {
830 unsigned int count;
831 asymbol **generic = bfd_get_outsymbols(abfd);
832 unsigned int index = 0;
833 for (count = 0; count < bfd_get_symcount(abfd); count++) {
834
835 oasys_symbol_record_type symbol;
836 asymbol * CONST g = generic[count];
837
838 CONST char *src = g->name;
839 char *dst = symbol.name;
840 unsigned int l = 0;
841
842 if (g->section == & bfd_com_section) {
843 symbol.relb = RELOCATION_TYPE_COM;
844 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
845 index++;
846 }
847 else if (g->section == & bfd_abs_section) {
848 symbol.relb = RELOCATION_TYPE_ABS;
849 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
850
851 }
852 else if (g->section == &bfd_und_section) {
853 symbol.relb = RELOCATION_TYPE_UND ;
854 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
855 /* Overload the value field with the output index number */
856 index++;
857 }
858 else if (g->flags & BSF_DEBUGGING) {
859 /* throw it away */
860 continue;
861 }
862 else {
863 if (g->section == (asection *)NULL) {
864 /* Sometime, the oasys tools give out a symbol with illegal
865 bits in it, we'll output it in the same broken way */
866
867 symbol.relb = RELOCATION_TYPE_REL | 0;
868 }
869 else {
870 symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
871 }
872 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
873 }
874 while (src[l]) {
875 dst[l] = src[l];
876 l++;
877 }
878
879 bfd_h_put_32(abfd, g->value, (bfd_byte*) 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 = {0};
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, (bfd_byte *) out.value);
915 bfd_h_put_32(abfd, s->vma, (bfd_byte *) 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 uint8e_type null = 0;
959 end.relb = RELOCATION_TYPE_ABS;
960 bfd_h_put_32(abfd, abfd->start_address, (bfd_byte *)end.entry);
961 bfd_h_put_16(abfd, 0, (bfd_byte *)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 uint8e_type *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 uint8e_type *mod = &processed_data.data[0];
1013 uint8e_type *dst = &processed_data.data[1];
1014
1015 unsigned int i;
1016 unsigned int long_length = 128;
1017
1018
1019 bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
1020 if ((size_t)(long_length + current_byte_index) > (size_t)(s->_cooked_size)) {
1021 long_length = s->_cooked_size - current_byte_index;
1022 }
1023 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
1024
1025 unsigned int length = long_length;
1026 *mod =0;
1027 if (length > 8)
1028 length = 8;
1029
1030 for (i = 0; i < length; i++) {
1031 if (relocs_to_go != 0) {
1032 arelent *r = *p;
1033 reloc_howto_type *CONST how=r->howto;
1034 /* There is a relocation, is it for this byte ? */
1035 if (r->address == current_byte_index) {
1036 uint8e_type rel_byte;
1037 p++;
1038 relocs_to_go--;
1039
1040 *mod |= (1<<i);
1041 if(how->pc_relative) {
1042 rel_byte = 0x80;
1043
1044 /* Also patch the raw data so that it doesn't have
1045 the -ve stuff any more */
1046 if (how->size != 2) {
1047 bfd_put_16(abfd,
1048 bfd_get_16(abfd,raw_data) +
1049 current_byte_index, raw_data);
1050 }
1051
1052 else {
1053 bfd_put_32(abfd,
1054 bfd_get_32(abfd,raw_data) +
1055 current_byte_index, raw_data);
1056 }
1057 }
1058 else {
1059 rel_byte = 0;
1060 }
1061 if (how->size ==2) {
1062 rel_byte |= 0x40;
1063 }
1064
1065 /* Is this a section relative relocation, or a symbol
1066 relative relocation ? */
1067 abort();
1068
1069 #if 0
1070 if (r->section != (asection*)NULL)
1071 {
1072 /* The relent has a section attached, so it must be section
1073 relative */
1074 rel_byte |= RELOCATION_TYPE_REL;
1075 rel_byte |= r->section->output_section->target_index;
1076 *dst++ = rel_byte;
1077 }
1078 else
1079 #endif
1080 {
1081 asymbol *p = *(r->sym_ptr_ptr);
1082
1083 /* If this symbol has a section attached, then it
1084 has already been resolved. Change from a symbol
1085 ref to a section ref */
1086 if(p->section != (asection *)NULL) {
1087 rel_byte |= RELOCATION_TYPE_REL;
1088 rel_byte |=
1089 p->section->output_section->target_index;
1090 *dst++ = rel_byte;
1091 }
1092 else {
1093 rel_byte |= RELOCATION_TYPE_UND;
1094
1095
1096 *dst++ = rel_byte;
1097 /* Next two bytes are a symbol index - we can get
1098 this from the symbol value which has been zapped
1099 into the symbol index in the table when the
1100 symbol table was written
1101 */
1102 *dst++ = p->value >> 8;
1103 *dst++ = p->value;
1104 }
1105
1106 }
1107 }
1108 }
1109 /* If this is coming from an unloadable section then copy
1110 zeros */
1111 if (raw_data == (uint8e_type *)NULL) {
1112 *dst++ = 0;
1113 }
1114 else {
1115 *dst++ = *raw_data++;
1116 }
1117 current_byte_index++;
1118 }
1119 mod = dst++;
1120 long_length -= length;
1121 }
1122
1123 oasys_write_record(abfd,
1124 oasys_record_is_data_enum,
1125 (oasys_record_union_type *)&processed_data,
1126 dst - (uint8e_type*)&processed_data);
1127
1128 }
1129 }
1130 }
1131 }
1132 static boolean
1133 DEFUN(oasys_write_object_contents, (abfd),
1134 bfd * CONST abfd)
1135 {
1136 oasys_write_header(abfd);
1137 oasys_write_syms(abfd);
1138 oasys_write_sections(abfd);
1139 oasys_write_data(abfd);
1140 oasys_write_end(abfd);
1141 return true;
1142 }
1143
1144
1145
1146
1147 /** exec and core file sections */
1148
1149 /* set section contents is complicated with OASYS since the format is
1150 * not a byte image, but a record stream.
1151 */
1152 static boolean
1153 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1154 bfd *abfd AND
1155 sec_ptr section AND
1156 PTR location AND
1157 file_ptr offset AND
1158 bfd_size_type count)
1159 {
1160 if (count != 0) {
1161 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1162 {
1163 oasys_per_section(section)->data =
1164 (bfd_byte *)(bfd_alloc(abfd,section->_cooked_size));
1165 }
1166 (void) memcpy((PTR)(oasys_per_section(section)->data + offset),
1167 location,
1168 count);
1169 }
1170 return true;
1171 }
1172
1173
1174
1175 /* Native-level interface to symbols. */
1176
1177 /* We read the symbols into a buffer, which is discarded when this
1178 function exits. We read the strings into a buffer large enough to
1179 hold them all plus all the cached symbol entries. */
1180
1181 static asymbol *
1182 DEFUN(oasys_make_empty_symbol,(abfd),
1183 bfd *abfd)
1184 {
1185
1186 oasys_symbol_type *new =
1187 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1188 new->symbol.the_bfd = abfd;
1189 return &new->symbol;
1190
1191 }
1192
1193
1194 \f
1195
1196 /* User should have checked the file flags; perhaps we should return
1197 BFD_NO_MORE_SYMBOLS if there are none? */
1198
1199 static bfd *
1200 oasys_openr_next_archived_file(arch, prev)
1201 bfd *arch;
1202 bfd *prev;
1203 {
1204 oasys_ar_data_type *ar = OASYS_AR_DATA(arch);
1205 oasys_module_info_type *p;
1206 /* take the next one from the arch state, or reset */
1207 if (prev == (bfd *)NULL) {
1208 /* Reset the index - the first two entries are bogus*/
1209 ar->module_index = 0;
1210 }
1211
1212 p = ar->module + ar->module_index;
1213 ar->module_index++;
1214
1215 if (ar->module_index <= ar->module_count) {
1216 if (p->abfd == (bfd *)NULL) {
1217 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1218 p->abfd->origin = p->pos;
1219 p->abfd->filename = p->name;
1220
1221 /* Fixup a pointer to this element for the member */
1222 p->abfd->arelt_data = (PTR)p;
1223 }
1224 return p->abfd;
1225 }
1226 else {
1227 bfd_error = no_more_archived_files;
1228 return (bfd *)NULL;
1229 }
1230 }
1231
1232 static boolean
1233 oasys_find_nearest_line(abfd,
1234 section,
1235 symbols,
1236 offset,
1237 filename_ptr,
1238 functionname_ptr,
1239 line_ptr)
1240 bfd *abfd;
1241 asection *section;
1242 asymbol **symbols;
1243 bfd_vma offset;
1244 char **filename_ptr;
1245 char **functionname_ptr;
1246 unsigned int *line_ptr;
1247 {
1248 return false;
1249
1250 }
1251
1252 static int
1253 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1254 bfd *abfd AND
1255 struct stat *buf)
1256 {
1257 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1258 if (mod == (oasys_module_info_type *)NULL) {
1259 bfd_error = invalid_operation;
1260 return -1;
1261 }
1262 else {
1263 buf->st_size = mod->size;
1264 buf->st_mode = 0666;
1265 return 0;
1266 }
1267 }
1268
1269 static int
1270 DEFUN(oasys_sizeof_headers,(abfd, exec),
1271 bfd *abfd AND
1272 boolean exec)
1273 {
1274 return 0;
1275 }
1276 #define FOO PROTO
1277 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1278 #define oasys_core_file_failing_signal (int (*)())bfd_0
1279 #define oasys_core_file_matches_executable_p 0
1280 #define oasys_slurp_armap bfd_true
1281 #define oasys_slurp_extended_name_table bfd_true
1282 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1283 #define oasys_write_armap 0
1284 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1285 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1286 #define oasys_set_arch_mach bfd_default_set_arch_mach
1287 #define oasys_bfd_debug_info_start bfd_void
1288 #define oasys_bfd_debug_info_end bfd_void
1289 #define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
1290 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1291
1292 /*SUPPRESS 460 */
1293 bfd_target oasys_vec =
1294 {
1295 "oasys", /* name */
1296 bfd_target_oasys_flavour,
1297 true, /* target byte order */
1298 true, /* target headers byte order */
1299 (HAS_RELOC | EXEC_P | /* object flags */
1300 HAS_LINENO | HAS_DEBUG |
1301 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1302 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1303 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1304 ' ', /* ar_pad_char */
1305 16, /* ar_max_namelen */
1306 1, /* minimum alignment */
1307 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
1308 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1309
1310 {_bfd_dummy_target,
1311 oasys_object_p, /* bfd_check_format */
1312 oasys_archive_p,
1313 _bfd_dummy_target,
1314 },
1315 { /* bfd_set_format */
1316 bfd_false,
1317 oasys_mkobject,
1318 _bfd_generic_mkarchive,
1319 bfd_false
1320 },
1321 { /* bfd_write_contents */
1322 bfd_false,
1323 oasys_write_object_contents,
1324 _bfd_write_archive_contents,
1325 bfd_false,
1326 },
1327 JUMP_TABLE(oasys)
1328 };