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