fix two small bugs: quick-append no longer used to create fresh archives;
[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
27#define obstack_chunk_alloc malloc
28#define obstack_chunk_free free
29
3e9aade1
SC
30#define oasys_malloc(abfd,size) \
31 obstack_alloc( &( oasys_data(abfd)->oasys_obstack), (size))
32
87f86b4e
DHW
33typedef void generic_symbol_type;
34
35
3e9aade1
SC
36static void
37DEFUN(oasys_read_record,(abfd, record),
38 bfd *CONST abfd AND
87f86b4e
DHW
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}
48static size_t
3e9aade1
SC
49DEFUN(oasys_string_length,(record),
50 oasys_record_union_type *record)
87f86b4e
DHW
51{
52return record->header.length
53 - ((char *)record->symbol.name - (char *)record);
54}
55
56/*****************************************************************************/
57
58/*
59
60Slurp the symbol table by reading in all the records at the start file
61till we get to the first section record.
62
3e9aade1
SC
63We'll sort the symbolss into two lists, defined and undefined. The
64undefined symbols will be placed into the table according to their
65refno.
66
67We do this by placing all undefined symbols at the front of the table
68moving in, and the defined symbols at the end of the table moving back.
87f86b4e
DHW
69
70*/
71
72static boolean
3e9aade1
SC
73DEFUN(oasys_slurp_symbol_table,(abfd),
74 bfd * CONST abfd)
87f86b4e
DHW
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 =
3e9aade1 90 (asymbol *)oasys_malloc(abfd, sizeof(asymbol) * abfd->symcount);
de7c1ff6
SC
91#ifdef UNDERSCORE_HACK
92 /* buy 1 more char for each symbol to keep the underscore in*/
3e9aade1
SC
93 data->strings = oasys_malloc(abfd, data->symbol_string_length +
94 abfd->symcount);
de7c1ff6 95#else
3e9aade1 96 data->strings = oasys_malloc(abfd, data->symbol_string_length);
de7c1ff6 97#endif
87f86b4e
DHW
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) {
de7c1ff6 105
87f86b4e
DHW
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 {
3e9aade1 113 int flag = record.header.type == oasys_record_is_local_enum ?
de7c1ff6
SC
114 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
115
116
87f86b4e 117 size_t length = oasys_string_length(&record);
3e9aade1 118 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
87f86b4e
DHW
119 case RELOCATION_TYPE_ABS:
120 dest = dest_defined--;
121 dest->section = 0;
de7c1ff6 122 dest->flags = BSF_ABSOLUTE | flag;
87f86b4e
DHW
123 break;
124 case RELOCATION_TYPE_REL:
125 dest = dest_defined--;
126 dest->section =
3e9aade1 127 oasys_data(abfd)->sections[record.symbol.relb &
87f86b4e
DHW
128 RELOCATION_SECT_BITS];
129 if (record.header.type == oasys_record_is_local_enum)
130 {
de7c1ff6 131 dest->flags = BSF_LOCAL;
87f86b4e
DHW
132 }
133 else {
134
de7c1ff6 135 dest->flags = flag;
87f86b4e
DHW
136 }
137 break;
138 case RELOCATION_TYPE_UND:
3e9aade1 139 dest = data->symbols + bfd_h_getshort(abfd, &record.symbol.refno[0]);
87f86b4e
DHW
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;
3e9aade1
SC
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 }
de7c1ff6 162#endif
87f86b4e 163 memcpy(string_ptr, record.symbol.name, length);
de7c1ff6
SC
164
165
87f86b4e
DHW
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
3e9aade1
SC
178static size_t
179DEFUN(oasys_get_symtab_upper_bound,(abfd),
180 bfd *CONST abfd)
87f86b4e
DHW
181{
182 oasys_slurp_symbol_table (abfd);
183
de7c1ff6 184 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
87f86b4e
DHW
185}
186
187/*
188*/
189
190extern bfd_target oasys_vec;
191
192unsigned int
3e9aade1
SC
193DEFUN(oasys_get_symtab,(abfd, location),
194 bfd *abfd AND
195 asymbol **location)
87f86b4e
DHW
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);
3e9aade1
SC
214static bfd_target *
215DEFUN(oasys_archive_p,(abfd),
216 bfd *abfd)
87f86b4e
DHW
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 =
3e9aade1 253 (oasys_ar_data_type*) oasys_malloc(abfd, sizeof(oasys_ar_data_type));
87f86b4e
DHW
254
255
256 oasys_module_info_type *module =
257 (oasys_module_info_type*)
3e9aade1 258 oasys_malloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
87f86b4e
DHW
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);
3e9aade1 273 module[i].name = oasys_malloc(abfd,record.mod_name_length+1);
87f86b4e
DHW
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
3e9aade1
SC
288static boolean
289DEFUN(oasys_mkobject,(abfd),
290 bfd *abfd)
87f86b4e 291{
3e9aade1 292 struct obstack tmp_obstack;
87f86b4e 293 oasys_data_type *oasys;
3e9aade1
SC
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}
87f86b4e 302
3e9aade1
SC
303#define MAX_SECS 16
304static bfd_target *
305DEFUN(oasys_object_p,(abfd),
306 bfd *abfd)
307{
308 oasys_data_type *oasys;
87f86b4e 309 boolean loop = true;
87f86b4e 310 boolean had_usefull = false;
3e9aade1
SC
311 oasys_data(abfd) = 0;
312 oasys_mkobject(abfd);
313 oasys = oasys_data(abfd);
314 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
87f86b4e
DHW
315
316 /* Point to the start of the file */
317 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
3e9aade1 318 oasys->symbol_string_length = 0;
87f86b4e
DHW
319 /* Inspect the records, but only keep the section info -
320 remember the size of the symbols
321 */
3e9aade1 322 oasys->first_data_record = 0;
87f86b4e
DHW
323 while (loop) {
324 oasys_record_union_type record;
325 oasys_read_record(abfd, &record);
3e9aade1
SC
326 if (record.header.length < sizeof(record.header))
327 goto fail;
328
87f86b4e
DHW
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++;
3e9aade1 338 oasys->symbol_string_length += 1 + oasys_string_length(&record);
87f86b4e
DHW
339 had_usefull = true;
340 break;
341 case oasys_record_is_section_enum:
3e9aade1
SC
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();
87f86b4e 362 }
87f86b4e 363
3e9aade1
SC
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 }
87f86b4e
DHW
369 break;
370 case oasys_record_is_data_enum:
3e9aade1 371 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
87f86b4e
DHW
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:
3e9aade1 376 if (had_usefull == false) goto fail;
87f86b4e
DHW
377 loop = false;
378 break;
379 default:
3e9aade1 380 goto fail;
87f86b4e
DHW
381 }
382 }
87f86b4e
DHW
383 oasys->symbols = (asymbol *)NULL;
384 /*
3e9aade1
SC
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 */
87f86b4e
DHW
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;
3e9aade1
SC
394
395 fail:
396 (void) obstack_finish(&oasys->oasys_obstack);
397 return (bfd_target *)NULL;
87f86b4e
DHW
398}
399
400
3e9aade1
SC
401static void
402DEFUN(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)
87f86b4e
DHW
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 {
3e9aade1 415CONST char *section_name = symbol->section == (asection *)NULL ?
87f86b4e
DHW
416 "*abs" : symbol->section->name;
417
3e9aade1 418 bfd_print_symbol_vandf((PTR)file,symbol);
87f86b4e
DHW
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*/
431static reloc_howto_type howto_table[]=
432{
433/* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
434
3e9aade1
SC
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}
87f86b4e
DHW
439};
440
441/* Read in all the section data and relocation stuff too */
3e9aade1
SC
442static boolean
443DEFUN(oasys_slurp_section_data,(abfd),
444 bfd *CONST abfd)
87f86b4e
DHW
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;
3e9aade1 458 per->data = (bfd_byte *) oasys_malloc(abfd, s->size);
87f86b4e 459 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
3e9aade1
SC
460 per->had_vma = false;
461 s->reloc_count = 0;
87f86b4e
DHW
462 }
463
de7c1ff6 464 if (data->first_data_record == 0) return true;
87f86b4e
DHW
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:
de7c1ff6 472 {
87f86b4e 473
de7c1ff6
SC
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 ;
de7c1ff6 480 unsigned int count;
3e9aade1
SC
481 asection * section =
482 data->sections[record.data.relb & RELOCATION_SECT_BITS];
483 bfd_vma dst_offset ;
de7c1ff6 484 per = oasys_per_section(section);
3e9aade1
SC
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
de7c1ff6
SC
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 *)
3e9aade1
SC
534 oasys_malloc(abfd,
535 sizeof(oasys_reloc_type));
de7c1ff6
SC
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];
3e9aade1 546 r->relent.addend = - r->relent.section->vma;
de7c1ff6
SC
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++;
de7c1ff6
SC
551 }
552 break;
553
554
555 case RELOCATION_TYPE_UND:
556 {
557 oasys_reloc_type *r =
558 (oasys_reloc_type *)
3e9aade1
SC
559 oasys_malloc(abfd,
560 sizeof(oasys_reloc_type));
de7c1ff6
SC
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;
de7c1ff6 574 section->reloc_count++;
3e9aade1 575
de7c1ff6
SC
576 src+=2;
577 }
578 break;
579 case RELOCATION_TYPE_COM:
580 BFD_FAIL();
581 }
582 }
583 *dst_ptr++ = *src++;
87f86b4e 584 }
87f86b4e 585 }
de7c1ff6
SC
586 }
587 }
87f86b4e
DHW
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
3e9aade1 603bfd_error_vector_type bfd_error_vector;
87f86b4e 604
3e9aade1
SC
605static boolean
606DEFUN(oasys_new_section_hook,(abfd, newsect),
607 bfd *abfd AND
608 asection *newsect)
87f86b4e
DHW
609{
610 newsect->used_by_bfd = (oasys_per_section_type *)
3e9aade1 611 oasys_malloc(abfd, sizeof(oasys_per_section_type));
87f86b4e
DHW
612 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
613 oasys_per_section(newsect)->section = newsect;
614 oasys_per_section(newsect)->offset = 0;
3e9aade1
SC
615 newsect->alignment_power = 3;
616 /* Turn the section string into an index */
617
618 sscanf(newsect->name,"%u", &newsect->target_index);
619
87f86b4e
DHW
620 return true;
621}
622
623
3e9aade1
SC
624static unsigned int
625DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
626 bfd *abfd AND
627 sec_ptr asect)
87f86b4e
DHW
628{
629 oasys_slurp_section_data(abfd);
630 return (asect->reloc_count+1) * sizeof(arelent *);
631}
632
633static boolean
3e9aade1
SC
634DEFUN(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)
87f86b4e
DHW
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
648unsigned int
3e9aade1
SC
649DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
650 bfd *abfd AND
651 sec_ptr section AND
652 arelent **relptr AND
653 asymbol **symbols)
87f86b4e 654{
3e9aade1 655 unsigned int reloc_count = 0;
87f86b4e
DHW
656 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
657 while (src != (oasys_reloc_type *)NULL) {
3e9aade1
SC
658 if (src->relent.section == (asection *)NULL)
659 {
660 src->relent.sym_ptr_ptr = symbols + src->symbol;
661 }
87f86b4e
DHW
662 *relptr ++ = &src->relent;
663 src = src->next;
3e9aade1 664 reloc_count++;
87f86b4e
DHW
665 }
666 *relptr = (arelent *)NULL;
3e9aade1 667 return section->reloc_count = reloc_count;
87f86b4e
DHW
668}
669
3e9aade1 670
87f86b4e 671boolean
3e9aade1
SC
672DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
673 bfd *abfd AND
674 enum bfd_architecture arch AND
675 unsigned long machine)
87f86b4e
DHW
676{
677 abfd->obj_arch = arch;
678 abfd->obj_machine = machine;
679 return true;
680}
681
3e9aade1
SC
682
683
684/* Writing */
685
686
687/* Calculate the checksum and write one record */
688static void
689DEFUN(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)
87f86b4e 694{
3e9aade1
SC
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++;
87f86b4e 706 }
3e9aade1
SC
707 record->header.check_sum = 0xff & (- checksum);
708 bfd_write((PTR)record, 1, size, abfd);
709}
87f86b4e 710
3e9aade1
SC
711
712/* Write out all the symbols */
713static void
714DEFUN(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 */
779static void
780DEFUN(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 }
87f86b4e
DHW
801}
802
3e9aade1
SC
803static void
804DEFUN(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 }
87f86b4e 813
3e9aade1
SC
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);
87f86b4e 820
3e9aade1
SC
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]));
87f86b4e
DHW
827
828
829
3e9aade1 830}
87f86b4e
DHW
831
832static void
3e9aade1
SC
833DEFUN(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
847static int
848DEFUN(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*/
861static void
862DEFUN(oasys_write_data, (abfd),
863 bfd *CONST abfd)
87f86b4e 864{
3e9aade1 865 asection *s;
87f86b4e 866 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
3e9aade1
SC
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);
87f86b4e 880 }
3e9aade1
SC
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 }
87f86b4e
DHW
987 }
988}
3e9aade1
SC
989static boolean
990DEFUN(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
87f86b4e
DHW
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*/
3e9aade1
SC
1009static boolean
1010DEFUN(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)
87f86b4e 1016{
3e9aade1
SC
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);
87f86b4e 1026 }
87f86b4e
DHW
1027 return true;
1028}
1029
1030
1031
87f86b4e
DHW
1032/* Native-level interface to symbols. */
1033
1034/* We read the symbols into a buffer, which is discarded when this
1035function exits. We read the strings into a buffer large enough to
1036hold them all plus all the cached symbol entries. */
1037
3e9aade1
SC
1038static asymbol *
1039DEFUN(oasys_make_empty_symbol,(abfd),
1040 bfd *abfd)
87f86b4e
DHW
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
87f86b4e
DHW
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
1055BFD_NO_MORE_SYMBOLS if there are none? */
1056
87f86b4e 1057
87f86b4e
DHW
1058
1059boolean
1060oasys_close_and_cleanup (abfd)
1061bfd *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:
3e9aade1 1071 if (!oasys_write_object_contents (abfd)) {
87f86b4e
DHW
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) {
3e9aade1
SC
1082 /* It's so easy to throw everything away */
1083(void) obstack_finish(&(oasys_data(abfd)->oasys_obstack));
87f86b4e
DHW
1084 }
1085
1086 return true;
1087}
1088
1089static bfd *
1090oasys_openr_next_archived_file(arch, prev)
1091bfd *arch;
1092bfd *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 */
3e9aade1 1112 p->abfd->arelt_data = (PTR)p;
87f86b4e
DHW
1113 }
1114 return p->abfd;
1115 }
1116 else {
1117 bfd_error = no_more_archived_files;
1118 return (bfd *)NULL;
1119 }
1120}
1121
1122static boolean
1123oasys_find_nearest_line(abfd,
1124 section,
1125 symbols,
1126 offset,
1127 filename_ptr,
1128 functionname_ptr,
1129 line_ptr)
1130bfd *abfd;
1131asection *section;
1132asymbol **symbols;
1133bfd_vma offset;
1134char **filename_ptr;
1135char **functionname_ptr;
1136unsigned int *line_ptr;
1137{
1138 return false;
1139
1140}
1141
1142static int
1143oasys_stat_arch_elt(abfd, buf)
1144bfd *abfd;
1145struct 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 */
1163bfd_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.138661 seconds and 4 git commands to generate.