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