-Wimplicit-fallthrough warning fixes
[external/binutils.git] / bfd / oasys.c
1 /* BFD back-end for oasys objects.
2    Copyright (C) 1990-2016 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22 #define UNDERSCORE_HACK 1
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "safe-ctype.h"
26 #include "libbfd.h"
27 #include "oasys.h"
28 #include "liboasys.h"
29 #include "libiberty.h"
30
31 /* Read in all the section data and relocation stuff too.  */
32
33 static bfd_boolean
34 oasys_read_record (bfd *abfd, oasys_record_union_type *record)
35 {
36   bfd_size_type amt = sizeof (record->header);
37
38   if (bfd_bread ((void *) record, amt, abfd) != amt)
39     return FALSE;
40
41   amt = record->header.length - sizeof (record->header);
42   if ((long) amt <= 0)
43     return TRUE;
44   if (bfd_bread ((void *) ((char *) record + sizeof (record->header)), amt, abfd)
45       != amt)
46     return FALSE;
47   return TRUE;
48 }
49
50 static size_t
51 oasys_string_length (oasys_record_union_type *record)
52 {
53   return record->header.length
54     - ((char *) record->symbol.name - (char *) record);
55 }
56
57 /* Slurp the symbol table by reading in all the records at the start file
58    till we get to the first section record.
59
60    We'll sort the symbolss into  two lists, defined and undefined. The
61    undefined symbols will be placed into the table according to their
62    refno.
63
64    We do this by placing all undefined symbols at the front of the table
65    moving in, and the defined symbols at the end of the table moving back.  */
66
67 static bfd_boolean
68 oasys_slurp_symbol_table (bfd *const abfd)
69 {
70   oasys_record_union_type record;
71   oasys_data_type *data = OASYS_DATA (abfd);
72   bfd_boolean loop = TRUE;
73   asymbol *dest_defined;
74   asymbol *dest;
75   char *string_ptr;
76   bfd_size_type amt;
77
78   if (data->symbols != NULL)
79     return TRUE;
80
81   /* Buy enough memory for all the symbols and all the names.  */
82   amt = abfd->symcount;
83   amt *= sizeof (asymbol);
84   data->symbols = bfd_alloc (abfd, amt);
85
86   amt = data->symbol_string_length;
87 #ifdef UNDERSCORE_HACK
88   /* Buy 1 more char for each symbol to keep the underscore in.  */
89   amt += abfd->symcount;
90 #endif
91   data->strings = bfd_alloc (abfd, amt);
92
93   if (!data->symbols || !data->strings)
94     return FALSE;
95
96   dest_defined = data->symbols + abfd->symcount - 1;
97
98   string_ptr = data->strings;
99   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
100     return FALSE;
101   while (loop)
102     {
103       if (! oasys_read_record (abfd, &record))
104         return FALSE;
105
106       switch (record.header.type)
107         {
108         case oasys_record_is_header_enum:
109           break;
110         case oasys_record_is_local_enum:
111         case oasys_record_is_symbol_enum:
112           {
113             int flag = record.header.type == (int) oasys_record_is_local_enum ?
114             (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
115
116             size_t length = oasys_string_length (&record);
117             switch (record.symbol.relb & RELOCATION_TYPE_BITS)
118               {
119               case RELOCATION_TYPE_ABS:
120                 dest = dest_defined--;
121                 dest->section = bfd_abs_section_ptr;
122                 dest->flags = 0;
123
124                 break;
125               case RELOCATION_TYPE_REL:
126                 dest = dest_defined--;
127                 dest->section =
128                   OASYS_DATA (abfd)->sections[record.symbol.relb &
129                                               RELOCATION_SECT_BITS];
130                 if (record.header.type == (int) oasys_record_is_local_enum)
131                   {
132                     dest->flags = BSF_LOCAL;
133                     if (dest->section == (asection *) (~0))
134                       {
135                         /* It seems that sometimes internal symbols are tied up, but
136                        still get output, even though there is no
137                        section */
138                         dest->section = 0;
139                       }
140                   }
141                 else
142                   dest->flags = flag;
143                 break;
144               case RELOCATION_TYPE_UND:
145                 dest = data->symbols + H_GET_16 (abfd, record.symbol.refno);
146                 dest->section = bfd_und_section_ptr;
147                 break;
148               case RELOCATION_TYPE_COM:
149                 dest = dest_defined--;
150                 dest->name = string_ptr;
151                 dest->the_bfd = abfd;
152                 dest->section = bfd_com_section_ptr;
153                 break;
154               default:
155                 dest = dest_defined--;
156                 BFD_ASSERT (FALSE);
157                 break;
158               }
159             dest->name = string_ptr;
160             dest->the_bfd = abfd;
161             dest->udata.p = NULL;
162             dest->value = H_GET_32 (abfd, record.symbol.value);
163
164 #ifdef UNDERSCORE_HACK
165             if (record.symbol.name[0] != '_')
166               {
167                 string_ptr[0] = '_';
168                 string_ptr++;
169               }
170 #endif
171             memcpy (string_ptr, record.symbol.name, length);
172
173             string_ptr[length] = 0;
174             string_ptr += length + 1;
175           }
176           break;
177         default:
178           loop = FALSE;
179         }
180     }
181   return TRUE;
182 }
183
184 static long
185 oasys_get_symtab_upper_bound (bfd *const abfd)
186 {
187   if (! oasys_slurp_symbol_table (abfd))
188     return -1;
189
190   return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
191 }
192
193 extern const bfd_target oasys_vec;
194
195 static long
196 oasys_canonicalize_symtab (bfd *abfd, asymbol **location)
197 {
198   asymbol *symbase;
199   unsigned int counter;
200
201   if (! oasys_slurp_symbol_table (abfd))
202     return -1;
203
204   symbase = OASYS_DATA (abfd)->symbols;
205   for (counter = 0; counter < abfd->symcount; counter++)
206     *(location++) = symbase++;
207
208   *location = 0;
209   return abfd->symcount;
210 }
211
212 /* Archive stuff.  */
213
214 static const bfd_target *
215 oasys_archive_p (bfd *abfd)
216 {
217   oasys_archive_header_type header;
218   oasys_extarchive_header_type header_ext;
219   unsigned int i;
220   file_ptr filepos;
221   bfd_size_type amt;
222
223   amt = sizeof (header_ext);
224   if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
225       || bfd_bread ((void *) &header_ext, amt, abfd) != amt)
226     {
227       if (bfd_get_error () != bfd_error_system_call)
228         bfd_set_error (bfd_error_wrong_format);
229       return NULL;
230     }
231
232   header.version = H_GET_32 (abfd, header_ext.version);
233   header.mod_count = H_GET_32 (abfd, header_ext.mod_count);
234   header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset);
235   header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size);
236   header.sym_count = H_GET_32 (abfd, header_ext.sym_count);
237   header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset);
238   header.xref_count = H_GET_32 (abfd, header_ext.xref_count);
239   header.xref_lst_offset = H_GET_32 (abfd, header_ext.xref_lst_offset);
240
241   /* There isn't a magic number in an Oasys archive, so the best we
242      can do to verify reasonableness is to make sure that the values in
243      the header are too weird.  */
244
245   if (header.version > 10000
246       || header.mod_count > 10000
247       || header.sym_count > 100000
248       || header.xref_count > 100000)
249     return NULL;
250
251   /* That all worked, let's buy the space for the header and read in
252      the headers.  */
253   {
254     oasys_ar_data_type *ar;
255     oasys_module_info_type *module;
256     oasys_module_table_type record;
257
258     amt = sizeof (oasys_ar_data_type);
259     ar = bfd_alloc (abfd, amt);
260
261     amt = header.mod_count;
262     amt *= sizeof (oasys_module_info_type);
263     module = bfd_alloc (abfd, amt);
264
265     if (!ar || !module)
266       return NULL;
267
268     abfd->tdata.oasys_ar_data = ar;
269     ar->module = module;
270     ar->module_count = header.mod_count;
271
272     filepos = header.mod_tbl_offset;
273     for (i = 0; i < header.mod_count; i++)
274       {
275         oasys_extmodule_table_type_b_type record_ext;
276
277         if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
278           return NULL;
279
280         /* There are two ways of specifying the archive header.  */
281         amt = sizeof (record_ext);
282         if (bfd_bread ((void *) &record_ext, amt, abfd) != amt)
283           return NULL;
284
285         record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
286         record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
287
288         record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
289         record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
290         record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
291         record.module_name_size = H_GET_32 (abfd,
292                                             record_ext.mod_name_length);
293
294         amt = record.module_name_size;
295         module[i].name = bfd_alloc (abfd, amt + 1);
296         if (!module[i].name)
297           return NULL;
298         if (bfd_bread ((void *) module[i].name, amt, abfd) != amt)
299           return NULL;
300         module[i].name[record.module_name_size] = 0;
301         filepos += (sizeof (record_ext)
302                     + record.dep_count * 4
303                     + record.module_name_size + 1);
304
305         module[i].size = record.mod_size;
306         module[i].pos = record.file_offset;
307         module[i].abfd = 0;
308       }
309   }
310   return abfd->xvec;
311 }
312
313 static bfd_boolean
314 oasys_mkobject (bfd *abfd)
315 {
316   bfd_size_type amt = sizeof (oasys_data_type);
317
318   abfd->tdata.oasys_obj_data = bfd_alloc (abfd, amt);
319
320   return abfd->tdata.oasys_obj_data != NULL;
321 }
322
323 /* The howto table is build using the top two bits of a reloc byte to
324    index into it. The bits are PCREL,WORD/LONG.  */
325
326 static reloc_howto_type howto_table[] =
327 {
328
329   HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16",   TRUE, 0x0000ffff, 0x0000ffff, FALSE),
330   HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32",   TRUE, 0xffffffff, 0xffffffff, FALSE),
331   HOWTO (0, 0, 1, 16, TRUE,  0, complain_overflow_signed,   0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
332   HOWTO (0, 0, 2, 32, TRUE,  0, complain_overflow_signed,   0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE)
333 };
334
335 /* Read in all the section data and relocation stuff too.  */
336
337 static bfd_boolean
338 oasys_slurp_section_data (bfd *const abfd)
339 {
340   oasys_record_union_type record;
341   oasys_data_type *data = OASYS_DATA (abfd);
342   bfd_boolean loop = TRUE;
343   oasys_per_section_type *per;
344   asection *s;
345   bfd_size_type amt;
346
347   /* See if the data has been slurped already.  */
348   for (s = abfd->sections; s != NULL; s = s->next)
349     {
350       per = oasys_per_section (s);
351       if (per->initialized)
352         return TRUE;
353     }
354
355   if (data->first_data_record == 0)
356     return TRUE;
357
358   if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
359     return FALSE;
360
361   while (loop)
362     {
363       if (! oasys_read_record (abfd, &record))
364         return FALSE;
365
366       switch (record.header.type)
367         {
368         case oasys_record_is_header_enum:
369           break;
370         case oasys_record_is_data_enum:
371           {
372             bfd_byte *src = record.data.data;
373             bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
374             bfd_byte *dst_ptr;
375             bfd_byte *dst_base_ptr;
376             unsigned int relbit;
377             unsigned int count;
378             asection *section =
379             data->sections[record.data.relb & RELOCATION_SECT_BITS];
380             bfd_vma dst_offset;
381
382             per = oasys_per_section (section);
383
384             if (! per->initialized)
385               {
386                 arelent **relpp;
387
388                 per->data = bfd_zalloc (abfd, section->size);
389                 if (!per->data)
390                   return FALSE;
391                 relpp = &section->relocation;
392                 per->reloc_tail_ptr = (oasys_reloc_type **) relpp;
393                 per->had_vma = FALSE;
394                 per->initialized = TRUE;
395                 section->reloc_count = 0;
396                 section->flags = SEC_ALLOC;
397               }
398
399             dst_offset = H_GET_32 (abfd, record.data.addr);
400             if (! per->had_vma)
401               {
402                 /* Take the first vma we see as the base.  */
403                 section->vma = dst_offset;
404                 per->had_vma = TRUE;
405               }
406
407             dst_offset -= section->vma;
408
409             dst_base_ptr = oasys_per_section (section)->data;
410             dst_ptr = oasys_per_section (section)->data +
411               dst_offset;
412
413             if (src < end_src)
414               section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
415
416             while (src < end_src)
417               {
418                 unsigned char mod_byte = *src++;
419                 size_t gap = end_src - src;
420
421                 count = 8;
422                 if (mod_byte == 0 && gap >= 8)
423                   {
424                     dst_ptr[0] = src[0];
425                     dst_ptr[1] = src[1];
426                     dst_ptr[2] = src[2];
427                     dst_ptr[3] = src[3];
428                     dst_ptr[4] = src[4];
429                     dst_ptr[5] = src[5];
430                     dst_ptr[6] = src[6];
431                     dst_ptr[7] = src[7];
432                     dst_ptr += 8;
433                     src += 8;
434                   }
435                 else
436                   {
437                     for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
438                       {
439                         if (relbit & mod_byte)
440                           {
441                             unsigned char reloc = *src;
442                             /* This item needs to be relocated.  */
443                             switch (reloc & RELOCATION_TYPE_BITS)
444                               {
445                               case RELOCATION_TYPE_ABS:
446                                 break;
447
448                               case RELOCATION_TYPE_REL:
449                                 {
450                                   /* Relocate the item relative to the section.  */
451                                   oasys_reloc_type *r;
452
453                                   amt = sizeof (oasys_reloc_type);
454                                   r = bfd_alloc (abfd, amt);
455                                   if (!r)
456                                     return FALSE;
457                                   *(per->reloc_tail_ptr) = r;
458                                   per->reloc_tail_ptr = &r->next;
459                                   r->next = NULL;
460                                   /* Reference to undefined symbol.  */
461                                   src++;
462                                   /* There is no symbol.  */
463                                   r->symbol = 0;
464                                   /* Work out the howto.  */
465                                   abort ();
466                                   r->relent.address = dst_ptr - dst_base_ptr;
467                                   r->relent.howto = &howto_table[reloc >> 6];
468                                   r->relent.sym_ptr_ptr = NULL;
469                                   section->reloc_count++;
470
471                                   /* Fake up the data to look like
472                                      it's got the -ve pc in it, this
473                                      makes it much easier to convert
474                                      into other formats.  This is done
475                                      by hitting the addend.  */
476                                   if (r->relent.howto->pc_relative)
477                                     r->relent.addend -= dst_ptr - dst_base_ptr;
478                                 }
479                                 break;
480
481                               case RELOCATION_TYPE_UND:
482                                 {
483                                   oasys_reloc_type *r;
484
485                                   amt = sizeof (oasys_reloc_type);
486                                   r = bfd_alloc (abfd, amt);
487                                   if (!r)
488                                     return FALSE;
489                                   *(per->reloc_tail_ptr) = r;
490                                   per->reloc_tail_ptr = &r->next;
491                                   r->next = NULL;
492                                   /* Reference to undefined symbol.  */
493                                   src++;
494                                   /* Get symbol number.  */
495                                   r->symbol = (src[0] << 8) | src[1];
496                                   /* Work out the howto.  */
497                                   abort ();
498
499                                   r->relent.addend = 0;
500                                   r->relent.address = dst_ptr - dst_base_ptr;
501                                   r->relent.howto = &howto_table[reloc >> 6];
502                                   r->relent.sym_ptr_ptr = NULL;
503                                   section->reloc_count++;
504
505                                   src += 2;
506                                   /* Fake up the data to look like
507                                      it's got the -ve pc in it, this
508                                      makes it much easier to convert
509                                      into other formats.  This is done
510                                      by hitting the addend.  */
511                                   if (r->relent.howto->pc_relative)
512                                     r->relent.addend -= dst_ptr - dst_base_ptr;
513                                 }
514                                 break;
515                               case RELOCATION_TYPE_COM:
516                                 BFD_FAIL ();
517                               }
518                           }
519                         *dst_ptr++ = *src++;
520                       }
521                   }
522               }
523           }
524           break;
525         case oasys_record_is_local_enum:
526         case oasys_record_is_symbol_enum:
527         case oasys_record_is_section_enum:
528           break;
529         default:
530           loop = FALSE;
531         }
532     }
533
534   return TRUE;
535
536 }
537
538 #define MAX_SECS 16
539
540 static const bfd_target *
541 oasys_object_p (bfd *abfd)
542 {
543   oasys_data_type *oasys;
544   oasys_data_type *save = OASYS_DATA (abfd);
545   bfd_boolean loop = TRUE;
546   bfd_boolean had_usefull = FALSE;
547
548   abfd->tdata.oasys_obj_data = 0;
549   oasys_mkobject (abfd);
550   oasys = OASYS_DATA (abfd);
551   memset ((void *) oasys->sections, 0xff, sizeof (oasys->sections));
552
553   /* Point to the start of the file.  */
554   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
555     goto fail;
556   oasys->symbol_string_length = 0;
557
558   /* Inspect the records, but only keep the section info -
559      remember the size of the symbols.  */
560   oasys->first_data_record = 0;
561   while (loop)
562     {
563       oasys_record_union_type record;
564       if (! oasys_read_record (abfd, &record))
565         goto fail;
566       if ((size_t) record.header.length < (size_t) sizeof (record.header))
567         goto fail;
568
569       switch ((oasys_record_enum_type) (record.header.type))
570         {
571         case oasys_record_is_header_enum:
572           had_usefull = TRUE;
573           break;
574         case oasys_record_is_symbol_enum:
575         case oasys_record_is_local_enum:
576           /* Count symbols and remember their size for a future malloc.  */
577           abfd->symcount++;
578           oasys->symbol_string_length += 1 + oasys_string_length (&record);
579           had_usefull = TRUE;
580           break;
581         case oasys_record_is_section_enum:
582           {
583             asection *s;
584             char *buffer;
585             unsigned int section_number;
586
587             if (record.section.header.length != sizeof (record.section))
588               goto fail;
589
590             buffer = bfd_alloc (abfd, (bfd_size_type) 3);
591             if (!buffer)
592               goto fail;
593             section_number = record.section.relb & RELOCATION_SECT_BITS;
594             sprintf (buffer, "%u", section_number);
595             s = bfd_make_section (abfd, buffer);
596             oasys->sections[section_number] = s;
597             switch (record.section.relb & RELOCATION_TYPE_BITS)
598               {
599               case RELOCATION_TYPE_ABS:
600               case RELOCATION_TYPE_REL:
601                 break;
602               case RELOCATION_TYPE_UND:
603               case RELOCATION_TYPE_COM:
604                 BFD_FAIL ();
605               }
606
607             s->size = H_GET_32 (abfd, record.section.value);
608             s->vma = H_GET_32 (abfd, record.section.vma);
609             s->flags = 0;
610             had_usefull = TRUE;
611           }
612           break;
613         case oasys_record_is_data_enum:
614           oasys->first_data_record = bfd_tell (abfd) - record.header.length;
615           /* Fall through.  */
616         case oasys_record_is_debug_enum:
617         case oasys_record_is_module_enum:
618         case oasys_record_is_named_section_enum:
619         case oasys_record_is_end_enum:
620           if (! had_usefull)
621             goto fail;
622           loop = FALSE;
623           break;
624         default:
625           goto fail;
626         }
627     }
628   oasys->symbols = NULL;
629
630   /* Oasys support several architectures, but I can't see a simple way
631      to discover which one is in a particular file - we'll guess.  */
632   bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
633   if (abfd->symcount != 0)
634     abfd->flags |= HAS_SYMS;
635
636   /* We don't know if a section has data until we've read it.  */
637   oasys_slurp_section_data (abfd);
638
639   return abfd->xvec;
640
641 fail:
642   (void) bfd_release (abfd, oasys);
643   abfd->tdata.oasys_obj_data = save;
644   return NULL;
645 }
646
647
648 static void
649 oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
650                        asymbol *symbol,
651                        symbol_info *ret)
652 {
653   bfd_symbol_info (symbol, ret);
654
655   if (!symbol->section)
656     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
657 }
658
659 static void
660 oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how)
661 {
662   FILE *file = (FILE *) afile;
663
664   switch (how)
665     {
666     case bfd_print_symbol_name:
667     case bfd_print_symbol_more:
668       fprintf (file, "%s", symbol->name);
669       break;
670     case bfd_print_symbol_all:
671       {
672         const char *section_name = symbol->section == NULL ?
673         (const char *) "*abs" : symbol->section->name;
674
675         bfd_print_symbol_vandf (abfd, (void *) file, symbol);
676
677         fprintf (file, " %-5s %s",
678                  section_name,
679                  symbol->name);
680       }
681       break;
682     }
683 }
684
685 static bfd_boolean
686 oasys_new_section_hook (bfd *abfd, asection *newsect)
687 {
688   if (!newsect->used_by_bfd)
689     {
690       newsect->used_by_bfd
691         = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
692       if (!newsect->used_by_bfd)
693         return FALSE;
694     }
695   oasys_per_section (newsect)->data = NULL;
696   oasys_per_section (newsect)->section = newsect;
697   oasys_per_section (newsect)->offset = 0;
698   oasys_per_section (newsect)->initialized = FALSE;
699   newsect->alignment_power = 1;
700
701   /* Turn the section string into an index.  */
702   sscanf (newsect->name, "%u", &newsect->target_index);
703
704   return _bfd_generic_new_section_hook (abfd, newsect);
705 }
706
707
708 static long
709 oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
710 {
711   if (! oasys_slurp_section_data (abfd))
712     return -1;
713   return (asect->reloc_count + 1) * sizeof (arelent *);
714 }
715
716 static bfd_boolean
717 oasys_get_section_contents (bfd *abfd,
718                             sec_ptr section,
719                             void * location,
720                             file_ptr offset,
721                             bfd_size_type count)
722 {
723   oasys_per_section_type *p = oasys_per_section (section);
724
725   oasys_slurp_section_data (abfd);
726
727   if (! p->initialized)
728     (void) memset (location, 0, (size_t) count);
729   else
730     (void) memcpy (location, (void *) (p->data + offset), (size_t) count);
731
732   return TRUE;
733 }
734
735 static long
736 oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
737                           sec_ptr section,
738                           arelent **relptr,
739                           asymbol **symbols ATTRIBUTE_UNUSED)
740 {
741   unsigned int reloc_count = 0;
742   oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
743
744   if (src != NULL)
745     abort ();
746
747   *relptr = NULL;
748   return section->reloc_count = reloc_count;
749 }
750
751
752 /* Writing.  */
753
754 /* Calculate the checksum and write one record.  */
755
756 static bfd_boolean
757 oasys_write_record (bfd *abfd,
758                     oasys_record_enum_type type,
759                     oasys_record_union_type *record,
760                     size_t size)
761 {
762   int checksum;
763   size_t i;
764   unsigned char *ptr;
765
766   record->header.length = size;
767   record->header.type = (int) type;
768   record->header.check_sum = 0;
769   record->header.fill = 0;
770   ptr = (unsigned char *) &record->pad[0];
771   checksum = 0;
772   for (i = 0; i < size; i++)
773     checksum += *ptr++;
774   record->header.check_sum = 0xff & (-checksum);
775   if (bfd_bwrite ((void *) record, (bfd_size_type) size, abfd) != size)
776     return FALSE;
777   return TRUE;
778 }
779
780
781 /* Write out all the symbols.  */
782
783 static bfd_boolean
784 oasys_write_syms (bfd *abfd)
785 {
786   unsigned int count;
787   asymbol **generic = bfd_get_outsymbols (abfd);
788   unsigned int sym_index = 0;
789
790   for (count = 0; count < bfd_get_symcount (abfd); count++)
791     {
792       oasys_symbol_record_type symbol;
793       asymbol *const g = generic[count];
794       const char *src = g->name;
795       char *dst = symbol.name;
796       unsigned int l = 0;
797
798       if (bfd_is_com_section (g->section))
799         {
800           symbol.relb = RELOCATION_TYPE_COM;
801           H_PUT_16 (abfd, sym_index, symbol.refno);
802           sym_index++;
803         }
804       else if (bfd_is_abs_section (g->section))
805         {
806           symbol.relb = RELOCATION_TYPE_ABS;
807           H_PUT_16 (abfd, 0, symbol.refno);
808         }
809       else if (bfd_is_und_section (g->section))
810         {
811           symbol.relb = RELOCATION_TYPE_UND;
812           H_PUT_16 (abfd, sym_index, symbol.refno);
813           /* Overload the value field with the output sym_index number */
814           sym_index++;
815         }
816       else if (g->flags & BSF_DEBUGGING)
817         /* Throw it away.  */
818         continue;
819       else
820         {
821           if (g->section == NULL)
822             /* Sometime, the oasys tools give out a symbol with illegal
823                bits in it, we'll output it in the same broken way.  */
824             symbol.relb = RELOCATION_TYPE_REL | 0;
825           else
826             symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
827
828           H_PUT_16 (abfd, 0, symbol.refno);
829         }
830
831 #ifdef UNDERSCORE_HACK
832       if (src[l] == '_')
833         dst[l++] = '.';
834 #endif
835       while (src[l])
836         {
837           dst[l] = src[l];
838           l++;
839         }
840
841       H_PUT_32 (abfd, g->value, symbol.value);
842
843       if (g->flags & BSF_LOCAL)
844         {
845           if (! oasys_write_record (abfd,
846                                     oasys_record_is_local_enum,
847                                     (oasys_record_union_type *) & symbol,
848                                     offsetof (oasys_symbol_record_type,
849                                               name[0]) + l))
850             return FALSE;
851         }
852       else
853         {
854           if (! oasys_write_record (abfd,
855                                     oasys_record_is_symbol_enum,
856                                     (oasys_record_union_type *) & symbol,
857                                     offsetof (oasys_symbol_record_type,
858                                               name[0]) + l))
859             return FALSE;
860         }
861       g->value = sym_index - 1;
862     }
863
864   return TRUE;
865 }
866
867 /* Write a section header for each section.  */
868
869 static bfd_boolean
870 oasys_write_sections (bfd *abfd)
871 {
872   asection *s;
873   static oasys_section_record_type out;
874
875   for (s = abfd->sections; s != NULL; s = s->next)
876     {
877       if (!ISDIGIT (s->name[0]))
878         {
879           _bfd_error_handler
880             (_("%s: can not represent section `%s' in oasys"),
881              bfd_get_filename (abfd), s->name);
882           bfd_set_error (bfd_error_nonrepresentable_section);
883           return FALSE;
884         }
885       out.relb = RELOCATION_TYPE_REL | s->target_index;
886       H_PUT_32 (abfd, s->size, out.value);
887       H_PUT_32 (abfd, s->vma, out.vma);
888
889       if (! oasys_write_record (abfd,
890                                 oasys_record_is_section_enum,
891                                 (oasys_record_union_type *) & out,
892                                 sizeof (out)))
893         return FALSE;
894     }
895   return TRUE;
896 }
897
898 static bfd_boolean
899 oasys_write_header (bfd *abfd)
900 {
901   /* Create and write the header.  */
902   oasys_header_record_type r;
903   size_t length = strlen (abfd->filename);
904
905   if (length > (size_t) sizeof (r.module_name))
906     length = sizeof (r.module_name);
907   else if (length < (size_t) sizeof (r.module_name))
908     (void) memset (r.module_name + length, ' ',
909                    sizeof (r.module_name) - length);
910
911   (void) memcpy (r.module_name, abfd->filename, length);
912
913   r.version_number = OASYS_VERSION_NUMBER;
914   r.rev_number = OASYS_REV_NUMBER;
915
916   return oasys_write_record (abfd, oasys_record_is_header_enum,
917                              (oasys_record_union_type *) & r,
918                              offsetof (oasys_header_record_type,
919                                        description[0]));
920 }
921
922 static bfd_boolean
923 oasys_write_end (bfd *abfd)
924 {
925   oasys_end_record_type end;
926   unsigned char null = 0;
927
928   end.relb = RELOCATION_TYPE_ABS;
929   H_PUT_32 (abfd, abfd->start_address, end.entry);
930   H_PUT_16 (abfd, 0, end.fill);
931   end.zero = 0;
932   if (! oasys_write_record (abfd,
933                             oasys_record_is_end_enum,
934                             (oasys_record_union_type *) & end,
935                             sizeof (end)))
936     return FALSE;
937
938   return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1;
939 }
940
941 static int
942 comp (const void * ap, const void * bp)
943 {
944   arelent *a = *((arelent **) ap);
945   arelent *b = *((arelent **) bp);
946
947   return a->address - b->address;
948 }
949
950 static bfd_boolean
951 oasys_write_data (bfd *abfd)
952 {
953   asection *s;
954
955   for (s = abfd->sections; s != NULL; s = s->next)
956     {
957       if (s->flags & SEC_LOAD)
958         {
959           bfd_byte *raw_data = oasys_per_section (s)->data;
960           oasys_data_record_type processed_data;
961           bfd_size_type current_byte_index = 0;
962           unsigned int relocs_to_go = s->reloc_count;
963           arelent **p = s->orelocation;
964
965           if (s->reloc_count != 0)
966             /* Sort the reloc records so it's easy to insert the relocs into the
967                data.  */
968             qsort (s->orelocation, s->reloc_count, sizeof (arelent **), comp);
969
970           current_byte_index = 0;
971           processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
972
973           while (current_byte_index < s->size)
974             {
975               /* Scan forwards by eight bytes or however much is left and see if
976                there are any relocations going on.  */
977               bfd_byte *mod = &processed_data.data[0];
978               bfd_byte *dst = &processed_data.data[1];
979
980               unsigned int i = 0;
981               *mod = 0;
982
983               H_PUT_32 (abfd, s->vma + current_byte_index,
984                         processed_data.addr);
985
986               /* Don't start a relocation unless you're sure you can finish it
987                  within the same data record.  The worst case relocation is a
988                  4-byte relocatable value which is split across two modification
989                  bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
990                  1 modification byte + 2 data = 8 bytes total).  That's where
991                  the magic number 8 comes from.  */
992               while (current_byte_index < s->size && dst <=
993                      & processed_data.data[sizeof (processed_data.data) - 8])
994                 {
995                   if (relocs_to_go != 0)
996                     {
997                       arelent *r = *p;
998
999                       /* There is a relocation, is it for this byte ?  */
1000                       if (r->address == current_byte_index)
1001                         abort ();
1002                     }
1003
1004                   /* If this is coming from an unloadable section then copy
1005                      zeros.  */
1006                   if (raw_data == NULL)
1007                     *dst++ = 0;
1008                   else
1009                     *dst++ = *raw_data++;
1010
1011                   if (++i >= 8)
1012                     {
1013                       i = 0;
1014                       mod = dst++;
1015                       *mod = 0;
1016                     }
1017                   current_byte_index++;
1018                 }
1019
1020               /* Don't write a useless null modification byte.  */
1021               if (dst == mod + 1)
1022                 --dst;
1023
1024               if (! (oasys_write_record
1025                      (abfd, oasys_record_is_data_enum,
1026                       ((oasys_record_union_type *) &processed_data),
1027                       (size_t) (dst - (bfd_byte *) &processed_data))))
1028                 return FALSE;
1029             }
1030         }
1031     }
1032
1033   return TRUE;
1034 }
1035
1036 static bfd_boolean
1037 oasys_write_object_contents (bfd *abfd)
1038 {
1039   if (! oasys_write_header (abfd))
1040     return FALSE;
1041   if (! oasys_write_syms (abfd))
1042     return FALSE;
1043   if (! oasys_write_sections (abfd))
1044     return FALSE;
1045   if (! oasys_write_data (abfd))
1046     return FALSE;
1047   if (! oasys_write_end (abfd))
1048     return FALSE;
1049   return TRUE;
1050 }
1051
1052 /* Set section contents is complicated with OASYS since the format is
1053    not a byte image, but a record stream.  */
1054
1055 static bfd_boolean
1056 oasys_set_section_contents (bfd *abfd,
1057                             sec_ptr section,
1058                             const void * location,
1059                             file_ptr offset,
1060                             bfd_size_type count)
1061 {
1062   if (count != 0)
1063     {
1064       if (oasys_per_section (section)->data == NULL)
1065         {
1066           oasys_per_section (section)->data = bfd_alloc (abfd, section->size);
1067           if (!oasys_per_section (section)->data)
1068             return FALSE;
1069         }
1070       (void) memcpy ((void *) (oasys_per_section (section)->data + offset),
1071                      location, (size_t) count);
1072     }
1073   return TRUE;
1074 }
1075
1076
1077
1078 /* Native-level interface to symbols.  */
1079
1080 /* We read the symbols into a buffer, which is discarded when this
1081    function exits.  We read the strings into a buffer large enough to
1082    hold them all plus all the cached symbol entries.  */
1083
1084 static asymbol *
1085 oasys_make_empty_symbol (bfd *abfd)
1086 {
1087   bfd_size_type amt = sizeof (oasys_symbol_type);
1088   oasys_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
1089
1090   if (!new_symbol_type)
1091     return NULL;
1092   new_symbol_type->symbol.the_bfd = abfd;
1093   return &new_symbol_type->symbol;
1094 }
1095
1096 /* User should have checked the file flags; perhaps we should return
1097    BFD_NO_MORE_SYMBOLS if there are none?  */
1098
1099 static bfd *
1100 oasys_openr_next_archived_file (bfd *arch, bfd *prev)
1101 {
1102   oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
1103   oasys_module_info_type *p;
1104
1105   /* Take the next one from the arch state, or reset.  */
1106   if (prev == NULL)
1107     /* Reset the index - the first two entries are bogus.  */
1108     ar->module_index = 0;
1109
1110   p = ar->module + ar->module_index;
1111   ar->module_index++;
1112
1113   if (ar->module_index <= ar->module_count)
1114     {
1115       if (p->abfd == NULL)
1116         {
1117           p->abfd = _bfd_create_empty_archive_element_shell (arch);
1118           p->abfd->origin = p->pos;
1119           p->abfd->filename = xstrdup (p->name);
1120
1121           /* Fixup a pointer to this element for the member.  */
1122           p->abfd->arelt_data = (void *) p;
1123         }
1124       return p->abfd;
1125     }
1126
1127   bfd_set_error (bfd_error_no_more_archived_files);
1128   return NULL;
1129 }
1130
1131 #define oasys_find_nearest_line _bfd_nosymbols_find_nearest_line
1132 #define oasys_find_line         _bfd_nosymbols_find_line
1133 #define oasys_find_inliner_info _bfd_nosymbols_find_inliner_info
1134
1135 static int
1136 oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
1137 {
1138   oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1139
1140   if (mod == NULL)
1141     {
1142       bfd_set_error (bfd_error_invalid_operation);
1143       return -1;
1144     }
1145
1146   buf->st_size = mod->size;
1147   buf->st_mode = 0666;
1148   return 0;
1149 }
1150
1151 static int
1152 oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
1153                       struct bfd_link_info *info ATTRIBUTE_UNUSED)
1154 {
1155   return 0;
1156 }
1157
1158 #define oasys_close_and_cleanup                    _bfd_generic_close_and_cleanup
1159 #define oasys_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
1160 #define oasys_slurp_armap                          bfd_true
1161 #define oasys_slurp_extended_name_table            bfd_true
1162 #define oasys_construct_extended_name_table        ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true)
1163 #define oasys_truncate_arname                      bfd_dont_truncate_arname
1164 #define oasys_write_armap                          ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true)
1165 #define oasys_read_ar_hdr                          bfd_nullvoidptr
1166 #define oasys_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
1167 #define oasys_get_elt_at_index                     _bfd_generic_get_elt_at_index
1168 #define oasys_update_armap_timestamp               bfd_true
1169 #define oasys_bfd_is_local_label_name              bfd_generic_is_local_label_name
1170 #define oasys_bfd_is_target_special_symbol         ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1171 #define oasys_get_lineno                           _bfd_nosymbols_get_lineno
1172 #define oasys_get_symbol_version_string            _bfd_nosymbols_get_symbol_version_string
1173 #define oasys_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
1174 #define oasys_read_minisymbols                     _bfd_generic_read_minisymbols
1175 #define oasys_minisymbol_to_symbol                 _bfd_generic_minisymbol_to_symbol
1176 #define oasys_bfd_reloc_type_lookup                _bfd_norelocs_bfd_reloc_type_lookup
1177 #define oasys_bfd_reloc_name_lookup          _bfd_norelocs_bfd_reloc_name_lookup
1178 #define oasys_set_arch_mach                        bfd_default_set_arch_mach
1179 #define oasys_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
1180 #define oasys_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
1181 #define oasys_bfd_relax_section                    bfd_generic_relax_section
1182 #define oasys_bfd_gc_sections                      bfd_generic_gc_sections
1183 #define oasys_bfd_lookup_section_flags             bfd_generic_lookup_section_flags
1184 #define oasys_bfd_merge_sections                   bfd_generic_merge_sections
1185 #define oasys_bfd_is_group_section                 bfd_generic_is_group_section
1186 #define oasys_bfd_discard_group                    bfd_generic_discard_group
1187 #define oasys_section_already_linked               _bfd_generic_section_already_linked
1188 #define oasys_bfd_define_common_symbol             bfd_generic_define_common_symbol
1189 #define oasys_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
1190 #define oasys_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
1191 #define oasys_bfd_link_just_syms                   _bfd_generic_link_just_syms
1192 #define oasys_bfd_copy_link_hash_symbol_type \
1193   _bfd_generic_copy_link_hash_symbol_type
1194 #define oasys_bfd_final_link                       _bfd_generic_final_link
1195 #define oasys_bfd_link_split_section               _bfd_generic_link_split_section
1196 #define oasys_bfd_link_check_relocs                _bfd_generic_link_check_relocs
1197
1198 const bfd_target oasys_vec =
1199 {
1200   "oasys",                      /* Name.  */
1201   bfd_target_oasys_flavour,
1202   BFD_ENDIAN_BIG,               /* Target byte order.  */
1203   BFD_ENDIAN_BIG,               /* Target headers byte order.  */
1204   (HAS_RELOC | EXEC_P |         /* Object flags.  */
1205    HAS_LINENO | HAS_DEBUG |
1206    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1207   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1208    | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags.  */
1209   0,                            /* Leading underscore.  */
1210   ' ',                          /* AR_pad_char.  */
1211   16,                           /* AR_max_namelen.  */
1212   0,                            /* match priority.  */
1213   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1214   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1215   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Data.  */
1216   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1217   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1218   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Headers.  */
1219
1220   {_bfd_dummy_target,
1221    oasys_object_p,              /* bfd_check_format.  */
1222    oasys_archive_p,
1223    _bfd_dummy_target,
1224   },
1225   {                             /* bfd_set_format.  */
1226     bfd_false,
1227     oasys_mkobject,
1228     _bfd_generic_mkarchive,
1229     bfd_false
1230   },
1231   {                             /* bfd_write_contents.  */
1232     bfd_false,
1233     oasys_write_object_contents,
1234     _bfd_write_archive_contents,
1235     bfd_false,
1236   },
1237
1238   BFD_JUMP_TABLE_GENERIC (oasys),
1239   BFD_JUMP_TABLE_COPY (_bfd_generic),
1240   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1241   BFD_JUMP_TABLE_ARCHIVE (oasys),
1242   BFD_JUMP_TABLE_SYMBOLS (oasys),
1243   BFD_JUMP_TABLE_RELOCS (oasys),
1244   BFD_JUMP_TABLE_WRITE (oasys),
1245   BFD_JUMP_TABLE_LINK (oasys),
1246   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1247
1248   NULL,
1249
1250   NULL
1251 };