]> Git Repo - binutils.git/blob - bfd/oasys.c
Make all callers of malloc or realloc (including via obstacks)
[binutils.git] / bfd / oasys.c
1 /* BFD back-end for oasys objects.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Written by Steve Chamberlain of Cygnus Support, <[email protected]>.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #define UNDERSCORE_HACK 1
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "oasys.h"
26 #include "liboasys.h"
27
28 /* XXX - FIXME.  offsetof belongs in the system-specific files in
29    ../include/sys. */
30 /* Define offsetof for those systems which lack it */
31
32 #ifndef offsetof
33 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier) 
34 #endif
35
36 static boolean oasys_write_sections PARAMS ((bfd *));
37
38 /* Read in all the section data and relocation stuff too */
39 PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
40
41 static void 
42 DEFUN(oasys_read_record,(abfd, record),
43       bfd *CONST abfd AND 
44       oasys_record_union_type *record)
45 {
46
47   bfd_read((PTR)record, 1, sizeof(record->header), abfd);
48
49   if ((size_t) record->header.length <= (size_t) sizeof (record->header))
50     return;
51   bfd_read((PTR)(((char *)record )+ sizeof(record->header)),
52            1, record->header.length - sizeof(record->header),
53            abfd);
54 }
55 static size_t
56 DEFUN(oasys_string_length,(record),
57       oasys_record_union_type *record)
58 {
59 return  record->header.length
60         - ((char *)record->symbol.name - (char *)record);
61 }
62
63 /*****************************************************************************/
64
65 /*
66
67 Slurp the symbol table by reading in all the records at the start file
68 till we get to the first section record.
69
70 We'll sort the symbolss into  two lists, defined and undefined. The
71 undefined symbols will be placed into the table according to their
72 refno. 
73
74 We do this by placing all undefined symbols at the front of the table
75 moving in, and the defined symbols at the end of the table moving back.
76
77 */
78
79 static boolean
80 DEFUN(oasys_slurp_symbol_table,(abfd),
81     bfd * CONST abfd)
82 {
83   oasys_record_union_type record;
84   oasys_data_type *data = OASYS_DATA(abfd);
85   boolean loop = true;
86   asymbol *dest_defined;
87   asymbol *dest;
88   char *string_ptr;
89
90
91   if (data->symbols != (asymbol *)NULL) {
92     return true;
93   }
94   /* Buy enough memory for all the symbols and all the names */
95   data->symbols = 
96     (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
97 #ifdef UNDERSCORE_HACK
98   /* buy 1 more char for each symbol to keep the underscore in*/
99   data->strings = bfd_alloc(abfd, data->symbol_string_length +
100                             abfd->symcount);
101 #else
102   data->strings = bfd_alloc(abfd, data->symbol_string_length);
103 #endif
104   if (!data->symbols || !data->strings)
105     {
106       bfd_error = no_memory;
107       return false;
108     }
109
110   dest_defined = data->symbols + abfd->symcount -1;
111
112   string_ptr = data->strings;
113   bfd_seek(abfd, (file_ptr)0, SEEK_SET);
114   while (loop) {
115
116     oasys_read_record(abfd, &record);
117     switch (record.header.type) {
118     case oasys_record_is_header_enum:
119       break;
120     case oasys_record_is_local_enum:
121     case oasys_record_is_symbol_enum:
122         {
123           int     flag = record.header.type == (int)oasys_record_is_local_enum ?
124             (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
125
126
127           size_t length = oasys_string_length(&record);
128           switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
129           case RELOCATION_TYPE_ABS:
130             dest = dest_defined--;
131             dest->section = &bfd_abs_section;
132             dest->flags =  0;
133             
134             break;
135           case RELOCATION_TYPE_REL:
136             dest = dest_defined--;
137             dest->section =
138               OASYS_DATA(abfd)->sections[record.symbol.relb &
139                                          RELOCATION_SECT_BITS];
140             if (record.header.type == (int)oasys_record_is_local_enum) 
141                 {
142                   dest->flags = BSF_LOCAL;
143                   if (dest->section ==(asection *)(~0)) {
144                     /* It seems that sometimes internal symbols are tied up, but
145                        still get output, even though there is no
146                        section */
147                     dest->section = 0;
148                   }
149                 }
150             else {
151
152               dest->flags = flag;
153             }
154             break;
155           case RELOCATION_TYPE_UND:
156             dest = data->symbols + bfd_h_get_16(abfd, record.symbol.refno);
157             dest->section = &bfd_und_section;
158             break;
159           case RELOCATION_TYPE_COM:
160             dest = dest_defined--;
161             dest->name = string_ptr;
162             dest->the_bfd = abfd;
163
164             dest->section = &bfd_com_section;
165
166             break;
167           default:
168             dest = dest_defined--;
169             BFD_ASSERT(0);
170             break;
171           }
172           dest->name = string_ptr;
173           dest->the_bfd = abfd;
174           dest->udata = (PTR)NULL;
175           dest->value = bfd_h_get_32(abfd, record.symbol.value);
176
177 #ifdef UNDERSCORE_HACK
178           if (record.symbol.name[0] != '_') {
179             string_ptr[0] = '_';
180             string_ptr++;
181           }
182 #endif
183           memcpy(string_ptr, record.symbol.name, length);
184
185
186           string_ptr[length] =0;
187           string_ptr += length +1;
188         }
189       break;
190     default:
191       loop = false;
192     }
193   }
194   return true;
195 }
196
197 static unsigned int
198 DEFUN(oasys_get_symtab_upper_bound,(abfd),
199      bfd *CONST abfd)
200 {
201   oasys_slurp_symbol_table (abfd);
202
203   return    (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
204 }
205
206 /* 
207 */
208
209 extern bfd_target oasys_vec;
210
211 unsigned int
212 DEFUN(oasys_get_symtab,(abfd, location),
213       bfd *abfd AND
214       asymbol **location)
215 {
216   asymbol *symbase ;
217   unsigned int counter ;
218   if (oasys_slurp_symbol_table(abfd) == false) {
219     return 0;
220   }
221   symbase = OASYS_DATA(abfd)->symbols;
222   for (counter = 0; counter < abfd->symcount; counter++) {
223     *(location++) = symbase++;
224   }
225   *location = 0;
226   return abfd->symcount;
227 }
228
229 /***********************************************************************
230 *  archive stuff 
231 */
232
233 static bfd_target *
234 DEFUN(oasys_archive_p,(abfd),
235       bfd *abfd)
236 {
237   oasys_archive_header_type header;
238   oasys_extarchive_header_type header_ext;
239   unsigned int i;
240   file_ptr filepos;  
241
242   bfd_seek(abfd, (file_ptr) 0, false);
243   bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);
244
245   header.version = bfd_h_get_32(abfd, header_ext.version);
246   header.mod_count = bfd_h_get_32(abfd, header_ext.mod_count);
247   header.mod_tbl_offset = bfd_h_get_32(abfd, header_ext.mod_tbl_offset);
248   header.sym_tbl_size = bfd_h_get_32(abfd, header_ext.sym_tbl_size);
249   header.sym_count = bfd_h_get_32(abfd, header_ext.sym_count);
250   header.sym_tbl_offset = bfd_h_get_32(abfd, header_ext.sym_tbl_offset);
251   header.xref_count = bfd_h_get_32(abfd, header_ext.xref_count);
252   header.xref_lst_offset = bfd_h_get_32(abfd, header_ext.xref_lst_offset);
253
254   /*
255     There isn't a magic number in an Oasys archive, so the best we
256     can do to verify reasnableness is to make sure that the values in
257     the header are too weird
258     */
259
260   if (header.version>10000 ||
261       header.mod_count>10000 ||
262       header.sym_count>100000 ||
263       header.xref_count > 100000) return (bfd_target *)NULL;
264
265   /*
266     That all worked, let's buy the space for the header and read in
267     the headers.
268     */
269     {
270       oasys_ar_data_type *ar =
271         (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
272
273       oasys_module_info_type *module = 
274         (oasys_module_info_type*)
275           bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
276       oasys_module_table_type record;
277
278       if (!ar || !module)
279         {
280           bfd_error = no_memory;
281           return NULL;
282         }
283
284       abfd->tdata.oasys_ar_data = ar;
285       ar->module = module;
286       ar->module_count = header.mod_count;
287
288       filepos = header.mod_tbl_offset;
289       for (i = 0; i < header.mod_count; i++) {
290         bfd_seek(abfd, filepos, SEEK_SET);
291
292         /* There are two ways of specifying the archive header */
293
294         if (0) {
295           oasys_extmodule_table_type_a_type record_ext;
296           bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
297         
298           record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
299           record.file_offset = bfd_h_get_32(abfd, record_ext.file_offset);
300
301           record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
302           record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
303           record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
304
305           module[i].name = bfd_alloc(abfd,33);
306           if (!module[i].name)
307             {
308               bfd_error = no_error;
309               return NULL;
310             }
311
312           memcpy(module[i].name, record_ext.mod_name, 33);
313           filepos +=
314             sizeof(record_ext) + 
315               record.dep_count * 4 +
316                 record.depee_count * 4 +
317                   record.sect_count * 8 + 187;
318         }
319         else {
320           oasys_extmodule_table_type_b_type record_ext;
321           bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
322         
323           record.mod_size = bfd_h_get_32(abfd, record_ext.mod_size);
324           record.file_offset = bfd_h_get_32(abfd, record_ext.file_offset);
325
326           record.dep_count = bfd_h_get_32(abfd, record_ext.dep_count);
327           record.depee_count = bfd_h_get_32(abfd, record_ext.depee_count);
328           record.sect_count = bfd_h_get_32(abfd, record_ext.sect_count);
329           record.module_name_size = bfd_h_get_32(abfd, record_ext.mod_name_length);
330
331           module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
332           if (!module[i].name)
333             {
334               bfd_error = no_error;
335               return NULL;
336             }
337           bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
338           module[i].name[record.module_name_size] = 0;
339           filepos +=
340             sizeof(record_ext) + 
341               record.dep_count * 4 +
342                 record.module_name_size + 1;
343
344         }
345
346
347         module[i].size = record.mod_size;
348         module[i].pos = record.file_offset;
349         module[i].abfd = 0;
350       }
351       
352     }
353   return abfd->xvec;
354 }
355
356 static boolean
357 DEFUN(oasys_mkobject,(abfd),
358       bfd *abfd)
359 {
360
361   abfd->tdata.oasys_obj_data =    (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type));
362   return abfd->tdata.oasys_obj_data ? true : false;
363 }
364
365 #define MAX_SECS 16
366 static bfd_target *
367 DEFUN(oasys_object_p,(abfd),
368       bfd *abfd)
369 {
370   oasys_data_type *oasys;
371   oasys_data_type *save = OASYS_DATA(abfd);
372   boolean loop = true;
373   boolean had_usefull = false;
374
375   abfd->tdata.oasys_obj_data = 0;
376   oasys_mkobject(abfd);
377   oasys = OASYS_DATA(abfd);
378   memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
379     
380   /* Point to the start of the file */
381   bfd_seek(abfd, (file_ptr)0, SEEK_SET);
382   oasys->symbol_string_length = 0;
383   /* Inspect the records, but only keep the section info -
384      remember the size of the symbols
385      */
386   oasys->first_data_record = 0;
387   while (loop) {
388     oasys_record_union_type record;
389     oasys_read_record(abfd, &record);
390     if ((size_t)record.header.length < (size_t)sizeof(record.header))
391       goto fail;
392
393
394     switch ((oasys_record_enum_type)(record.header.type)) {
395     case oasys_record_is_header_enum:
396       had_usefull = true;
397       break;
398     case oasys_record_is_symbol_enum:
399     case oasys_record_is_local_enum:
400       /* Count symbols and remember their size for a future malloc   */
401       abfd->symcount++;
402       oasys->symbol_string_length += 1 + oasys_string_length(&record);
403       had_usefull = true;
404       break;
405     case oasys_record_is_section_enum:
406         {
407           asection *s;
408           char *buffer;
409           unsigned int section_number;
410           if (record.section.header.length != sizeof(record.section))
411               {
412                 goto fail;
413               }
414           buffer = bfd_alloc(abfd, 3);
415           if (!buffer)
416             {
417               bfd_error = no_memory;
418               goto fail;
419             }
420           section_number= record.section.relb & RELOCATION_SECT_BITS;
421           sprintf(buffer,"%u", section_number);
422           s = bfd_make_section(abfd,buffer);
423           oasys->sections[section_number] = s;
424           switch (record.section.relb & RELOCATION_TYPE_BITS) {
425           case RELOCATION_TYPE_ABS:
426           case RELOCATION_TYPE_REL:
427             break;
428           case RELOCATION_TYPE_UND:
429           case RELOCATION_TYPE_COM:
430             BFD_FAIL();
431           }
432
433           s->_raw_size  = bfd_h_get_32(abfd, record.section.value);
434           s->vma = bfd_h_get_32(abfd, record.section.vma);
435           s->flags= 0;
436           had_usefull = true;
437         }
438       break;
439     case oasys_record_is_data_enum:
440       oasys->first_data_record = bfd_tell(abfd) - record.header.length;
441     case oasys_record_is_debug_enum:
442     case oasys_record_is_module_enum:
443     case oasys_record_is_named_section_enum:
444     case oasys_record_is_end_enum:
445       if (had_usefull == false) goto fail;
446       loop = false;
447       break;
448     default:
449       goto fail;
450     }
451   }
452   oasys->symbols = (asymbol *)NULL;
453   /* 
454     Oasys support several architectures, but I can't see a simple way
455     to discover which one is in a particular file - we'll guess 
456     */
457   bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0);
458   if (abfd->symcount != 0) {
459     abfd->flags |= HAS_SYMS;
460   }
461
462   /* 
463     We don't know if a section has data until we've read it..
464     */
465
466   oasys_slurp_section_data(abfd);
467
468
469   return abfd->xvec;
470
471  fail:
472   (void)  bfd_release(abfd, oasys);
473   abfd->tdata.oasys_obj_data = save;
474   return (bfd_target *)NULL;
475 }
476
477
478 static void 
479 DEFUN(oasys_get_symbol_info,(ignore_abfd, symbol, ret),
480       bfd *ignore_abfd AND
481       asymbol *symbol AND
482       symbol_info *ret)
483 {
484   bfd_symbol_info (symbol, ret);
485   if (!symbol->section)
486     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
487 }
488
489 static void 
490 DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),
491       bfd *ignore_abfd AND
492       PTR afile AND
493       asymbol *symbol AND
494       bfd_print_symbol_type how)
495 {
496   FILE *file = (FILE *)afile;
497
498   switch (how) {
499   case bfd_print_symbol_name:
500   case bfd_print_symbol_more:
501     fprintf(file,"%s", symbol->name);
502     break;
503   case bfd_print_symbol_all:
504     {
505       CONST char *section_name = symbol->section == (asection *)NULL ?
506         (CONST char *) "*abs" : symbol->section->name;
507
508       bfd_print_symbol_vandf((PTR)file,symbol);
509
510       fprintf(file," %-5s %s",
511               section_name,
512               symbol->name);
513     }
514     break;
515   }
516 }
517 /*
518  The howto table is build using the top two bits of a reloc byte to
519  index into it. The bits are PCREL,WORD/LONG
520 */
521 static reloc_howto_type howto_table[]= 
522 {
523
524 HOWTO(  0, 0,  1,   16, false,0,complain_overflow_bitfield,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
525 HOWTO(  0, 0,  2,   32, false,0,complain_overflow_bitfield,0,"abs32",true,0xffffffff, 0xffffffff,false),
526 HOWTO(  0, 0,  1,   16, true,0,complain_overflow_signed,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
527 HOWTO(  0, 0,  2,   32, true,0,complain_overflow_signed,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
528 };
529
530 /* Read in all the section data and relocation stuff too */
531 static boolean 
532 DEFUN(oasys_slurp_section_data,(abfd),
533   bfd *CONST abfd)
534 {
535   oasys_record_union_type record;
536   oasys_data_type *data = OASYS_DATA(abfd);
537   boolean loop = true;
538
539   oasys_per_section_type *per ;
540
541   asection *s;
542
543   /* See if the data has been slurped already .. */
544   for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
545     per =  oasys_per_section(s);
546     if (per->initialized == true) 
547       return true;
548   }
549
550   if (data->first_data_record == 0)  return true;
551
552   bfd_seek(abfd, data->first_data_record, SEEK_SET);
553   while (loop) {
554     oasys_read_record(abfd, &record);
555     switch (record.header.type) 
556         {
557         case oasys_record_is_header_enum:
558           break;
559         case oasys_record_is_data_enum:
560             {
561
562               bfd_byte *src = record.data.data;
563               bfd_byte *end_src = ((bfd_byte *)&record) + record.header.length;
564               bfd_byte *dst_ptr;
565               bfd_byte *dst_base_ptr;
566               unsigned int relbit;
567               unsigned int count;
568               asection *  section =
569                 data->sections[record.data.relb & RELOCATION_SECT_BITS];
570               bfd_vma dst_offset ;
571
572               per =  oasys_per_section(section);
573
574               if (per->initialized == false) 
575                   {
576                     per->data = (bfd_byte *) bfd_zalloc(abfd, section->_raw_size);
577                     if (!per->data)
578                       {
579                         bfd_error = no_memory;
580                         return false;
581                       }
582                     per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
583                     per->had_vma = false;
584                     per->initialized = true;
585                     section->reloc_count = 0;
586                     section->flags = SEC_ALLOC;
587                   }
588
589               dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
590               if (per->had_vma == false) {
591                 /* Take the first vma we see as the base */
592                 section->vma = dst_offset;
593                 per->had_vma = true;
594               }
595
596               dst_offset -=   section->vma;
597
598               dst_base_ptr = oasys_per_section(section)->data;
599               dst_ptr = oasys_per_section(section)->data +
600                 dst_offset;
601
602               if (src < end_src) {
603                 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
604               }
605               while (src < end_src) {
606                 unsigned char mod_byte = *src++;
607                 size_t gap = end_src - src;
608                 
609                 count = 8;
610                 if (mod_byte == 0 && gap >= 8) {
611                   dst_ptr[0] = src[0];
612                   dst_ptr[1] = src[1];
613                   dst_ptr[2] = src[2];
614                   dst_ptr[3] = src[3];
615                   dst_ptr[4] = src[4];
616                   dst_ptr[5] = src[5];
617                   dst_ptr[6] = src[6];
618                   dst_ptr[7] = src[7];
619                   dst_ptr+= 8;
620                   src += 8;
621                 }
622                 else {
623                   for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1) 
624                       {
625                         if (relbit & mod_byte) 
626                             {
627                               unsigned char reloc = *src;
628                               /* This item needs to be relocated */
629                               switch (reloc & RELOCATION_TYPE_BITS) {
630                               case RELOCATION_TYPE_ABS:
631
632                                 break;
633
634                               case RELOCATION_TYPE_REL: 
635                                   {
636                                     /* Relocate the item relative to the section */
637                                     oasys_reloc_type *r =
638                                       (oasys_reloc_type *)
639                                         bfd_alloc(abfd,
640                                                   sizeof(oasys_reloc_type));
641                                     if (!r)
642                                       {
643                                         bfd_error = no_memory;
644                                         return false;
645                                       }
646                                     *(per->reloc_tail_ptr) = r;
647                                     per->reloc_tail_ptr = &r->next;
648                                     r->next= (oasys_reloc_type *)NULL;
649                                     /* Reference to undefined symbol */
650                                     src++;
651                                     /* There is no symbol */
652                                     r->symbol = 0;
653                                     /* Work out the howto */
654                                     abort();
655 #if 0
656                                     r->relent.section =
657                                       data->sections[reloc &
658                                                      RELOCATION_SECT_BITS];
659
660                                     r->relent.addend = -
661                                       r->relent.section->vma;
662 #endif
663                                     r->relent.address = dst_ptr - dst_base_ptr;
664                                     r->relent.howto = &howto_table[reloc>>6];
665                                     r->relent.sym_ptr_ptr = (asymbol **)NULL;
666                                     section->reloc_count++;
667
668                                     /* Fake up the data to look like it's got the -ve pc in it, this makes
669                                        it much easier to convert into other formats. This is done by
670                                        hitting the addend.
671                                        */
672                                     if (r->relent.howto->pc_relative == true) {
673                                       r->relent.addend -= dst_ptr - dst_base_ptr;
674                                     }
675
676
677                                   }
678                                 break;
679
680
681                               case RELOCATION_TYPE_UND:
682                                   { 
683                                     oasys_reloc_type *r =
684                                       (oasys_reloc_type *)
685                                         bfd_alloc(abfd,
686                                                   sizeof(oasys_reloc_type));
687                                     if (!r)
688                                       {
689                                         bfd_error = no_memory;
690                                         return false;
691                                       }
692                                     *(per->reloc_tail_ptr) = r;
693                                     per->reloc_tail_ptr = &r->next;
694                                     r->next= (oasys_reloc_type *)NULL;
695                                     /* Reference to undefined symbol */
696                                     src++;
697                                     /* Get symbol number */
698                                     r->symbol = (src[0]<<8) | src[1];
699                                     /* Work out the howto */
700                                     abort();
701                                     
702 #if 0
703                                     r->relent.section = (asection
704                                                          *)NULL;
705 #endif
706                                     r->relent.addend = 0;
707                                     r->relent.address = dst_ptr - dst_base_ptr;
708                                     r->relent.howto = &howto_table[reloc>>6];
709                                     r->relent.sym_ptr_ptr = (asymbol **)NULL;
710                                     section->reloc_count++;
711
712                                     src+=2;
713                                     /* Fake up the data to look like it's got the -ve pc in it, this makes
714                                        it much easier to convert into other formats. This is done by
715                                        hitting the addend.
716                                        */
717                                     if (r->relent.howto->pc_relative == true) {
718                                       r->relent.addend -= dst_ptr - dst_base_ptr;
719                                     }
720
721                                 
722
723                                   }
724                                 break;
725                               case RELOCATION_TYPE_COM:
726                                 BFD_FAIL();
727                               }
728                             }
729                         *dst_ptr++ = *src++;
730                       }
731                 }
732               }   
733             }
734           break;
735         case oasys_record_is_local_enum:
736         case oasys_record_is_symbol_enum:
737         case oasys_record_is_section_enum:
738           break;
739         default:
740           loop = false;
741         }
742   }
743
744   return true;
745
746 }
747
748 static boolean
749 DEFUN(oasys_new_section_hook,(abfd, newsect),
750       bfd *abfd AND
751       asection *newsect)
752 {
753   newsect->used_by_bfd = (PTR)
754     bfd_alloc(abfd, sizeof(oasys_per_section_type));
755   if (!newsect->used_by_bfd)
756     {
757       bfd_error = no_memory;
758       return false;
759     }
760   oasys_per_section( newsect)->data = (bfd_byte *)NULL;
761   oasys_per_section(newsect)->section = newsect;
762   oasys_per_section(newsect)->offset  = 0;
763   oasys_per_section(newsect)->initialized = false;
764   newsect->alignment_power = 1;
765   /* Turn the section string into an index */
766
767   sscanf(newsect->name,"%u", &newsect->target_index);
768
769   return true;
770 }
771
772
773 static unsigned int
774 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
775       bfd *abfd AND
776       sec_ptr asect)
777 {
778   oasys_slurp_section_data(abfd);
779   return (asect->reloc_count+1) * sizeof(arelent *);
780 }
781
782 static boolean
783 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
784       bfd *abfd AND
785       sec_ptr section AND
786       PTR location AND
787       file_ptr offset AND
788       bfd_size_type count)
789 {
790   oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
791   oasys_slurp_section_data(abfd);
792   if (p->initialized == false) 
793       {
794         (void) memset(location, 0, (int)count);
795       }
796   else 
797       {
798         (void) memcpy(location,(PTR)( p->data + offset), (int)count);
799       }
800   return true;
801 }
802
803
804 unsigned int
805 DEFUN(oasys_canonicalize_reloc,(ignore_abfd, section, relptr, symbols),
806       bfd *ignore_abfd AND
807       sec_ptr section AND
808       arelent **relptr AND
809       asymbol **symbols)
810 {
811   unsigned int reloc_count = 0;
812   oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
813   while (src != (oasys_reloc_type *)NULL) {
814       abort();
815       
816 #if 0
817     if (src->relent.section == (asection *)NULL) 
818         {
819           src->relent.sym_ptr_ptr = symbols + src->symbol;
820         }
821 #endif
822
823     *relptr ++ = &src->relent;
824     src = src->next;
825     reloc_count++;
826   }
827   *relptr = (arelent *)NULL;
828   return section->reloc_count = reloc_count;
829 }
830
831
832
833
834 /* Writing */
835
836
837 /* Calculate the checksum and write one record */
838 static void 
839 DEFUN(oasys_write_record,(abfd, type, record, size),
840       bfd *CONST abfd AND
841       CONST oasys_record_enum_type type AND
842       oasys_record_union_type *record AND
843       CONST size_t size)
844 {
845   int checksum;
846   size_t i;
847   unsigned char *ptr;
848
849   record->header.length = size;
850   record->header.type = (int)type;
851   record->header.check_sum = 0;
852   record->header.fill = 0;
853   ptr = (unsigned char *)&record->pad[0];
854   checksum = 0;
855   for (i = 0; i < size; i++) {
856     checksum += *ptr++;
857   }
858   record->header.check_sum = 0xff & (- checksum);
859   bfd_write((PTR)record, 1, size, abfd);
860 }
861
862
863 /* Write out all the symbols */
864 static void 
865 DEFUN(oasys_write_syms, (abfd),
866       bfd * CONST abfd)
867 {
868   unsigned int count;
869   asymbol **generic = bfd_get_outsymbols(abfd);
870   unsigned int index = 0;
871   for (count = 0; count < bfd_get_symcount(abfd); count++) {
872
873     oasys_symbol_record_type symbol;
874     asymbol * CONST g = generic[count];
875
876     CONST    char *src = g->name;
877     char *dst = symbol.name;
878     unsigned int l = 0;
879
880     if (bfd_is_com_section (g->section)) {
881       symbol.relb = RELOCATION_TYPE_COM;
882       bfd_h_put_16(abfd, index, symbol.refno);
883       index++;
884     }
885     else if (g->section == & bfd_abs_section) {
886       symbol.relb = RELOCATION_TYPE_ABS;
887       bfd_h_put_16(abfd, 0, symbol.refno);
888
889     }
890     else if (g->section == &bfd_und_section) {
891       symbol.relb = RELOCATION_TYPE_UND ;
892       bfd_h_put_16(abfd, index, symbol.refno);
893       /* Overload the value field with the output index number */
894       index++;
895     }
896     else if (g->flags & BSF_DEBUGGING) {
897       /* throw it away */
898       continue;
899     }
900     else {
901       if (g->section == (asection *)NULL) {
902         /* Sometime, the oasys tools give out a symbol with illegal
903            bits in it, we'll output it in the same broken way */
904         
905         symbol.relb = RELOCATION_TYPE_REL | 0;
906       }
907       else {
908         symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
909       }
910       bfd_h_put_16(abfd, 0, symbol.refno);
911     }
912 #ifdef UNDERSCORE_HACK
913     if (src[l] == '_')
914       dst[l++] = '.';
915 #endif
916     while (src[l]) {
917       dst[l] = src[l];
918       l++;
919     }
920
921     bfd_h_put_32(abfd, g->value, symbol.value);
922
923       
924     if (g->flags & BSF_LOCAL) {
925       oasys_write_record(abfd,  
926                          oasys_record_is_local_enum,
927                          (oasys_record_union_type *) &symbol,
928                          offsetof(oasys_symbol_record_type, name[0]) + l);
929     }
930     else {
931       oasys_write_record(abfd,  
932                          oasys_record_is_symbol_enum,
933                          (oasys_record_union_type *) &symbol,
934                          offsetof(oasys_symbol_record_type, name[0]) + l);
935     }
936     g->value = index-1;
937   }
938 }
939
940
941   /* Write a section header for each section */
942 static boolean
943 oasys_write_sections (abfd)
944      bfd *abfd;
945 {
946   asection *s;
947   static oasys_section_record_type out;
948
949   for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
950     if (!isdigit(s->name[0])) 
951         {
952           bfd_error = nonrepresentable_section;
953           return false;
954         }
955     out.relb = RELOCATION_TYPE_REL | s->target_index;
956     bfd_h_put_32(abfd, s->_cooked_size, out.value);
957     bfd_h_put_32(abfd, s->vma, out.vma);
958
959     oasys_write_record(abfd,
960                        oasys_record_is_section_enum,
961                        (oasys_record_union_type *) &out,
962                        sizeof(out));
963   }
964   return true;
965 }
966
967 static void
968 DEFUN(oasys_write_header, (abfd),
969       bfd *CONST abfd)
970 {
971   /* Create and write the header */
972   oasys_header_record_type r;
973   size_t length = strlen(abfd->filename);
974   if (length > (size_t)sizeof(r.module_name)) {
975     length = sizeof(r.module_name);
976   }
977
978   (void)memcpy(r.module_name,
979                abfd->filename,
980                length);
981   (void)memset(r.module_name + length,
982                ' ',
983                sizeof(r.module_name) - length);
984
985   r.version_number = OASYS_VERSION_NUMBER;
986   r.rev_number = OASYS_REV_NUMBER;
987   oasys_write_record(abfd,
988                      oasys_record_is_header_enum,
989                      (oasys_record_union_type *)&r,
990                      offsetof(oasys_header_record_type, description[0]));
991
992
993
994 }
995
996 static void
997 DEFUN(oasys_write_end,(abfd),
998       bfd *CONST abfd)
999 {
1000   oasys_end_record_type end;
1001   unsigned char null = 0;
1002   end.relb = RELOCATION_TYPE_ABS;
1003   bfd_h_put_32(abfd, abfd->start_address, end.entry); 
1004   bfd_h_put_16(abfd, 0, end.fill);
1005   end.zero = 0;
1006   oasys_write_record(abfd,
1007                      oasys_record_is_end_enum,
1008                      (oasys_record_union_type *)&end,
1009                      sizeof(end));
1010   bfd_write((PTR)&null, 1, 1, abfd);
1011 }
1012
1013 static int 
1014 DEFUN(comp,(ap, bp),
1015    CONST PTR ap AND
1016    CONST PTR bp)
1017 {
1018   arelent *a = *((arelent **)ap);
1019   arelent *b = *((arelent **)bp);
1020   return a->address - b->address;
1021 }
1022
1023 /*
1024  Writing data..
1025  
1026 */
1027 static void
1028 DEFUN(oasys_write_data, (abfd),
1029       bfd *CONST abfd)
1030 {
1031   asection *s;
1032   for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
1033     if (s->flags & SEC_LOAD) {
1034       bfd_byte *raw_data = oasys_per_section(s)->data;
1035       oasys_data_record_type processed_data;
1036       bfd_size_type current_byte_index = 0;
1037       unsigned int relocs_to_go = s->reloc_count;
1038       arelent **p = s->orelocation;
1039       if (s->reloc_count != 0) {
1040 /* Sort the reloc records so it's easy to insert the relocs into the
1041            data */
1042     
1043         qsort(s->orelocation,
1044               s->reloc_count,
1045               sizeof(arelent **),
1046               comp);
1047       }
1048       current_byte_index = 0;
1049       processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
1050
1051       while (current_byte_index < s->_cooked_size) 
1052           {
1053             /* Scan forwards by eight bytes or however much is left and see if
1054                there are any relocations going on */
1055             bfd_byte *mod = &processed_data.data[0];
1056             bfd_byte *dst = &processed_data.data[1];
1057
1058             unsigned int i = 0;
1059             *mod = 0;
1060
1061
1062             bfd_h_put_32(abfd, s->vma + current_byte_index,
1063                          processed_data.addr);
1064
1065             /* Don't start a relocation unless you're sure you can finish it
1066                within the same data record.  The worst case relocation is a
1067                4-byte relocatable value which is split across two modification
1068                bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
1069                1 modification byte + 2 data = 8 bytes total).  That's where
1070                the magic number 8 comes from.
1071             */
1072             while (current_byte_index < s->_raw_size && dst <=
1073                 &processed_data.data[sizeof(processed_data.data)-8]) {
1074             
1075
1076                 if (relocs_to_go != 0) {        
1077                   arelent *r = *p;
1078                   const reloc_howto_type * const how=r->howto;
1079                   /* There is a relocation, is it for this byte ? */
1080                   if (r->address == current_byte_index) {
1081                     unsigned char rel_byte;
1082
1083                     p++;
1084                     relocs_to_go--;
1085
1086                     *mod |= (1<<i);
1087                     if(how->pc_relative) {
1088                       rel_byte = RELOCATION_PCREL_BIT;
1089
1090                       /* Also patch the raw data so that it doesn't have
1091                          the -ve stuff any more */
1092                       if (how->size != 2) {
1093                         bfd_put_16(abfd, 
1094                                    bfd_get_16(abfd,raw_data) +
1095                                    current_byte_index, raw_data);
1096                       }
1097
1098                       else {
1099                         bfd_put_32(abfd, 
1100                                    bfd_get_32(abfd,raw_data) +
1101                                    current_byte_index, raw_data);
1102                       }
1103                     }
1104                     else {
1105                       rel_byte = 0;
1106                     }
1107                     if (how->size ==2) {
1108                       rel_byte |= RELOCATION_32BIT_BIT;
1109                     }
1110                   
1111                     /* Is this a section relative relocation, or a symbol
1112                        relative relocation ? */
1113                     abort();
1114         
1115 #if 0
1116                     if (r->section != (asection*)NULL) 
1117                         {
1118                           /* The relent has a section attached, so it must be section
1119                              relative */
1120                           rel_byte |= RELOCATION_TYPE_REL;
1121                           rel_byte |= r->section->output_section->target_index;
1122                           *dst++ = rel_byte;
1123                         }
1124                     else 
1125 #endif
1126                         {
1127                           asymbol *p = *(r->sym_ptr_ptr);
1128
1129                           /* If this symbol has a section attached, then it
1130                              has already been resolved.  Change from a symbol
1131                              ref to a section ref */
1132                           if(p->section != (asection *)NULL) {
1133                             rel_byte |= RELOCATION_TYPE_REL;
1134                             rel_byte |=
1135                               p->section->output_section->target_index;
1136                             *dst++ = rel_byte;
1137                           }
1138                           else {
1139                             rel_byte |= RELOCATION_TYPE_UND;
1140                             *dst++ = rel_byte;
1141                             /* Next two bytes are a symbol index - we can get
1142                                this from the symbol value which has been zapped
1143                                into the symbol index in the table when the
1144                                symbol table was written
1145                                */
1146                             *dst++ = p->value >> 8;
1147                             *dst++ = p->value;
1148                           }
1149                         }
1150 #define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
1151                     /* relocations never occur from an unloadable section,
1152                        so we can assume that raw_data is not NULL
1153                      */
1154                     *dst++ = *raw_data++;
1155                     ADVANCE
1156                     *dst++ = *raw_data++;
1157                     ADVANCE
1158                     if (how->size == 2) {
1159                       *dst++ = *raw_data++;
1160                       ADVANCE
1161                       *dst++ = *raw_data++;
1162                       ADVANCE
1163                     }
1164                     continue;
1165                   }
1166                 }
1167                 /* If this is coming from an unloadable section then copy
1168                    zeros */
1169                 if (raw_data == NULL) {
1170                   *dst++ = 0;
1171                 }
1172                 else {
1173                   *dst++ = *raw_data++;
1174                 }
1175                 ADVANCE
1176             }
1177
1178             /* Don't write a useless null modification byte */
1179             if (dst == mod+1) {
1180               --dst;
1181             }
1182
1183             oasys_write_record(abfd,
1184                                oasys_record_is_data_enum,
1185                                (oasys_record_union_type *)&processed_data,
1186                                dst - (bfd_byte *)&processed_data);
1187                          
1188           }
1189     }
1190   }
1191 }
1192 static boolean
1193 DEFUN(oasys_write_object_contents, (abfd),
1194       bfd *abfd)
1195 {
1196   oasys_write_header(abfd);
1197   oasys_write_syms(abfd);
1198   if (! oasys_write_sections(abfd))
1199     return false;
1200   oasys_write_data(abfd);
1201   oasys_write_end(abfd);
1202   return true;
1203 }
1204
1205
1206
1207
1208 /** exec and core file sections */
1209
1210 /* set section contents is complicated with OASYS since the format is 
1211 * not a byte image, but a record stream.
1212 */
1213 static boolean
1214 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1215       bfd *abfd AND
1216       sec_ptr section AND 
1217       PTR location AND
1218       file_ptr offset AND
1219       bfd_size_type count)
1220 {
1221   if (count != 0) {
1222     if (oasys_per_section(section)->data == (bfd_byte *)NULL ) 
1223         {
1224           oasys_per_section(section)->data =
1225             (bfd_byte *)(bfd_alloc(abfd,section->_cooked_size));    
1226           if (!   oasys_per_section(section)->data)
1227             {
1228               bfd_error = no_memory;
1229               return false;
1230             }
1231         }
1232     (void) memcpy((PTR)(oasys_per_section(section)->data + offset),
1233                   location,
1234                   count);
1235   }
1236   return true;
1237 }
1238
1239
1240
1241 /* Native-level interface to symbols. */
1242
1243 /* We read the symbols into a buffer, which is discarded when this
1244 function exits.  We read the strings into a buffer large enough to
1245 hold them all plus all the cached symbol entries. */
1246
1247 static asymbol *
1248 DEFUN(oasys_make_empty_symbol,(abfd),
1249       bfd *abfd)
1250 {
1251
1252   oasys_symbol_type  *new =
1253     (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1254   if (!new)
1255     {
1256       bfd_error = no_memory;
1257       return NULL;
1258     }
1259   new->symbol.the_bfd = abfd;
1260   return &new->symbol;
1261 }
1262
1263
1264 \f
1265
1266 /* User should have checked the file flags; perhaps we should return
1267 BFD_NO_MORE_SYMBOLS if there are none? */
1268
1269 static bfd *
1270 oasys_openr_next_archived_file(arch, prev)
1271 bfd *arch;
1272 bfd *prev;
1273 {
1274   oasys_ar_data_type *ar = OASYS_AR_DATA(arch);
1275   oasys_module_info_type *p;
1276   /* take the next one from the arch state, or reset */
1277   if (prev == (bfd *)NULL) {
1278     /* Reset the index - the first two entries are bogus*/
1279     ar->module_index = 0;
1280   }
1281
1282   p = ar->module + ar->module_index;
1283   ar->module_index++;
1284
1285   if (ar->module_index <= ar->module_count) {
1286     if (p->abfd == (bfd *)NULL) {
1287       p->abfd = _bfd_create_empty_archive_element_shell(arch);
1288       p->abfd->origin = p->pos;
1289       p->abfd->filename = p->name;
1290
1291       /* Fixup a pointer to this element for the member */
1292       p->abfd->arelt_data = (PTR)p;
1293     }
1294     return p->abfd;
1295   }
1296   else {
1297     bfd_error = no_more_archived_files;
1298     return (bfd *)NULL;
1299   }
1300 }
1301
1302 static boolean
1303 oasys_find_nearest_line(abfd,
1304                          section,
1305                          symbols,
1306                          offset,
1307                          filename_ptr,
1308                          functionname_ptr,
1309                          line_ptr)
1310 bfd *abfd;
1311 asection *section;
1312 asymbol **symbols;
1313 bfd_vma offset;
1314 char **filename_ptr;
1315 char **functionname_ptr;
1316 unsigned int *line_ptr;
1317 {
1318   return false;
1319
1320 }
1321
1322 static int
1323 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1324       bfd *abfd AND
1325       struct stat *buf)
1326 {
1327   oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1328   if (mod == (oasys_module_info_type *)NULL) {
1329     bfd_error = invalid_operation;
1330     return -1;
1331   }
1332   else {
1333     buf->st_size = mod->size;
1334     buf->st_mode = 0666;
1335     return 0;
1336   }
1337 }
1338
1339 static int 
1340 DEFUN(oasys_sizeof_headers,(abfd, exec),
1341       bfd *abfd AND
1342       boolean exec)
1343 {
1344 return 0;
1345 }
1346 #define FOO PROTO
1347 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1348 #define oasys_core_file_failing_signal (int (*)())bfd_0
1349 #define oasys_core_file_matches_executable_p  0 
1350 #define oasys_slurp_armap bfd_true
1351 #define oasys_slurp_extended_name_table bfd_true
1352 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1353 #define oasys_write_armap 0
1354 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1355 #define oasys_close_and_cleanup         bfd_generic_close_and_cleanup
1356 #define oasys_set_arch_mach bfd_default_set_arch_mach
1357 #define oasys_bfd_debug_info_start bfd_void
1358 #define oasys_bfd_debug_info_end bfd_void
1359 #define oasys_bfd_debug_info_accumulate  (FOO(void, (*), (bfd *, asection *)))bfd_void
1360 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1361 #define oasys_bfd_relax_section bfd_generic_relax_section
1362 #define oasys_bfd_reloc_type_lookup \
1363   ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
1364 #define oasys_bfd_make_debug_symbol \
1365   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
1366 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1367 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1368 #define oasys_bfd_final_link _bfd_generic_final_link
1369
1370 /*SUPPRESS 460 */
1371 bfd_target oasys_vec =
1372 {
1373   "oasys",                      /* name */
1374   bfd_target_oasys_flavour,
1375   true,                         /* target byte order */
1376   true,                         /* target headers byte order */
1377   (HAS_RELOC | EXEC_P |         /* object flags */
1378    HAS_LINENO | HAS_DEBUG |
1379    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1380   (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1381    |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1382    0,                           /* leading underscore */
1383   ' ',                          /* ar_pad_char */
1384   16,                           /* ar_max_namelen */
1385   1,                            /* minimum alignment */
1386   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1387     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1388     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1389   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1390     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1391     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1392
1393     {_bfd_dummy_target,
1394        oasys_object_p,          /* bfd_check_format */
1395        oasys_archive_p,
1396        _bfd_dummy_target,
1397      },
1398     {                           /* bfd_set_format */
1399       bfd_false,
1400       oasys_mkobject, 
1401       _bfd_generic_mkarchive,
1402       bfd_false
1403       },
1404     {                           /* bfd_write_contents */
1405       bfd_false,
1406       oasys_write_object_contents,
1407       _bfd_write_archive_contents,
1408       bfd_false,
1409     },
1410   JUMP_TABLE(oasys),
1411   (PTR) 0
1412 };
This page took 0.102636 seconds and 4 git commands to generate.