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