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