*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / oasys.c
CommitLineData
3e9aade1
SC
1#define UNDERSCORE_HACK 1
2#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
87f86b4e
DHW
3/*
4
5 bfd backend for oasys objects.
6
7
3e9aade1
SC
8 Written by Steve Chamberlain
9 steve@cygnus.com
87f86b4e 10
3e9aade1 11 $Id$
87f86b4e
DHW
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
87f86b4e 27
87f86b4e
DHW
28
29
3e9aade1
SC
30static void
31DEFUN(oasys_read_record,(abfd, record),
32 bfd *CONST abfd AND
87f86b4e
DHW
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}
42static size_t
3e9aade1
SC
43DEFUN(oasys_string_length,(record),
44 oasys_record_union_type *record)
87f86b4e
DHW
45{
46return record->header.length
47 - ((char *)record->symbol.name - (char *)record);
48}
49
50/*****************************************************************************/
51
52/*
53
54Slurp the symbol table by reading in all the records at the start file
55till we get to the first section record.
56
3e9aade1
SC
57We'll sort the symbolss into two lists, defined and undefined. The
58undefined symbols will be placed into the table according to their
59refno.
60
61We do this by placing all undefined symbols at the front of the table
62moving in, and the defined symbols at the end of the table moving back.
87f86b4e
DHW
63
64*/
65
66static boolean
3e9aade1
SC
67DEFUN(oasys_slurp_symbol_table,(abfd),
68 bfd * CONST abfd)
87f86b4e
DHW
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 =
9872a49c 84 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
de7c1ff6
SC
85#ifdef UNDERSCORE_HACK
86 /* buy 1 more char for each symbol to keep the underscore in*/
9872a49c 87 data->strings = bfd_alloc(abfd, data->symbol_string_length +
3e9aade1 88 abfd->symcount);
de7c1ff6 89#else
9872a49c 90 data->strings = bfd_alloc(abfd, data->symbol_string_length);
de7c1ff6 91#endif
87f86b4e
DHW
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) {
de7c1ff6 99
87f86b4e
DHW
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 {
3e9aade1 107 int flag = record.header.type == oasys_record_is_local_enum ?
de7c1ff6
SC
108 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
109
110
87f86b4e 111 size_t length = oasys_string_length(&record);
3e9aade1 112 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
87f86b4e
DHW
113 case RELOCATION_TYPE_ABS:
114 dest = dest_defined--;
115 dest->section = 0;
de7c1ff6 116 dest->flags = BSF_ABSOLUTE | flag;
87f86b4e
DHW
117 break;
118 case RELOCATION_TYPE_REL:
119 dest = dest_defined--;
120 dest->section =
3e9aade1 121 oasys_data(abfd)->sections[record.symbol.relb &
87f86b4e
DHW
122 RELOCATION_SECT_BITS];
123 if (record.header.type == oasys_record_is_local_enum)
124 {
de7c1ff6 125 dest->flags = BSF_LOCAL;
87f86b4e
DHW
126 }
127 else {
128
de7c1ff6 129 dest->flags = flag;
87f86b4e
DHW
130 }
131 break;
132 case RELOCATION_TYPE_UND:
3e9aade1 133 dest = data->symbols + bfd_h_getshort(abfd, &record.symbol.refno[0]);
87f86b4e
DHW
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;
3e9aade1
SC
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 }
de7c1ff6 156#endif
87f86b4e 157 memcpy(string_ptr, record.symbol.name, length);
de7c1ff6
SC
158
159
87f86b4e
DHW
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
3e9aade1
SC
172static size_t
173DEFUN(oasys_get_symtab_upper_bound,(abfd),
174 bfd *CONST abfd)
87f86b4e
DHW
175{
176 oasys_slurp_symbol_table (abfd);
177
de7c1ff6 178 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
87f86b4e
DHW
179}
180
181/*
182*/
183
184extern bfd_target oasys_vec;
185
186unsigned int
3e9aade1
SC
187DEFUN(oasys_get_symtab,(abfd, location),
188 bfd *abfd AND
189 asymbol **location)
87f86b4e
DHW
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);
3e9aade1
SC
208static bfd_target *
209DEFUN(oasys_archive_p,(abfd),
210 bfd *abfd)
87f86b4e
DHW
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 =
9872a49c 247 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
87f86b4e
DHW
248
249
250 oasys_module_info_type *module =
251 (oasys_module_info_type*)
9872a49c 252 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
87f86b4e
DHW
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);
9872a49c 267 module[i].name = bfd_alloc(abfd,record.mod_name_length+1);
87f86b4e
DHW
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
3e9aade1
SC
282static boolean
283DEFUN(oasys_mkobject,(abfd),
284 bfd *abfd)
87f86b4e
DHW
285{
286 oasys_data_type *oasys;
9872a49c 287
3e9aade1 288 oasys_data(abfd) =
9872a49c 289 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type));
3e9aade1 290 oasys = oasys_data(abfd);
3e9aade1
SC
291 return true;
292}
87f86b4e 293
3e9aade1
SC
294#define MAX_SECS 16
295static bfd_target *
296DEFUN(oasys_object_p,(abfd),
297 bfd *abfd)
298{
299 oasys_data_type *oasys;
87f86b4e 300 boolean loop = true;
87f86b4e 301 boolean had_usefull = false;
3e9aade1
SC
302 oasys_data(abfd) = 0;
303 oasys_mkobject(abfd);
304 oasys = oasys_data(abfd);
305 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
87f86b4e
DHW
306
307 /* Point to the start of the file */
308 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
3e9aade1 309 oasys->symbol_string_length = 0;
87f86b4e
DHW
310 /* Inspect the records, but only keep the section info -
311 remember the size of the symbols
312 */
3e9aade1 313 oasys->first_data_record = 0;
87f86b4e
DHW
314 while (loop) {
315 oasys_record_union_type record;
316 oasys_read_record(abfd, &record);
301dfc71 317 if ((size_t)record.header.length < (size_t)sizeof(record.header))
3e9aade1
SC
318 goto fail;
319
87f86b4e
DHW
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++;
3e9aade1 329 oasys->symbol_string_length += 1 + oasys_string_length(&record);
87f86b4e
DHW
330 had_usefull = true;
331 break;
332 case oasys_record_is_section_enum:
3e9aade1
SC
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 }
9872a49c 341 buffer = bfd_alloc(abfd, 3);
3e9aade1
SC
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();
87f86b4e 353 }
87f86b4e 354
3e9aade1
SC
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 }
87f86b4e
DHW
360 break;
361 case oasys_record_is_data_enum:
3e9aade1 362 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
87f86b4e
DHW
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:
3e9aade1 367 if (had_usefull == false) goto fail;
87f86b4e
DHW
368 loop = false;
369 break;
370 default:
3e9aade1 371 goto fail;
87f86b4e
DHW
372 }
373 }
87f86b4e
DHW
374 oasys->symbols = (asymbol *)NULL;
375 /*
3e9aade1
SC
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 */
87f86b4e
DHW
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;
3e9aade1
SC
385
386 fail:
9872a49c 387 (void) bfd_release(abfd, oasys);
3e9aade1 388 return (bfd_target *)NULL;
87f86b4e
DHW
389}
390
391
3e9aade1
SC
392static void
393DEFUN(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)
87f86b4e
DHW
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 {
3e9aade1 406CONST char *section_name = symbol->section == (asection *)NULL ?
87f86b4e
DHW
407 "*abs" : symbol->section->name;
408
3e9aade1 409 bfd_print_symbol_vandf((PTR)file,symbol);
87f86b4e
DHW
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*/
422static reloc_howto_type howto_table[]=
423{
424/* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
425
3e9aade1
SC
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}
87f86b4e
DHW
430};
431
432/* Read in all the section data and relocation stuff too */
3e9aade1
SC
433static boolean
434DEFUN(oasys_slurp_section_data,(abfd),
435 bfd *CONST abfd)
87f86b4e
DHW
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;
9872a49c 449 per->data = (bfd_byte *) bfd_alloc(abfd, s->size);
87f86b4e 450 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
3e9aade1
SC
451 per->had_vma = false;
452 s->reloc_count = 0;
87f86b4e
DHW
453 }
454
de7c1ff6 455 if (data->first_data_record == 0) return true;
87f86b4e
DHW
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:
de7c1ff6 463 {
87f86b4e 464
de7c1ff6
SC
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 ;
de7c1ff6 471 unsigned int count;
3e9aade1
SC
472 asection * section =
473 data->sections[record.data.relb & RELOCATION_SECT_BITS];
474 bfd_vma dst_offset ;
de7c1ff6 475 per = oasys_per_section(section);
3e9aade1
SC
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
de7c1ff6
SC
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 *)
9872a49c 525 bfd_alloc(abfd,
3e9aade1 526 sizeof(oasys_reloc_type));
de7c1ff6
SC
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];
3e9aade1 537 r->relent.addend = - r->relent.section->vma;
de7c1ff6
SC
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++;
de7c1ff6
SC
542 }
543 break;
544
545
546 case RELOCATION_TYPE_UND:
547 {
548 oasys_reloc_type *r =
549 (oasys_reloc_type *)
9872a49c 550 bfd_alloc(abfd,
3e9aade1 551 sizeof(oasys_reloc_type));
de7c1ff6
SC
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;
de7c1ff6 565 section->reloc_count++;
3e9aade1 566
de7c1ff6
SC
567 src+=2;
568 }
569 break;
570 case RELOCATION_TYPE_COM:
571 BFD_FAIL();
572 }
573 }
574 *dst_ptr++ = *src++;
87f86b4e 575 }
87f86b4e 576 }
de7c1ff6
SC
577 }
578 }
87f86b4e
DHW
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
3e9aade1 594bfd_error_vector_type bfd_error_vector;
87f86b4e 595
3e9aade1
SC
596static boolean
597DEFUN(oasys_new_section_hook,(abfd, newsect),
598 bfd *abfd AND
599 asection *newsect)
87f86b4e 600{
a6dab071 601 newsect->used_by_bfd = (PTR)
9872a49c 602 bfd_alloc(abfd, sizeof(oasys_per_section_type));
87f86b4e
DHW
603 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
604 oasys_per_section(newsect)->section = newsect;
605 oasys_per_section(newsect)->offset = 0;
3e9aade1
SC
606 newsect->alignment_power = 3;
607 /* Turn the section string into an index */
608
609 sscanf(newsect->name,"%u", &newsect->target_index);
610
87f86b4e
DHW
611 return true;
612}
613
614
3e9aade1
SC
615static unsigned int
616DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
617 bfd *abfd AND
618 sec_ptr asect)
87f86b4e
DHW
619{
620 oasys_slurp_section_data(abfd);
621 return (asect->reloc_count+1) * sizeof(arelent *);
622}
623
624static boolean
3e9aade1
SC
625DEFUN(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)
87f86b4e 631{
a6dab071 632 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
87f86b4e
DHW
633 oasys_slurp_section_data(abfd);
634 (void) memcpy(location, p->data + offset, count);
635 return true;
636}
637
638
639unsigned int
3e9aade1
SC
640DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
641 bfd *abfd AND
642 sec_ptr section AND
643 arelent **relptr AND
644 asymbol **symbols)
87f86b4e 645{
3e9aade1 646 unsigned int reloc_count = 0;
87f86b4e
DHW
647 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
648 while (src != (oasys_reloc_type *)NULL) {
3e9aade1
SC
649 if (src->relent.section == (asection *)NULL)
650 {
651 src->relent.sym_ptr_ptr = symbols + src->symbol;
652 }
87f86b4e
DHW
653 *relptr ++ = &src->relent;
654 src = src->next;
3e9aade1 655 reloc_count++;
87f86b4e
DHW
656 }
657 *relptr = (arelent *)NULL;
3e9aade1 658 return section->reloc_count = reloc_count;
87f86b4e
DHW
659}
660
3e9aade1 661
87f86b4e 662boolean
3e9aade1
SC
663DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
664 bfd *abfd AND
665 enum bfd_architecture arch AND
666 unsigned long machine)
87f86b4e
DHW
667{
668 abfd->obj_arch = arch;
669 abfd->obj_machine = machine;
670 return true;
671}
672
3e9aade1
SC
673
674
675/* Writing */
676
677
678/* Calculate the checksum and write one record */
679static void
680DEFUN(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)
87f86b4e 685{
3e9aade1
SC
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++;
87f86b4e 697 }
3e9aade1
SC
698 record->header.check_sum = 0xff & (- checksum);
699 bfd_write((PTR)record, 1, size, abfd);
700}
87f86b4e 701
3e9aade1
SC
702
703/* Write out all the symbols */
704static void
705DEFUN(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 */
770static void
771DEFUN(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 }
87f86b4e
DHW
792}
793
3e9aade1
SC
794static void
795DEFUN(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);
301dfc71 801 if (length > (size_t)sizeof(r.module_name)) {
3e9aade1
SC
802 length = sizeof(r.module_name);
803 }
87f86b4e 804
3e9aade1
SC
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);
87f86b4e 811
3e9aade1
SC
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]));
87f86b4e
DHW
818
819
820
3e9aade1 821}
87f86b4e
DHW
822
823static void
3e9aade1
SC
824DEFUN(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
838static int
839DEFUN(comp,(ap, bp),
9872a49c
SC
840 CONST PTR ap AND
841 CONST PTR bp)
3e9aade1 842{
9872a49c
SC
843 arelent *a = *((arelent **)ap);
844 arelent *b = *((arelent **)bp);
3e9aade1
SC
845 return a->address - b->address;
846}
847
848/*
849 Writing data..
850
851*/
852static void
853DEFUN(oasys_write_data, (abfd),
854 bfd *CONST abfd)
87f86b4e 855{
3e9aade1 856 asection *s;
87f86b4e 857 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
3e9aade1
SC
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);
87f86b4e 871 }
3e9aade1
SC
872 current_byte_index = 0;
873 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
874
301dfc71 875 while ((size_t)current_byte_index < s->size)
3e9aade1
SC
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);
9872a49c 887 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
3e9aade1
SC
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 }
87f86b4e
DHW
978 }
979}
3e9aade1
SC
980static boolean
981DEFUN(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
87f86b4e
DHW
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*/
3e9aade1
SC
1000static boolean
1001DEFUN(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)
87f86b4e 1007{
3e9aade1
SC
1008 if (count != 0) {
1009 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1010 {
1011 oasys_per_section(section)->data =
9872a49c 1012 (bfd_byte *)(bfd_alloc(abfd,section->size));
3e9aade1
SC
1013 }
1014 (void) memcpy(oasys_per_section(section)->data + offset,
1015 location,
1016 count);
87f86b4e 1017 }
87f86b4e
DHW
1018 return true;
1019}
1020
1021
1022
87f86b4e
DHW
1023/* Native-level interface to symbols. */
1024
1025/* We read the symbols into a buffer, which is discarded when this
1026function exits. We read the strings into a buffer large enough to
1027hold them all plus all the cached symbol entries. */
1028
3e9aade1
SC
1029static asymbol *
1030DEFUN(oasys_make_empty_symbol,(abfd),
1031 bfd *abfd)
87f86b4e
DHW
1032{
1033
1034 oasys_symbol_type *new =
9872a49c 1035 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
87f86b4e
DHW
1036 new->symbol.the_bfd = abfd;
1037 return &new->symbol;
1038
1039}
1040
87f86b4e
DHW
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
1046BFD_NO_MORE_SYMBOLS if there are none? */
1047
87f86b4e 1048
87f86b4e
DHW
1049
1050boolean
1051oasys_close_and_cleanup (abfd)
1052bfd *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:
3e9aade1 1062 if (!oasys_write_object_contents (abfd)) {
87f86b4e
DHW
1063 return false;
1064 }
1065 break;
1066 default:
1067 bfd_error = invalid_operation;
1068 return false;
1069 }
1070
1071
87f86b4e
DHW
1072
1073 return true;
1074}
1075
1076static bfd *
1077oasys_openr_next_archived_file(arch, prev)
1078bfd *arch;
1079bfd *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 */
3e9aade1 1099 p->abfd->arelt_data = (PTR)p;
87f86b4e
DHW
1100 }
1101 return p->abfd;
1102 }
1103 else {
1104 bfd_error = no_more_archived_files;
1105 return (bfd *)NULL;
1106 }
1107}
1108
1109static boolean
1110oasys_find_nearest_line(abfd,
1111 section,
1112 symbols,
1113 offset,
1114 filename_ptr,
1115 functionname_ptr,
1116 line_ptr)
1117bfd *abfd;
1118asection *section;
1119asymbol **symbols;
1120bfd_vma offset;
1121char **filename_ptr;
1122char **functionname_ptr;
1123unsigned int *line_ptr;
1124{
1125 return false;
1126
1127}
1128
1129static int
9872a49c 1130oasys_generic_stat_arch_elt(abfd, buf)
87f86b4e
DHW
1131bfd *abfd;
1132struct stat *buf;
1133{
a6dab071 1134 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
87f86b4e
DHW
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
9872a49c
SC
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
87f86b4e
DHW
1158
1159/*SUPPRESS 460 */
1160bfd_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 */
87f86b4e
DHW
1171 ' ', /* ar_pad_char */
1172 16, /* ar_max_namelen */
87f86b4e
DHW
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 },
9872a49c 1188JUMP_TABLE(oasys)
87f86b4e 1189};
This page took 0.074129 seconds and 4 git commands to generate.