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