*** empty log message ***
[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 /* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
425
426 { 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff},
427 { 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff},
428 { 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff},
429 { 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff}
430 };
431
432 /* Read in all the section data and relocation stuff too */
433 static boolean
434 DEFUN(oasys_slurp_section_data,(abfd),
435 bfd *CONST abfd)
436 {
437 oasys_record_union_type record;
438 oasys_data_type *data = oasys_data(abfd);
439 boolean loop = true;
440
441 oasys_per_section_type *per ;
442
443 asection *s;
444
445 /* Buy enough memory for all the section data and relocations */
446 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
447 per = oasys_per_section(s);
448 if (per->data != (bfd_byte*)NULL) return true;
449 per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
450 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
451 per->had_vma = false;
452 s->reloc_count = 0;
453 }
454
455 if (data->first_data_record == 0) return true;
456 bfd_seek(abfd, data->first_data_record, SEEK_SET);
457 while (loop) {
458 oasys_read_record(abfd, &record);
459 switch (record.header.type) {
460 case oasys_record_is_header_enum:
461 break;
462 case oasys_record_is_data_enum:
463 {
464
465 uint8e_type *src = record.data.data;
466 uint8e_type *end_src = ((uint8e_type *)&record) +
467 record.header.length;
468 unsigned int relbit;
469 bfd_byte *dst_ptr ;
470 bfd_byte *dst_base_ptr ;
471 unsigned int count;
472 asection * section =
473 data->sections[record.data.relb & RELOCATION_SECT_BITS];
474 bfd_vma dst_offset ;
475 per = oasys_per_section(section);
476 dst_offset = bfd_h_getlong(abfd, record.data.addr) ;
477 if (per->had_vma == false) {
478 /* Take the first vma we see as the base */
479
480 section->vma = dst_offset;
481 per->had_vma = true;
482 }
483
484
485 dst_offset -= section->vma;
486
487
488 dst_base_ptr = oasys_per_section(section)->data;
489 dst_ptr = oasys_per_section(section)->data +
490 dst_offset;
491
492 while (src < end_src) {
493 uint32_type gap = end_src - src -1;
494 uint8e_type mod_byte = *src++;
495 count = 8;
496 if (mod_byte == 0 && gap >= 8) {
497 dst_ptr[0] = src[0];
498 dst_ptr[1] = src[1];
499 dst_ptr[2] = src[2];
500 dst_ptr[3] = src[3];
501 dst_ptr[4] = src[4];
502 dst_ptr[5] = src[5];
503 dst_ptr[6] = src[6];
504 dst_ptr[7] = src[7];
505 dst_ptr+= 8;
506 src += 8;
507 }
508 else {
509 for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
510 {
511 if (relbit & mod_byte)
512 {
513 uint8e_type reloc = *src;
514 /* This item needs to be relocated */
515 switch (reloc & RELOCATION_TYPE_BITS) {
516 case RELOCATION_TYPE_ABS:
517
518 break;
519
520 case RELOCATION_TYPE_REL:
521 {
522 /* Relocate the item relative to the section */
523 oasys_reloc_type *r =
524 (oasys_reloc_type *)
525 bfd_alloc(abfd,
526 sizeof(oasys_reloc_type));
527 *(per->reloc_tail_ptr) = r;
528 per->reloc_tail_ptr = &r->next;
529 r->next= (oasys_reloc_type *)NULL;
530 /* Reference to undefined symbol */
531 src++;
532 /* There is no symbol */
533 r->symbol = 0;
534 /* Work out the howto */
535 r->relent.section =
536 data->sections[reloc & RELOCATION_SECT_BITS];
537 r->relent.addend = - r->relent.section->vma;
538 r->relent.address = dst_ptr - dst_base_ptr;
539 r->relent.howto = &howto_table[reloc>>6];
540 r->relent.sym_ptr_ptr = (asymbol **)NULL;
541 section->reloc_count++;
542 }
543 break;
544
545
546 case RELOCATION_TYPE_UND:
547 {
548 oasys_reloc_type *r =
549 (oasys_reloc_type *)
550 bfd_alloc(abfd,
551 sizeof(oasys_reloc_type));
552 *(per->reloc_tail_ptr) = r;
553 per->reloc_tail_ptr = &r->next;
554 r->next= (oasys_reloc_type *)NULL;
555 /* Reference to undefined symbol */
556 src++;
557 /* Get symbol number */
558 r->symbol = (src[0]<<8) | src[1];
559 /* Work out the howto */
560 r->relent.section = (asection *)NULL;
561 r->relent.addend = 0;
562 r->relent.address = dst_ptr - dst_base_ptr;
563 r->relent.howto = &howto_table[reloc>>6];
564 r->relent.sym_ptr_ptr = (asymbol **)NULL;
565 section->reloc_count++;
566
567 src+=2;
568 }
569 break;
570 case RELOCATION_TYPE_COM:
571 BFD_FAIL();
572 }
573 }
574 *dst_ptr++ = *src++;
575 }
576 }
577 }
578 }
579 break;
580 case oasys_record_is_local_enum:
581 case oasys_record_is_symbol_enum:
582 case oasys_record_is_section_enum:
583 break;
584 default:
585 loop = false;
586 }
587 }
588 return true;
589
590 }
591
592
593
594 bfd_error_vector_type bfd_error_vector;
595
596 static boolean
597 DEFUN(oasys_new_section_hook,(abfd, newsect),
598 bfd *abfd AND
599 asection *newsect)
600 {
601 newsect->used_by_bfd = (PTR)
602 bfd_alloc(abfd, sizeof(oasys_per_section_type));
603 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
604 oasys_per_section(newsect)->section = newsect;
605 oasys_per_section(newsect)->offset = 0;
606 newsect->alignment_power = 3;
607 /* Turn the section string into an index */
608
609 sscanf(newsect->name,"%u", &newsect->target_index);
610
611 return true;
612 }
613
614
615 static unsigned int
616 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
617 bfd *abfd AND
618 sec_ptr asect)
619 {
620 oasys_slurp_section_data(abfd);
621 return (asect->reloc_count+1) * sizeof(arelent *);
622 }
623
624 static boolean
625 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
626 bfd *abfd AND
627 sec_ptr section AND
628 void *location AND
629 file_ptr offset AND
630 unsigned int count)
631 {
632 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
633 oasys_slurp_section_data(abfd);
634 (void) memcpy(location, p->data + offset, count);
635 return true;
636 }
637
638
639 unsigned int
640 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
641 bfd *abfd AND
642 sec_ptr section AND
643 arelent **relptr AND
644 asymbol **symbols)
645 {
646 unsigned int reloc_count = 0;
647 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
648 while (src != (oasys_reloc_type *)NULL) {
649 if (src->relent.section == (asection *)NULL)
650 {
651 src->relent.sym_ptr_ptr = symbols + src->symbol;
652 }
653 *relptr ++ = &src->relent;
654 src = src->next;
655 reloc_count++;
656 }
657 *relptr = (arelent *)NULL;
658 return section->reloc_count = reloc_count;
659 }
660
661
662 boolean
663 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
664 bfd *abfd AND
665 enum bfd_architecture arch AND
666 unsigned long machine)
667 {
668 abfd->obj_arch = arch;
669 abfd->obj_machine = machine;
670 return true;
671 }
672
673
674
675 /* Writing */
676
677
678 /* Calculate the checksum and write one record */
679 static void
680 DEFUN(oasys_write_record,(abfd, type, record, size),
681 bfd *CONST abfd AND
682 CONST oasys_record_enum_type type AND
683 oasys_record_union_type *record AND
684 CONST size_t size)
685 {
686 int checksum;
687 size_t i;
688 uint8e_type *ptr;
689 record->header.length = size;
690 record->header.type = type;
691 record->header.check_sum = 0;
692 record->header.fill = 0;
693 ptr = &record->pad[0];
694 checksum = 0;
695 for (i = 0; i < size; i++) {
696 checksum += *ptr++;
697 }
698 record->header.check_sum = 0xff & (- checksum);
699 bfd_write((PTR)record, 1, size, abfd);
700 }
701
702
703 /* Write out all the symbols */
704 static void
705 DEFUN(oasys_write_syms, (abfd),
706 bfd * CONST abfd)
707 {
708 unsigned int count;
709 asymbol **generic = bfd_get_outsymbols(abfd);
710 unsigned int index = 0;
711 for (count = 0; count < bfd_get_symcount(abfd); count++) {
712
713 oasys_symbol_record_type symbol;
714 asymbol * CONST g = generic[count];
715
716 CONST char *src = g->name;
717 char *dst = symbol.name;
718 unsigned int l = 0;
719
720 if (g->flags & BSF_FORT_COMM) {
721 symbol.relb = RELOCATION_TYPE_COM;
722 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
723 index++;
724 }
725 else if (g->flags & BSF_ABSOLUTE) {
726 symbol.relb = RELOCATION_TYPE_ABS;
727 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
728
729 }
730 else if (g->flags & BSF_UNDEFINED) {
731 symbol.relb = RELOCATION_TYPE_UND ;
732 bfd_h_putshort(abfd, index, (uint8e_type *)(&symbol.refno[0]));
733 /* Overload the value field with the output index number */
734 index++;
735 }
736 else if (g->flags & BSF_DEBUGGING) {
737 /* throw it away */
738 continue;
739 }
740 else {
741 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
742 bfd_h_putshort(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
743 }
744 while (src[l]) {
745 dst[l] = src[l];
746 l++;
747 }
748
749 bfd_h_putlong(abfd, g->value, symbol.value);
750
751
752 if (g->flags & BSF_LOCAL) {
753 oasys_write_record(abfd,
754 oasys_record_is_local_enum,
755 (oasys_record_union_type *) &symbol,
756 offsetof(oasys_symbol_record_type, name[0]) + l);
757 }
758 else {
759 oasys_write_record(abfd,
760 oasys_record_is_symbol_enum,
761 (oasys_record_union_type *) &symbol,
762 offsetof(oasys_symbol_record_type, name[0]) + l);
763 }
764 g->value = index-1;
765 }
766 }
767
768
769 /* Write a section header for each section */
770 static void
771 DEFUN(oasys_write_sections, (abfd),
772 bfd *CONST abfd)
773 {
774 asection *s;
775 static oasys_section_record_type out = {0};
776
777 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
778 if (!isdigit(s->name[0]))
779 {
780 bfd_error_vector.nonrepresentable_section(abfd,
781 s->name);
782 }
783 out.relb = RELOCATION_TYPE_REL | s->target_index;
784 bfd_h_putlong(abfd, s->size, out.value);
785 bfd_h_putlong(abfd, s->vma, out.vma);
786
787 oasys_write_record(abfd,
788 oasys_record_is_section_enum,
789 (oasys_record_union_type *) &out,
790 sizeof(out));
791 }
792 }
793
794 static void
795 DEFUN(oasys_write_header, (abfd),
796 bfd *CONST abfd)
797 {
798 /* Create and write the header */
799 oasys_header_record_type r;
800 size_t length = strlen(abfd->filename);
801 if (length > (size_t)sizeof(r.module_name)) {
802 length = sizeof(r.module_name);
803 }
804
805 (void)memcpy(r.module_name,
806 abfd->filename,
807 length);
808 (void)memset(r.module_name + length,
809 ' ',
810 sizeof(r.module_name) - length);
811
812 r.version_number = OASYS_VERSION_NUMBER;
813 r.rev_number = OASYS_REV_NUMBER;
814 oasys_write_record(abfd,
815 oasys_record_is_header_enum,
816 (oasys_record_union_type *)&r,
817 offsetof(oasys_header_record_type, description[0]));
818
819
820
821 }
822
823 static void
824 DEFUN(oasys_write_end,(abfd),
825 bfd *CONST abfd)
826 {
827 oasys_end_record_type end;
828 end.relb = RELOCATION_TYPE_ABS;
829 bfd_h_putlong(abfd, abfd->start_address, end.entry);
830 bfd_h_putshort(abfd, 0, end.fill);
831 end.zero =0;
832 oasys_write_record(abfd,
833 oasys_record_is_end_enum,
834 (oasys_record_union_type *)&end,
835 sizeof(end));
836 }
837
838 static int
839 DEFUN(comp,(ap, bp),
840 CONST PTR ap AND
841 CONST PTR bp)
842 {
843 arelent *a = *((arelent **)ap);
844 arelent *b = *((arelent **)bp);
845 return a->address - b->address;
846 }
847
848 /*
849 Writing data..
850
851 */
852 static void
853 DEFUN(oasys_write_data, (abfd),
854 bfd *CONST abfd)
855 {
856 asection *s;
857 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
858 uint8e_type *raw_data = oasys_per_section(s)->data;
859 oasys_data_record_type processed_data;
860 unsigned int current_byte_index = 0;
861 unsigned int relocs_to_go = s->reloc_count;
862 arelent **p = s->orelocation;
863 if (s->reloc_count != 0) {
864 /* Sort the reloc records so it's easy to insert the relocs into the
865 data */
866
867 qsort(s->orelocation,
868 s->reloc_count,
869 sizeof(arelent **),
870 comp);
871 }
872 current_byte_index = 0;
873 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
874
875 while ((size_t)current_byte_index < s->size)
876 {
877 /* Scan forwards by eight bytes or however much is left and see if
878 there are any relocations going on */
879 uint8e_type *mod = &processed_data.data[0];
880 uint8e_type *dst = &processed_data.data[1];
881
882 unsigned int i;
883 unsigned int long_length = 128;
884
885
886 bfd_h_putlong(abfd, s->vma + current_byte_index, processed_data.addr);
887 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
888 long_length = s->size - current_byte_index;
889 }
890 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
891
892 unsigned int length = long_length;
893 *mod =0;
894 if (length > 8)
895 length = 8;
896
897 for (i = 0; i < length; i++) {
898 if (relocs_to_go != 0) {
899 arelent *r = *p;
900 reloc_howto_type *CONST how=r->howto;
901 /* There is a relocation, is it for this byte ? */
902 if (r->address == current_byte_index) {
903 uint8e_type rel_byte;
904 p++;
905 relocs_to_go--;
906
907 *mod |= (1<<i);
908 if(how->pc_relative) {
909 rel_byte = 0x80;
910 }
911 else {
912 rel_byte = 0;
913 }
914 if (how->size ==2) {
915 rel_byte |= 0x40;
916 }
917
918 /* Is this a section relative relocation, or a symbol
919 relative relocation ? */
920 if (r->section != (asection*)NULL)
921 {
922 /* The relent has a section attatched, so it must be section
923 relative */
924 rel_byte |= RELOCATION_TYPE_REL;
925 rel_byte |= r->section->output_section->target_index;
926 *dst++ = rel_byte;
927 }
928 else
929 {
930 asymbol *p = *(r->sym_ptr_ptr);
931
932 /* If this symbol has a section attatched, then it
933 has already been resolved. Change from a symbol
934 ref to a section ref */
935 if(p->section != (asection *)NULL) {
936 rel_byte |= RELOCATION_TYPE_REL;
937 rel_byte |=
938 p->section->output_section->target_index;
939 *dst++ = rel_byte;
940 }
941 else {
942 rel_byte |= RELOCATION_TYPE_UND;
943
944
945 *dst++ = rel_byte;
946 /* Next two bytes are a symbol index - we can get
947 this from the symbol value which has been zapped
948 into the symbol index in the table when the
949 symbol table was written
950 */
951 *dst++ = p->value >> 8;
952 *dst++ = p->value;
953 }
954
955 }
956 }
957 }
958 /* If this is coming from an unloadable section then copy
959 zeros */
960 if (raw_data == (uint8e_type *)NULL) {
961 *dst++ = 0;
962 }
963 else {
964 *dst++ = *raw_data++;
965 }
966 current_byte_index++;
967 }
968 mod = dst++;
969 long_length -= length;
970 }
971
972 oasys_write_record(abfd,
973 oasys_record_is_data_enum,
974 (oasys_record_union_type *)&processed_data,
975 dst - (uint8e_type*)&processed_data);
976
977 }
978 }
979 }
980 static boolean
981 DEFUN(oasys_write_object_contents, (abfd),
982 bfd * CONST abfd)
983 {
984 oasys_write_header(abfd);
985 oasys_write_syms(abfd);
986 oasys_write_sections(abfd);
987 oasys_write_data(abfd);
988 oasys_write_end(abfd);
989 return true;
990 }
991
992
993
994
995 /** exec and core file sections */
996
997 /* set section contents is complicated with OASYS since the format is
998 * not a byte image, but a record stream.
999 */
1000 static boolean
1001 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1002 bfd *abfd AND
1003 sec_ptr section AND
1004 unsigned char *location AND
1005 file_ptr offset AND
1006 int count)
1007 {
1008 if (count != 0) {
1009 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1010 {
1011 oasys_per_section(section)->data =
1012 (bfd_byte *)(bfd_alloc(abfd,section->size));
1013 }
1014 (void) memcpy(oasys_per_section(section)->data + offset,
1015 location,
1016 count);
1017 }
1018 return true;
1019 }
1020
1021
1022
1023 /* Native-level interface to symbols. */
1024
1025 /* We read the symbols into a buffer, which is discarded when this
1026 function exits. We read the strings into a buffer large enough to
1027 hold them all plus all the cached symbol entries. */
1028
1029 static asymbol *
1030 DEFUN(oasys_make_empty_symbol,(abfd),
1031 bfd *abfd)
1032 {
1033
1034 oasys_symbol_type *new =
1035 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1036 new->symbol.the_bfd = abfd;
1037 return &new->symbol;
1038
1039 }
1040
1041
1042 \f
1043 /* Obsbolete procedural interface; better to look at the cache directly */
1044
1045 /* User should have checked the file flags; perhaps we should return
1046 BFD_NO_MORE_SYMBOLS if there are none? */
1047
1048
1049
1050 boolean
1051 oasys_close_and_cleanup (abfd)
1052 bfd *abfd;
1053 {
1054 if (bfd_read_p (abfd) == false)
1055 switch (abfd->format) {
1056 case bfd_archive:
1057 if (!_bfd_write_archive_contents (abfd)) {
1058 return false;
1059 }
1060 break;
1061 case bfd_object:
1062 if (!oasys_write_object_contents (abfd)) {
1063 return false;
1064 }
1065 break;
1066 default:
1067 bfd_error = invalid_operation;
1068 return false;
1069 }
1070
1071
1072
1073 return true;
1074 }
1075
1076 static bfd *
1077 oasys_openr_next_archived_file(arch, prev)
1078 bfd *arch;
1079 bfd *prev;
1080 {
1081 oasys_ar_data_type *ar = oasys_ar_data(arch);
1082 oasys_module_info_type *p;
1083 /* take the next one from the arch state, or reset */
1084 if (prev == (bfd *)NULL) {
1085 /* Reset the index - the first two entries are bogus*/
1086 ar->module_index = 0;
1087 }
1088
1089 p = ar->module + ar->module_index;
1090 ar->module_index++;
1091
1092 if (ar->module_index <= ar->module_count) {
1093 if (p->abfd == (bfd *)NULL) {
1094 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1095 p->abfd->origin = p->pos;
1096 p->abfd->filename = p->name;
1097
1098 /* Fixup a pointer to this element for the member */
1099 p->abfd->arelt_data = (PTR)p;
1100 }
1101 return p->abfd;
1102 }
1103 else {
1104 bfd_error = no_more_archived_files;
1105 return (bfd *)NULL;
1106 }
1107 }
1108
1109 static boolean
1110 oasys_find_nearest_line(abfd,
1111 section,
1112 symbols,
1113 offset,
1114 filename_ptr,
1115 functionname_ptr,
1116 line_ptr)
1117 bfd *abfd;
1118 asection *section;
1119 asymbol **symbols;
1120 bfd_vma offset;
1121 char **filename_ptr;
1122 char **functionname_ptr;
1123 unsigned int *line_ptr;
1124 {
1125 return false;
1126
1127 }
1128
1129 static int
1130 oasys_generic_stat_arch_elt(abfd, buf)
1131 bfd *abfd;
1132 struct stat *buf;
1133 {
1134 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1135 if (mod == (oasys_module_info_type *)NULL) {
1136 bfd_error = invalid_operation;
1137 return -1;
1138 }
1139 else {
1140 buf->st_size = mod->size;
1141 buf->st_mode = 0666;
1142 return 0;
1143 }
1144
1145
1146 }
1147
1148 #define oasys_core_file_failing_command bfd_false
1149 #define oasys_core_file_failing_signal bfd_false
1150 #define oasys_core_file_matches_executable_p bfd_false
1151 #define oasys_slurp_armap bfd_false
1152 #define oasys_slurp_extended_name_table bfd_false
1153 #define oasys_truncate_arname bfd_false
1154 #define oasys_write_armap bfd_false
1155 #define oasys_get_lineno bfd_false
1156
1157
1158
1159 /*SUPPRESS 460 */
1160 bfd_target oasys_vec =
1161 {
1162 "oasys", /* name */
1163 bfd_target_oasys_flavour_enum,
1164 true, /* target byte order */
1165 true, /* target headers byte order */
1166 (HAS_RELOC | EXEC_P | /* object flags */
1167 HAS_LINENO | HAS_DEBUG |
1168 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1169 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1170 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1171 ' ', /* ar_pad_char */
1172 16, /* ar_max_namelen */
1173
1174 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1175 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1176
1177 {_bfd_dummy_target,
1178 oasys_object_p, /* bfd_check_format */
1179 oasys_archive_p,
1180 bfd_false
1181 },
1182 {
1183 bfd_false,
1184 oasys_mkobject,
1185 _bfd_generic_mkarchive,
1186 bfd_false
1187 },
1188 JUMP_TABLE(oasys)
1189 };
This page took 0.054202 seconds and 5 git commands to generate.