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