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