9f3c91679a67133fd4b3691707eb69009fc7e618
[deliverable/binutils-gdb.git] / bfd / oasys.c
1 #define UNDERSCORE_HACK 1
2 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
3 /*
4
5 bfd backend for oasys objects.
6
7
8 Written by Steve Chamberlain
9 steve@cygnus.com
10
11 $Id$
12
13
14 */
15
16
17 #include <ansidecl.h>
18 #include "sysdep.h"
19 #include "bfd.h"
20 #include "libbfd.h"
21 #include "obstack.h"
22 #include "oasys.h"
23 #include "liboasys.h"
24
25
26
27
28
29
30 static void
31 DEFUN(oasys_read_record,(abfd, record),
32 bfd *CONST abfd AND
33 oasys_record_union_type *record)
34 {
35
36 bfd_read(record, 1, sizeof(record->header), abfd);
37
38 bfd_read(((char *)record )+ sizeof(record->header),
39 1, record->header.length - sizeof(record->header),
40 abfd);
41 }
42 static size_t
43 DEFUN(oasys_string_length,(record),
44 oasys_record_union_type *record)
45 {
46 return record->header.length
47 - ((char *)record->symbol.name - (char *)record);
48 }
49
50 /*****************************************************************************/
51
52 /*
53
54 Slurp the symbol table by reading in all the records at the start file
55 till we get to the first section record.
56
57 We'll sort the symbolss into two lists, defined and undefined. The
58 undefined symbols will be placed into the table according to their
59 refno.
60
61 We do this by placing all undefined symbols at the front of the table
62 moving in, and the defined symbols at the end of the table moving back.
63
64 */
65
66 static boolean
67 DEFUN(oasys_slurp_symbol_table,(abfd),
68 bfd * CONST abfd)
69 {
70 oasys_record_union_type record;
71 oasys_data_type *data = oasys_data(abfd);
72 boolean loop = true;
73 asymbol *dest_undefined;
74 asymbol *dest_defined;
75 asymbol *dest;
76 char *string_ptr;
77
78
79 if (data->symbols != (asymbol *)NULL) {
80 return true;
81 }
82 /* Buy enough memory for all the symbols and all the names */
83 data->symbols =
84 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
85 #ifdef UNDERSCORE_HACK
86 /* buy 1 more char for each symbol to keep the underscore in*/
87 data->strings = bfd_alloc(abfd, data->symbol_string_length +
88 abfd->symcount);
89 #else
90 data->strings = bfd_alloc(abfd, data->symbol_string_length);
91 #endif
92
93 dest_undefined = data->symbols;
94 dest_defined = data->symbols + abfd->symcount -1;
95
96 string_ptr = data->strings;
97 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
98 while (loop) {
99
100 oasys_read_record(abfd, &record);
101 switch (record.header.type) {
102 case oasys_record_is_header_enum:
103 break;
104 case oasys_record_is_local_enum:
105 case oasys_record_is_symbol_enum:
106 {
107 int flag = record.header.type == oasys_record_is_local_enum ?
108 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
109
110
111 size_t length = oasys_string_length(&record);
112 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
113 case RELOCATION_TYPE_ABS:
114 dest = dest_defined--;
115 dest->section = 0;
116 dest->flags = BSF_ABSOLUTE | flag;
117 break;
118 case RELOCATION_TYPE_REL:
119 dest = dest_defined--;
120 dest->section =
121 oasys_data(abfd)->sections[record.symbol.relb &
122 RELOCATION_SECT_BITS];
123 if (record.header.type == oasys_record_is_local_enum)
124 {
125 dest->flags = BSF_LOCAL;
126 }
127 else {
128
129 dest->flags = flag;
130 }
131 break;
132 case RELOCATION_TYPE_UND:
133 dest = data->symbols + bfd_h_getshort(abfd, &record.symbol.refno[0]);
134 dest->section = (asection *)NULL;
135 dest->flags = BSF_UNDEFINED;
136 break;
137 case RELOCATION_TYPE_COM:
138 dest = dest_defined--;
139 dest->name = string_ptr;
140 dest->the_bfd = abfd;
141
142 dest->section = (asection *)NULL;
143 dest->flags = BSF_FORT_COMM;
144 break;
145 }
146 dest->name = string_ptr;
147 dest->the_bfd = abfd;
148 dest->udata = (PTR)NULL;
149 dest->value = bfd_h_getlong(abfd, &record.symbol.value[0]);
150
151 #ifdef UNDERSCORE_HACK
152 if (record.symbol.name[0] != '_') {
153 string_ptr[0] = '_';
154 string_ptr++;
155 }
156 #endif
157 memcpy(string_ptr, record.symbol.name, length);
158
159
160 string_ptr[length] =0;
161 string_ptr += length +1;
162 }
163 break;
164 default:
165 loop = false;
166 }
167 }
168 return true;
169
170 }
171
172 static size_t
173 DEFUN(oasys_get_symtab_upper_bound,(abfd),
174 bfd *CONST abfd)
175 {
176 oasys_slurp_symbol_table (abfd);
177
178 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
179 }
180
181 /*
182 */
183
184 extern bfd_target oasys_vec;
185
186 unsigned int
187 DEFUN(oasys_get_symtab,(abfd, location),
188 bfd *abfd AND
189 asymbol **location)
190 {
191 asymbol *symbase ;
192 unsigned int counter ;
193 if (oasys_slurp_symbol_table(abfd) == false) {
194 return 0;
195 }
196 symbase = oasys_data(abfd)->symbols;
197 for (counter = 0; counter < abfd->symcount; counter++) {
198 *(location++) = symbase++;
199 }
200 *location = 0;
201 return abfd->symcount;
202 }
203
204 /***********************************************************************
205 * archive stuff
206 */
207 #define swap(x) x = bfd_h_get_x(abfd, &x);
208 static bfd_target *
209 DEFUN(oasys_archive_p,(abfd),
210 bfd *abfd)
211 {
212 oasys_archive_header_type header;
213 unsigned int i;
214
215 bfd_seek(abfd, (file_ptr) 0, false);
216
217
218 bfd_read(&header, 1, sizeof(header), abfd);
219
220
221 swap(header.version);
222 swap(header.mod_count);
223 swap(header.mod_tbl_offset);
224 swap(header.sym_tbl_size);
225 swap(header.sym_count);
226 swap(header.sym_tbl_offset);
227 swap(header.xref_count);
228 swap(header.xref_lst_offset);
229
230 /*
231 There isn't a magic number in an Oasys archive, so the best we
232 can do to verify reasnableness is to make sure that the values in
233 the header are too weird
234 */
235
236 if (header.version>10000 ||
237 header.mod_count>10000 ||
238 header.sym_count>100000 ||
239 header.xref_count > 100000) return (bfd_target *)NULL;
240
241 /*
242 That all worked, lets buy the space for the header and read in
243 the headers.
244 */
245 {
246 oasys_ar_data_type *ar =
247 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
248
249
250 oasys_module_info_type *module =
251 (oasys_module_info_type*)
252 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
253
254 oasys_module_table_type record;
255
256 oasys_ar_data(abfd) =ar;
257 ar->module = module;
258 ar->module_count = header.mod_count;
259
260 bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
261 for (i = 0; i < header.mod_count; i++) {
262
263 bfd_read(&record, 1, sizeof(record), abfd);
264 swap(record.mod_size);
265 swap(record.file_offset);
266 swap(record.mod_name_length);
267 module[i].name = bfd_alloc(abfd,record.mod_name_length+1);
268
269 bfd_read(module[i].name, 1, record.mod_name_length +1, abfd);
270 /* SKip some stuff */
271 bfd_seek(abfd, record.dep_count * sizeof(int32_type),
272 SEEK_CUR);
273
274 module[i].size = record.mod_size;
275 module[i].pos = record.file_offset;
276 }
277
278 }
279 return abfd->xvec;
280 }
281
282 static boolean
283 DEFUN(oasys_mkobject,(abfd),
284 bfd *abfd)
285 {
286 oasys_data_type *oasys;
287
288 oasys_data(abfd) =
289 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type));
290 oasys = oasys_data(abfd);
291 return true;
292 }
293
294 #define MAX_SECS 16
295 static bfd_target *
296 DEFUN(oasys_object_p,(abfd),
297 bfd *abfd)
298 {
299 oasys_data_type *oasys;
300 boolean loop = true;
301 boolean had_usefull = false;
302 oasys_data(abfd) = 0;
303 oasys_mkobject(abfd);
304 oasys = oasys_data(abfd);
305 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
306
307 /* Point to the start of the file */
308 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
309 oasys->symbol_string_length = 0;
310 /* Inspect the records, but only keep the section info -
311 remember the size of the symbols
312 */
313 oasys->first_data_record = 0;
314 while (loop) {
315 oasys_record_union_type record;
316 oasys_read_record(abfd, &record);
317 if ((size_t)record.header.length < (size_t)sizeof(record.header))
318 goto fail;
319
320
321 switch ((oasys_record_enum_type)(record.header.type)) {
322 case oasys_record_is_header_enum:
323 had_usefull = true;
324 break;
325 case oasys_record_is_symbol_enum:
326 case oasys_record_is_local_enum:
327 /* Count symbols and remember their size for a future malloc */
328 abfd->symcount++;
329 oasys->symbol_string_length += 1 + oasys_string_length(&record);
330 had_usefull = true;
331 break;
332 case oasys_record_is_section_enum:
333 {
334 asection *s;
335 char *buffer;
336 unsigned int section_number;
337 if (record.section.header.length != sizeof(record.section))
338 {
339 goto fail;
340 }
341 buffer = bfd_alloc(abfd, 3);
342 section_number= record.section.relb & RELOCATION_SECT_BITS;
343 sprintf(buffer,"%u", section_number);
344 s = bfd_make_section(abfd,buffer);
345 oasys->sections[section_number] = s;
346 switch (record.section.relb & RELOCATION_TYPE_BITS) {
347 case RELOCATION_TYPE_ABS:
348 case RELOCATION_TYPE_REL:
349 break;
350 case RELOCATION_TYPE_UND:
351 case RELOCATION_TYPE_COM:
352 BFD_FAIL();
353 }
354
355 s->size = bfd_h_getlong(abfd, & record.section.value[0]) ;
356 s->vma = bfd_h_getlong(abfd, &record.section.vma[0]);
357 s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
358 had_usefull = true;
359 }
360 break;
361 case oasys_record_is_data_enum:
362 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
363 case oasys_record_is_debug_enum:
364 case oasys_record_is_module_enum:
365 case oasys_record_is_named_section_enum:
366 case oasys_record_is_end_enum:
367 if (had_usefull == false) goto fail;
368 loop = false;
369 break;
370 default:
371 goto fail;
372 }
373 }
374 oasys->symbols = (asymbol *)NULL;
375 /*
376 Oasys support several architectures, but I can't see a simple way
377 to discover which one is in a particular file - we'll guess
378 */
379 abfd->obj_arch = bfd_arch_m68k;
380 abfd->obj_machine =0;
381 if (abfd->symcount != 0) {
382 abfd->flags |= HAS_SYMS;
383 }
384 return abfd->xvec;
385
386 fail:
387 (void) bfd_release(abfd, oasys);
388 return (bfd_target *)NULL;
389 }
390
391
392 static void
393 DEFUN(oasys_print_symbol,(ignore_abfd, file, symbol, how),
394 bfd *ignore_abfd AND
395 FILE *file AND
396 asymbol *symbol AND
397 bfd_print_symbol_enum_type how)
398 {
399 switch (how) {
400 case bfd_print_symbol_name_enum:
401 case bfd_print_symbol_type_enum:
402 fprintf(file,"%s", symbol->name);
403 break;
404 case bfd_print_symbol_all_enum:
405 {
406 CONST char *section_name = symbol->section == (asection *)NULL ?
407 "*abs" : symbol->section->name;
408
409 bfd_print_symbol_vandf((PTR)file,symbol);
410
411 fprintf(file," %-5s %s",
412 section_name,
413 symbol->name);
414 }
415 break;
416 }
417 }
418 /*
419 The howto table is build using the top two bits of a reloc byte to
420 index into it. The bits are PCREL,WORD/LONG
421 */
422 static reloc_howto_type howto_table[]=
423 {
424
425 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
426 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
427 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
428 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
429 };
430
431 /* Read in all the section data and relocation stuff too */
432 static boolean
433 DEFUN(oasys_slurp_section_data,(abfd),
434 bfd *CONST abfd)
435 {
436 oasys_record_union_type record;
437 oasys_data_type *data = oasys_data(abfd);
438 boolean loop = true;
439
440 oasys_per_section_type *per ;
441
442 asection *s;
443
444 /* Buy enough memory for all the section data and relocations */
445 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
446 per = oasys_per_section(s);
447 if (per->data != (bfd_byte*)NULL) return true;
448 per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
449 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
450 per->had_vma = false;
451 s->reloc_count = 0;
452 }
453
454 if (data->first_data_record == 0) return true;
455 bfd_seek(abfd, data->first_data_record, SEEK_SET);
456 while (loop) {
457 oasys_read_record(abfd, &record);
458 switch (record.header.type) {
459 case oasys_record_is_header_enum:
460 break;
461 case oasys_record_is_data_enum:
462 {
463
464 uint8e_type *src = record.data.data;
465 uint8e_type *end_src = ((uint8e_type *)&record) +
466 record.header.length;
467 unsigned int relbit;
468 bfd_byte *dst_ptr ;
469 bfd_byte *dst_base_ptr ;
470 unsigned int count;
471 asection * section =
472 data->sections[record.data.relb & RELOCATION_SECT_BITS];
473 bfd_vma dst_offset ;
474 per = oasys_per_section(section);
475 dst_offset = bfd_h_getlong(abfd, record.data.addr) ;
476 if (per->had_vma == false) {
477 /* Take the first vma we see as the base */
478
479 section->vma = dst_offset;
480 per->had_vma = true;
481 }
482
483
484 dst_offset -= section->vma;
485
486
487 dst_base_ptr = oasys_per_section(section)->data;
488 dst_ptr = oasys_per_section(section)->data +
489 dst_offset;
490
491 while (src < end_src) {
492 uint32_type gap = end_src - src -1;
493 uint8e_type mod_byte = *src++;
494 count = 8;
495 if (mod_byte == 0 && gap >= 8) {
496 dst_ptr[0] = src[0];
497 dst_ptr[1] = src[1];
498 dst_ptr[2] = src[2];
499 dst_ptr[3] = src[3];
500 dst_ptr[4] = src[4];
501 dst_ptr[5] = src[5];
502 dst_ptr[6] = src[6];
503 dst_ptr[7] = src[7];
504 dst_ptr+= 8;
505 src += 8;
506 }
507 else {
508 for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
509 {
510 if (relbit & mod_byte)
511 {
512 uint8e_type reloc = *src;
513 /* This item needs to be relocated */
514 switch (reloc & RELOCATION_TYPE_BITS) {
515 case RELOCATION_TYPE_ABS:
516
517 break;
518
519 case RELOCATION_TYPE_REL:
520 {
521 /* Relocate the item relative to the section */
522 oasys_reloc_type *r =
523 (oasys_reloc_type *)
524 bfd_alloc(abfd,
525 sizeof(oasys_reloc_type));
526 *(per->reloc_tail_ptr) = r;
527 per->reloc_tail_ptr = &r->next;
528 r->next= (oasys_reloc_type *)NULL;
529 /* Reference to undefined symbol */
530 src++;
531 /* There is no symbol */
532 r->symbol = 0;
533 /* Work out the howto */
534 r->relent.section =
535 data->sections[reloc & RELOCATION_SECT_BITS];
536 r->relent.addend = - r->relent.section->vma;
537 r->relent.address = dst_ptr - dst_base_ptr;
538 r->relent.howto = &howto_table[reloc>>6];
539 r->relent.sym_ptr_ptr = (asymbol **)NULL;
540 section->reloc_count++;
541 }
542 break;
543
544
545 case RELOCATION_TYPE_UND:
546 {
547 oasys_reloc_type *r =
548 (oasys_reloc_type *)
549 bfd_alloc(abfd,
550 sizeof(oasys_reloc_type));
551 *(per->reloc_tail_ptr) = r;
552 per->reloc_tail_ptr = &r->next;
553 r->next= (oasys_reloc_type *)NULL;
554 /* Reference to undefined symbol */
555 src++;
556 /* Get symbol number */
557 r->symbol = (src[0]<<8) | src[1];
558 /* Work out the howto */
559 r->relent.section = (asection *)NULL;
560 r->relent.addend = 0;
561 r->relent.address = dst_ptr - dst_base_ptr;
562 r->relent.howto = &howto_table[reloc>>6];
563 r->relent.sym_ptr_ptr = (asymbol **)NULL;
564 section->reloc_count++;
565
566 src+=2;
567 }
568 break;
569 case RELOCATION_TYPE_COM:
570 BFD_FAIL();
571 }
572 }
573 *dst_ptr++ = *src++;
574 }
575 }
576 }
577 }
578 break;
579 case oasys_record_is_local_enum:
580 case oasys_record_is_symbol_enum:
581 case oasys_record_is_section_enum:
582 break;
583 default:
584 loop = false;
585 }
586 }
587 return true;
588
589 }
590
591
592
593 bfd_error_vector_type bfd_error_vector;
594
595 static boolean
596 DEFUN(oasys_new_section_hook,(abfd, newsect),
597 bfd *abfd AND
598 asection *newsect)
599 {
600 newsect->used_by_bfd = (PTR)
601 bfd_alloc(abfd, sizeof(oasys_per_section_type));
602 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
603 oasys_per_section(newsect)->section = newsect;
604 oasys_per_section(newsect)->offset = 0;
605 newsect->alignment_power = 3;
606 /* Turn the section string into an index */
607
608 sscanf(newsect->name,"%u", &newsect->target_index);
609
610 return true;
611 }
612
613
614 static unsigned int
615 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
616 bfd *abfd AND
617 sec_ptr asect)
618 {
619 oasys_slurp_section_data(abfd);
620 return (asect->reloc_count+1) * sizeof(arelent *);
621 }
622
623 static boolean
624 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
625 bfd *abfd AND
626 sec_ptr section AND
627 void *location AND
628 file_ptr offset AND
629 unsigned int count)
630 {
631 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
632 oasys_slurp_section_data(abfd);
633 (void) memcpy(location, p->data + offset, count);
634 return true;
635 }
636
637
638 unsigned int
639 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
640 bfd *abfd AND
641 sec_ptr section AND
642 arelent **relptr AND
643 asymbol **symbols)
644 {
645 unsigned int reloc_count = 0;
646 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
647 while (src != (oasys_reloc_type *)NULL) {
648 if (src->relent.section == (asection *)NULL)
649 {
650 src->relent.sym_ptr_ptr = symbols + src->symbol;
651 }
652 *relptr ++ = &src->relent;
653 src = src->next;
654 reloc_count++;
655 }
656 *relptr = (arelent *)NULL;
657 return section->reloc_count = reloc_count;
658 }
659
660
661 boolean
662 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
663 bfd *abfd AND
664 enum bfd_architecture arch AND
665 unsigned long machine)
666 {
667 abfd->obj_arch = arch;
668 abfd->obj_machine = machine;
669 return true;
670 }
671
672
673
674 /* Writing */
675
676
677 /* Calculate the checksum and write one record */
678 static void
679 DEFUN(oasys_write_record,(abfd, type, record, size),
680 bfd *CONST abfd AND
681 CONST oasys_record_enum_type type AND
682 oasys_record_union_type *record AND
683 CONST size_t size)
684 {
685 int checksum;
686 size_t i;
687 uint8e_type *ptr;
688 record->header.length = size;
689 record->header.type = type;
690 record->header.check_sum = 0;
691 record->header.fill = 0;
692 ptr = &record->pad[0];
693 checksum = 0;
694 for (i = 0; i < size; i++) {
695 checksum += *ptr++;
696 }
697 record->header.check_sum = 0xff & (- checksum);
698 bfd_write((PTR)record, 1, size, abfd);
699 }
700
701
702 /* Write out all the symbols */
703 static void
704 DEFUN(oasys_write_syms, (abfd),
705 bfd * CONST abfd)
706 {
707 unsigned int count;
708 asymbol **generic = bfd_get_outsymbols(abfd);
709 unsigned int index = 0;
710 for (count = 0; count < bfd_get_symcount(abfd); count++) {
711
712 oasys_symbol_record_type symbol;
713 asymbol * CONST g = generic[count];
714
715 CONST char *src = g->name;
716 char *dst = symbol.name;
717 unsigned int l = 0;
718
719 if (g->flags & BSF_FORT_COMM) {
720 symbol.relb = RELOCATION_TYPE_COM;
721 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
722 index++;
723 }
724 else if (g->flags & BSF_ABSOLUTE) {
725 symbol.relb = RELOCATION_TYPE_ABS;
726 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
727
728 }
729 else if (g->flags & BSF_UNDEFINED) {
730 symbol.relb = RELOCATION_TYPE_UND ;
731 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
732 /* Overload the value field with the output index number */
733 index++;
734 }
735 else if (g->flags & BSF_DEBUGGING) {
736 /* throw it away */
737 continue;
738 }
739 else {
740 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
741 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
742 }
743 while (src[l]) {
744 dst[l] = src[l];
745 l++;
746 }
747
748 bfd_h_putlong(abfd, g->value, symbol.value);
749
750
751 if (g->flags & BSF_LOCAL) {
752 oasys_write_record(abfd,
753 oasys_record_is_local_enum,
754 (oasys_record_union_type *) &symbol,
755 offsetof(oasys_symbol_record_type, name[0]) + l);
756 }
757 else {
758 oasys_write_record(abfd,
759 oasys_record_is_symbol_enum,
760 (oasys_record_union_type *) &symbol,
761 offsetof(oasys_symbol_record_type, name[0]) + l);
762 }
763 g->value = index-1;
764 }
765 }
766
767
768 /* Write a section header for each section */
769 static void
770 DEFUN(oasys_write_sections, (abfd),
771 bfd *CONST abfd)
772 {
773 asection *s;
774 static oasys_section_record_type out = {0};
775
776 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
777 if (!isdigit(s->name[0]))
778 {
779 bfd_error_vector.nonrepresentable_section(abfd,
780 s->name);
781 }
782 out.relb = RELOCATION_TYPE_REL | s->target_index;
783 bfd_h_putlong(abfd, s->size, out.value);
784 bfd_h_putlong(abfd, s->vma, out.vma);
785
786 oasys_write_record(abfd,
787 oasys_record_is_section_enum,
788 (oasys_record_union_type *) &out,
789 sizeof(out));
790 }
791 }
792
793 static void
794 DEFUN(oasys_write_header, (abfd),
795 bfd *CONST abfd)
796 {
797 /* Create and write the header */
798 oasys_header_record_type r;
799 size_t length = strlen(abfd->filename);
800 if (length > (size_t)sizeof(r.module_name)) {
801 length = sizeof(r.module_name);
802 }
803
804 (void)memcpy(r.module_name,
805 abfd->filename,
806 length);
807 (void)memset(r.module_name + length,
808 ' ',
809 sizeof(r.module_name) - length);
810
811 r.version_number = OASYS_VERSION_NUMBER;
812 r.rev_number = OASYS_REV_NUMBER;
813 oasys_write_record(abfd,
814 oasys_record_is_header_enum,
815 (oasys_record_union_type *)&r,
816 offsetof(oasys_header_record_type, description[0]));
817
818
819
820 }
821
822 static void
823 DEFUN(oasys_write_end,(abfd),
824 bfd *CONST abfd)
825 {
826 oasys_end_record_type end;
827 end.relb = RELOCATION_TYPE_ABS;
828 bfd_h_putlong(abfd, abfd->start_address, end.entry);
829 bfd_h_putshort(abfd, 0, end.fill);
830 end.zero =0;
831 oasys_write_record(abfd,
832 oasys_record_is_end_enum,
833 (oasys_record_union_type *)&end,
834 sizeof(end));
835 }
836
837 static int
838 DEFUN(comp,(ap, bp),
839 CONST PTR ap AND
840 CONST PTR bp)
841 {
842 arelent *a = *((arelent **)ap);
843 arelent *b = *((arelent **)bp);
844 return a->address - b->address;
845 }
846
847 /*
848 Writing data..
849
850 */
851 static void
852 DEFUN(oasys_write_data, (abfd),
853 bfd *CONST abfd)
854 {
855 asection *s;
856 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
857 uint8e_type *raw_data = oasys_per_section(s)->data;
858 oasys_data_record_type processed_data;
859 unsigned int current_byte_index = 0;
860 unsigned int relocs_to_go = s->reloc_count;
861 arelent **p = s->orelocation;
862 if (s->reloc_count != 0) {
863 /* Sort the reloc records so it's easy to insert the relocs into the
864 data */
865
866 qsort(s->orelocation,
867 s->reloc_count,
868 sizeof(arelent **),
869 comp);
870 }
871 current_byte_index = 0;
872 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
873
874 while ((size_t)current_byte_index < s->size)
875 {
876 /* Scan forwards by eight bytes or however much is left and see if
877 there are any relocations going on */
878 uint8e_type *mod = &processed_data.data[0];
879 uint8e_type *dst = &processed_data.data[1];
880
881 unsigned int i;
882 unsigned int long_length = 128;
883
884
885 bfd_h_putlong(abfd, s->vma + current_byte_index, processed_data.addr);
886 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
887 long_length = s->size - current_byte_index;
888 }
889 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
890
891 unsigned int length = long_length;
892 *mod =0;
893 if (length > 8)
894 length = 8;
895
896 for (i = 0; i < length; i++) {
897 if (relocs_to_go != 0) {
898 arelent *r = *p;
899 reloc_howto_type *CONST how=r->howto;
900 /* There is a relocation, is it for this byte ? */
901 if (r->address == current_byte_index) {
902 uint8e_type rel_byte;
903 p++;
904 relocs_to_go--;
905
906 *mod |= (1<<i);
907 if(how->pc_relative) {
908 rel_byte = 0x80;
909 }
910 else {
911 rel_byte = 0;
912 }
913 if (how->size ==2) {
914 rel_byte |= 0x40;
915 }
916
917 /* Is this a section relative relocation, or a symbol
918 relative relocation ? */
919 if (r->section != (asection*)NULL)
920 {
921 /* The relent has a section attatched, so it must be section
922 relative */
923 rel_byte |= RELOCATION_TYPE_REL;
924 rel_byte |= r->section->output_section->target_index;
925 *dst++ = rel_byte;
926 }
927 else
928 {
929 asymbol *p = *(r->sym_ptr_ptr);
930
931 /* If this symbol has a section attatched, then it
932 has already been resolved. Change from a symbol
933 ref to a section ref */
934 if(p->section != (asection *)NULL) {
935 rel_byte |= RELOCATION_TYPE_REL;
936 rel_byte |=
937 p->section->output_section->target_index;
938 *dst++ = rel_byte;
939 }
940 else {
941 rel_byte |= RELOCATION_TYPE_UND;
942
943
944 *dst++ = rel_byte;
945 /* Next two bytes are a symbol index - we can get
946 this from the symbol value which has been zapped
947 into the symbol index in the table when the
948 symbol table was written
949 */
950 *dst++ = p->value >> 8;
951 *dst++ = p->value;
952 }
953
954 }
955 }
956 }
957 /* If this is coming from an unloadable section then copy
958 zeros */
959 if (raw_data == (uint8e_type *)NULL) {
960 *dst++ = 0;
961 }
962 else {
963 *dst++ = *raw_data++;
964 }
965 current_byte_index++;
966 }
967 mod = dst++;
968 long_length -= length;
969 }
970
971 oasys_write_record(abfd,
972 oasys_record_is_data_enum,
973 (oasys_record_union_type *)&processed_data,
974 dst - (uint8e_type*)&processed_data);
975
976 }
977 }
978 }
979 static boolean
980 DEFUN(oasys_write_object_contents, (abfd),
981 bfd * CONST abfd)
982 {
983 oasys_write_header(abfd);
984 oasys_write_syms(abfd);
985 oasys_write_sections(abfd);
986 oasys_write_data(abfd);
987 oasys_write_end(abfd);
988 return true;
989 }
990
991
992
993
994 /** exec and core file sections */
995
996 /* set section contents is complicated with OASYS since the format is
997 * not a byte image, but a record stream.
998 */
999 static boolean
1000 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1001 bfd *abfd AND
1002 sec_ptr section AND
1003 unsigned char *location AND
1004 file_ptr offset AND
1005 int count)
1006 {
1007 if (count != 0) {
1008 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1009 {
1010 oasys_per_section(section)->data =
1011 (bfd_byte *)(bfd_alloc(abfd,section->size));
1012 }
1013 (void) memcpy(oasys_per_section(section)->data + offset,
1014 location,
1015 count);
1016 }
1017 return true;
1018 }
1019
1020
1021
1022 /* Native-level interface to symbols. */
1023
1024 /* We read the symbols into a buffer, which is discarded when this
1025 function exits. We read the strings into a buffer large enough to
1026 hold them all plus all the cached symbol entries. */
1027
1028 static asymbol *
1029 DEFUN(oasys_make_empty_symbol,(abfd),
1030 bfd *abfd)
1031 {
1032
1033 oasys_symbol_type *new =
1034 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1035 new->symbol.the_bfd = abfd;
1036 return &new->symbol;
1037
1038 }
1039
1040
1041 \f
1042 /* Obsbolete procedural interface; better to look at the cache directly */
1043
1044 /* User should have checked the file flags; perhaps we should return
1045 BFD_NO_MORE_SYMBOLS if there are none? */
1046
1047
1048
1049 boolean
1050 oasys_close_and_cleanup (abfd)
1051 bfd *abfd;
1052 {
1053 if (bfd_read_p (abfd) == false)
1054 switch (abfd->format) {
1055 case bfd_archive:
1056 if (!_bfd_write_archive_contents (abfd)) {
1057 return false;
1058 }
1059 break;
1060 case bfd_object:
1061 if (!oasys_write_object_contents (abfd)) {
1062 return false;
1063 }
1064 break;
1065 default:
1066 bfd_error = invalid_operation;
1067 return false;
1068 }
1069
1070
1071
1072 return true;
1073 }
1074
1075 static bfd *
1076 oasys_openr_next_archived_file(arch, prev)
1077 bfd *arch;
1078 bfd *prev;
1079 {
1080 oasys_ar_data_type *ar = oasys_ar_data(arch);
1081 oasys_module_info_type *p;
1082 /* take the next one from the arch state, or reset */
1083 if (prev == (bfd *)NULL) {
1084 /* Reset the index - the first two entries are bogus*/
1085 ar->module_index = 0;
1086 }
1087
1088 p = ar->module + ar->module_index;
1089 ar->module_index++;
1090
1091 if (ar->module_index <= ar->module_count) {
1092 if (p->abfd == (bfd *)NULL) {
1093 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1094 p->abfd->origin = p->pos;
1095 p->abfd->filename = p->name;
1096
1097 /* Fixup a pointer to this element for the member */
1098 p->abfd->arelt_data = (PTR)p;
1099 }
1100 return p->abfd;
1101 }
1102 else {
1103 bfd_error = no_more_archived_files;
1104 return (bfd *)NULL;
1105 }
1106 }
1107
1108 static boolean
1109 oasys_find_nearest_line(abfd,
1110 section,
1111 symbols,
1112 offset,
1113 filename_ptr,
1114 functionname_ptr,
1115 line_ptr)
1116 bfd *abfd;
1117 asection *section;
1118 asymbol **symbols;
1119 bfd_vma offset;
1120 char **filename_ptr;
1121 char **functionname_ptr;
1122 unsigned int *line_ptr;
1123 {
1124 return false;
1125
1126 }
1127
1128 static int
1129 oasys_generic_stat_arch_elt(abfd, buf)
1130 bfd *abfd;
1131 struct stat *buf;
1132 {
1133 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1134 if (mod == (oasys_module_info_type *)NULL) {
1135 bfd_error = invalid_operation;
1136 return -1;
1137 }
1138 else {
1139 buf->st_size = mod->size;
1140 buf->st_mode = 0666;
1141 return 0;
1142 }
1143 }
1144
1145 static int
1146 DEFUN(oasys_sizeof_headers,(abfd),
1147 bfd *abfd)
1148 {
1149 return 0;
1150 }
1151
1152 #define oasys_core_file_failing_command bfd_false
1153 #define oasys_core_file_failing_signal bfd_false
1154 #define oasys_core_file_matches_executable_p bfd_false
1155 #define oasys_slurp_armap bfd_false
1156 #define oasys_slurp_extended_name_table bfd_false
1157 #define oasys_truncate_arname bfd_false
1158 #define oasys_write_armap bfd_false
1159 #define oasys_get_lineno bfd_false
1160
1161
1162
1163 /*SUPPRESS 460 */
1164 bfd_target oasys_vec =
1165 {
1166 "oasys", /* name */
1167 bfd_target_oasys_flavour_enum,
1168 true, /* target byte order */
1169 true, /* target headers byte order */
1170 (HAS_RELOC | EXEC_P | /* object flags */
1171 HAS_LINENO | HAS_DEBUG |
1172 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1173 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1174 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1175 ' ', /* ar_pad_char */
1176 16, /* ar_max_namelen */
1177
1178 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1179 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1180
1181 {_bfd_dummy_target,
1182 oasys_object_p, /* bfd_check_format */
1183 oasys_archive_p,
1184 bfd_false
1185 },
1186 {
1187 bfd_false,
1188 oasys_mkobject,
1189 _bfd_generic_mkarchive,
1190 bfd_false
1191 },
1192 JUMP_TABLE(oasys)
1193 };
This page took 0.054375 seconds and 4 git commands to generate.