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