* bfd/elf32-sh.c (sh_elf_size_dynamic_sections): Zero initialize
[external/binutils.git] / bfd / elf32-frv.c
1 /* FRV-specific support for 32-bit ELF.
2    Copyright (C) 2002 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24 #include "elf/frv.h"
25
26 /* Forward declarations.  */
27 static bfd_reloc_status_type elf32_frv_relocate_lo16
28   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
29 static bfd_reloc_status_type elf32_frv_relocate_hi16
30   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
31 static bfd_reloc_status_type elf32_frv_relocate_label24
32   PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
33 static bfd_reloc_status_type elf32_frv_relocate_gprel12
34   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
35 static bfd_reloc_status_type elf32_frv_relocate_gprelu12
36   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
37 static bfd_reloc_status_type elf32_frv_relocate_gprello
38   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
39 static bfd_reloc_status_type elf32_frv_relocate_gprelhi
40   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41 static reloc_howto_type *frv_reloc_type_lookup
42   PARAMS ((bfd *, bfd_reloc_code_real_type));
43 static void frv_info_to_howto_rela 
44   PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
45 static boolean elf32_frv_relocate_section 
46   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
47 static boolean elf32_frv_add_symbol_hook
48   PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *));
49 static bfd_reloc_status_type frv_final_link_relocate
50   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
51 static boolean elf32_frv_gc_sweep_hook
52   PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
53 static asection * elf32_frv_gc_mark_hook
54   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
55 static boolean elf32_frv_check_relocs
56   PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
57 static int elf32_frv_machine PARAMS ((bfd *));
58 static boolean elf32_frv_object_p PARAMS ((bfd *));
59 static boolean frv_elf_set_private_flags PARAMS ((bfd *, flagword));
60 static boolean frv_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
61 static boolean frv_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
62 static boolean frv_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
63
64 static reloc_howto_type elf32_frv_howto_table [] =
65 {
66   /* This reloc does nothing.  */
67   HOWTO (R_FRV_NONE,            /* type */
68          0,                     /* rightshift */
69          2,                     /* size (0 = byte, 1 = short, 2 = long) */
70          32,                    /* bitsize */
71          false,                 /* pc_relative */
72          0,                     /* bitpos */
73          complain_overflow_bitfield, /* complain_on_overflow */
74          bfd_elf_generic_reloc, /* special_function */
75          "R_FRV_NONE",          /* name */
76          false,                 /* partial_inplace */
77          0,                     /* src_mask */
78          0,                     /* dst_mask */
79          false),                /* pcrel_offset */
80
81   /* A 32 bit absolute relocation.  */
82   HOWTO (R_FRV_32,              /* type */
83          0,                     /* rightshift */
84          2,                     /* size (0 = byte, 1 = short, 2 = long) */
85          32,                    /* bitsize */
86          false,                 /* pc_relative */
87          0,                     /* bitpos */
88          complain_overflow_bitfield, /* complain_on_overflow */
89          bfd_elf_generic_reloc, /* special_function */
90          "R_FRV_32",            /* name */
91          false,                 /* partial_inplace */
92          0xffffffff,            /* src_mask */
93          0xffffffff,            /* dst_mask */
94          false),                /* pcrel_offset */
95
96   /* A 16 bit pc-relative relocation.  */
97   HOWTO (R_FRV_LABEL16,         /* type */
98          0,                     /* rightshift */
99          2,                     /* size (0 = byte, 1 = short, 2 = long) */
100          16,                    /* bitsize */
101          true,                  /* pc_relative */
102          0,                     /* bitpos */
103          complain_overflow_bitfield, /* complain_on_overflow */
104          bfd_elf_generic_reloc, /* special_function */
105          "R_FRV_LABEL16",       /* name */
106          false,                 /* partial_inplace */
107          0xffff,                /* src_mask */
108          0xffff,                /* dst_mask */
109          true),                 /* pcrel_offset */
110
111   /* A 24-bit pc-relative relocation.  */
112   HOWTO (R_FRV_LABEL24, /* type */
113          2,                     /* rightshift */
114          2,                     /* size (0 = byte, 1 = short, 2 = long) */
115          26,                    /* bitsize */
116          true,                  /* pc_relative */
117          0,                     /* bitpos */
118          complain_overflow_bitfield, /* complain_on_overflow */
119          bfd_elf_generic_reloc, /* special_function */
120          "R_FRV_LABEL24",       /* name */
121          false,                 /* partial_inplace */
122          0x7e03ffff,            /* src_mask */
123          0x7e03ffff,            /* dst_mask */
124          true),                 /* pcrel_offset */
125
126   HOWTO (R_FRV_LO16,            /* type */
127          0,                     /* rightshift */
128          2,                     /* size (0 = byte, 1 = short, 2 = long) */
129          16,                    /* bitsize */
130          false,                 /* pc_relative */
131          0,                     /* bitpos */
132          complain_overflow_dont, /* complain_on_overflow */
133          bfd_elf_generic_reloc, /* special_function */
134          "R_FRV_LO16",          /* name */
135         false,                  /* partial_inplace */
136          0xffff,                /* src_mask */
137          0xffff,                /* dst_mask */
138          false),                /* pcrel_offset */
139
140   HOWTO (R_FRV_HI16,            /* type */
141          0,                     /* rightshift */
142          2,                     /* size (0 = byte, 1 = short, 2 = long) */
143          16,                    /* bitsize */
144          false,                 /* pc_relative */
145          0,                     /* bitpos */
146          complain_overflow_dont, /* complain_on_overflow */
147          bfd_elf_generic_reloc, /* special_function */
148          "R_FRV_HI16",          /* name */
149          false,                 /* partial_inplace */
150          0xffff,                /* src_mask */
151          0xffff,                /* dst_mask */
152          false),                /* pcrel_offset */
153
154   HOWTO (R_FRV_GPREL12,         /* type */
155          0,                     /* rightshift */
156          2,                     /* size (0 = byte, 1 = short, 2 = long) */
157          12,                    /* bitsize */
158          false,                 /* pc_relative */
159          0,                     /* bitpos */
160          complain_overflow_dont, /* complain_on_overflow */
161          bfd_elf_generic_reloc, /* special_function */
162          "R_FRV_GPREL12",       /* name */
163          false,                 /* partial_inplace */
164          0xfff,                 /* src_mask */
165          0xfff,                 /* dst_mask */
166          false),                /* pcrel_offset */
167
168   HOWTO (R_FRV_GPRELU12,        /* type */
169          0,                     /* rightshift */
170          2,                     /* size (0 = byte, 1 = short, 2 = long) */
171          12,                    /* bitsize */
172          false,                 /* pc_relative */
173          0,                     /* bitpos */
174          complain_overflow_dont, /* complain_on_overflow */
175          bfd_elf_generic_reloc, /* special_function */
176          "R_FRV_GPRELU12",      /* name */
177          false,                 /* partial_inplace */
178          0xfff,                 /* src_mask */
179          0x3f03f,               /* dst_mask */
180          false),                /* pcrel_offset */
181
182   HOWTO (R_FRV_GPREL32,         /* type */
183          0,                     /* rightshift */
184          2,                     /* size (0 = byte, 1 = short, 2 = long) */
185          32,                    /* bitsize */
186          false,                 /* pc_relative */
187          0,                     /* bitpos */
188          complain_overflow_dont, /* complain_on_overflow */
189          bfd_elf_generic_reloc, /* special_function */
190          "R_FRV_GPREL32",       /* name */
191          false,                 /* partial_inplace */
192          0xffffffff,            /* src_mask */
193          0xffffffff,            /* dst_mask */
194          false),                /* pcrel_offset */
195
196   HOWTO (R_FRV_GPRELHI,         /* type */
197          0,                     /* rightshift */
198          2,                     /* size (0 = byte, 1 = short, 2 = long) */
199          16,                    /* bitsize */
200          false,                 /* pc_relative */
201          0,                     /* bitpos */
202          complain_overflow_dont, /* complain_on_overflow */
203          bfd_elf_generic_reloc, /* special_function */
204          "R_FRV_GPRELHI",       /* name */
205          false,                 /* partial_inplace */
206          0xffff,                        /* src_mask */
207          0xffff,                /* dst_mask */
208          false),                /* pcrel_offset */
209
210   HOWTO (R_FRV_GPRELLO,         /* type */
211          0,                     /* rightshift */
212          2,                     /* size (0 = byte, 1 = short, 2 = long) */
213          16,                    /* bitsize */
214          false,                 /* pc_relative */
215          0,                     /* bitpos */
216          complain_overflow_dont, /* complain_on_overflow */
217          bfd_elf_generic_reloc, /* special_function */
218          "R_FRV_GPRELLO",       /* name */
219          false,                 /* partial_inplace */
220          0xffff,                        /* src_mask */
221          0xffff,                /* dst_mask */
222          false),                /* pcrel_offset */
223 };
224
225 /* GNU extension to record C++ vtable hierarchy.  */
226 static reloc_howto_type elf32_frv_vtinherit_howto =
227   HOWTO (R_FRV_GNU_VTINHERIT,   /* type */
228          0,                     /* rightshift */
229          2,                     /* size (0 = byte, 1 = short, 2 = long) */
230          0,                     /* bitsize */
231          false,                 /* pc_relative */
232          0,                     /* bitpos */
233          complain_overflow_dont, /* complain_on_overflow */
234          NULL,                  /* special_function */
235          "R_FRV_GNU_VTINHERIT", /* name */
236          false,                 /* partial_inplace */
237          0,                     /* src_mask */
238          0,                     /* dst_mask */
239          false);                /* pcrel_offset */
240
241   /* GNU extension to record C++ vtable member usage.  */
242 static reloc_howto_type elf32_frv_vtentry_howto =
243   HOWTO (R_FRV_GNU_VTENTRY,     /* type */
244          0,                     /* rightshift */
245          2,                     /* size (0 = byte, 1 = short, 2 = long) */
246          0,                     /* bitsize */
247          false,                 /* pc_relative */
248          0,                     /* bitpos */
249          complain_overflow_dont, /* complain_on_overflow */
250          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
251          "R_FRV_GNU_VTENTRY",   /* name */
252          false,                 /* partial_inplace */
253          0,                     /* src_mask */
254          0,                     /* dst_mask */
255          false);                /* pcrel_offset */
256 \f
257 /* Map BFD reloc types to FRV ELF reloc types.  */
258 #if 0
259 struct frv_reloc_map
260 {
261   unsigned int bfd_reloc_val;
262   unsigned int frv_reloc_val;
263 };
264
265 static const struct frv_reloc_map frv_reloc_map [] =
266 {
267   { BFD_RELOC_NONE,           R_FRV_NONE },
268   { BFD_RELOC_32,             R_FRV_32 },
269   { BFD_RELOC_FRV_LABEL16,    R_FRV_LABEL16 },
270   { BFD_RELOC_FRV_LABEL24,    R_FRV_LABEL24 },
271   { BFD_RELOC_FRV_LO16,       R_FRV_LO16 },
272   { BFD_RELOC_FRV_HI16,       R_FRV_HI16 },
273   { BFD_RELOC_FRV_GPREL12,    R_FRV_GPREL12 },
274   { BFD_RELOC_FRV_GPRELU12,   R_FRV_GPRELU12 },
275   { BFD_RELOC_FRV_GPREL32,    R_FRV_GPREL32 },
276   { BFD_RELOC_FRV_GPRELHI,    R_FRV_GPRELHI },
277   { BFD_RELOC_FRV_GPRELLO,    R_FRV_GPRELLO },
278   { BFD_RELOC_VTABLE_INHERIT, R_FRV_GNU_VTINHERIT },
279   { BFD_RELOC_VTABLE_ENTRY,   R_FRV_GNU_VTENTRY },
280 };
281 #endif
282
283 /* Handle an FRV small data reloc.  */
284
285 static bfd_reloc_status_type
286 elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation, contents, value)
287      struct bfd_link_info *info;
288      bfd *input_bfd;
289      asection *input_section;
290      Elf_Internal_Rela *relocation;
291      bfd_byte *contents;
292      bfd_vma value;
293 {
294   bfd_vma insn;
295   bfd_vma gp;
296   struct bfd_link_hash_entry *h;
297
298   h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
299
300   gp = (h->u.def.value
301         + h->u.def.section->output_section->vma
302         + h->u.def.section->output_offset);
303
304   value -= input_section->output_section->vma;
305   value -= (gp - input_section->output_section->vma);
306
307   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
308
309   value += relocation->r_addend;
310
311   if ((long) value > 0x7ff || (long) value < -0x800)
312     return bfd_reloc_overflow;
313
314   bfd_put_32 (input_bfd,
315               (insn & 0xfffff000) | (value & 0xfff),
316               contents + relocation->r_offset);
317
318   return bfd_reloc_ok;
319 }
320
321 /* Handle an FRV small data reloc. for the u12 field.  */
322
323 static bfd_reloc_status_type
324 elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation, contents, value)
325      struct bfd_link_info *info;
326      bfd *input_bfd;
327      asection *input_section;
328      Elf_Internal_Rela *relocation;
329      bfd_byte *contents;
330      bfd_vma value;
331 {
332   bfd_vma insn;
333   bfd_vma gp;
334   struct bfd_link_hash_entry *h;
335   bfd_vma mask;
336
337   h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
338
339   gp = (h->u.def.value
340         + h->u.def.section->output_section->vma
341         + h->u.def.section->output_offset);
342  
343   value -= input_section->output_section->vma;
344   value -= (gp - input_section->output_section->vma);
345
346   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
347
348   value += relocation->r_addend;
349
350   if ((long) value > 0x7ff || (long) value < -0x800)
351     return bfd_reloc_overflow;
352
353   /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0.  */
354   mask = 0x3f03f;
355   insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
356
357   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
358
359   return bfd_reloc_ok;
360 }
361
362 /* Handle an FRV ELF HI16 reloc.  */
363
364 static bfd_reloc_status_type
365 elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
366      bfd *input_bfd;
367      Elf_Internal_Rela *relhi;
368      bfd_byte *contents;
369      bfd_vma value;
370 {
371   bfd_vma insn;
372
373   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
374
375   value += relhi->r_addend;
376   value = ((value >> 16) & 0xffff);
377
378   insn = (insn & 0xffff0000) | value;
379
380   if ((long) value > 0xffff || (long) value < -0x10000)
381     return bfd_reloc_overflow;
382
383   bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
384   return bfd_reloc_ok;
385
386 }
387 static bfd_reloc_status_type
388 elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
389      bfd *input_bfd;
390      Elf_Internal_Rela *rello;
391      bfd_byte *contents;
392      bfd_vma value;
393 {
394   bfd_vma insn;
395
396   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
397
398   value += rello->r_addend;
399   value = value & 0xffff;
400
401   insn = (insn & 0xffff0000) | value;
402
403   if ((long) value > 0xffff || (long) value < -0x10000)
404     return bfd_reloc_overflow;
405
406   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
407   return bfd_reloc_ok;
408 }
409
410 /* Perform the relocation for the CALL label24 instruction.  */
411
412 static bfd_reloc_status_type
413 elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
414      bfd *input_bfd;
415      asection *input_section;
416      Elf_Internal_Rela *rello;
417      bfd_byte *contents;
418      bfd_vma value;
419 {
420   bfd_vma insn;
421   bfd_vma label6;
422   bfd_vma label18;
423
424   /* The format for the call instruction is:
425
426     0 000000 0001111 000000000000000000 
427       label6 opcode  label18
428
429     The branch calculation is: pc + (4*label24)
430     where label24 is the concatenation of label6 and label18.  */
431
432   /* Grab the instruction.  */
433   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
434
435   value -= input_section->output_section->vma + input_section->output_offset;
436   value -= rello->r_offset;
437   value += rello->r_addend;
438
439   value = value >> 2;
440
441   label6  = value & 0xfc0000;
442   label6  = label6 << 7;
443
444   label18 = value & 0x3ffff;
445
446   insn = insn & 0x803c0000;
447   insn = insn | label6;
448   insn = insn | label18;
449
450   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
451
452   return bfd_reloc_ok;
453 }
454
455 static bfd_reloc_status_type
456 elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation, contents, value)
457      struct bfd_link_info *info;
458      bfd *input_bfd;
459      asection *input_section;
460      Elf_Internal_Rela *relocation;
461      bfd_byte *contents;
462      bfd_vma value;
463 {
464   bfd_vma insn;
465   bfd_vma gp;
466   struct bfd_link_hash_entry *h;
467
468   h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
469
470   gp = (h->u.def.value
471         + h->u.def.section->output_section->vma
472         + h->u.def.section->output_offset);
473
474   value -= input_section->output_section->vma;
475   value -= (gp - input_section->output_section->vma);
476   value += relocation->r_addend;
477   value = ((value >> 16) & 0xffff);
478
479   if ((long) value > 0xffff || (long) value < -0x10000)
480     return bfd_reloc_overflow;
481
482   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
483   insn = (insn & 0xffff0000) | value;
484
485   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
486   return bfd_reloc_ok;
487 }
488
489 static bfd_reloc_status_type
490 elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation, contents, value)
491      struct bfd_link_info *info;
492      bfd *input_bfd;
493      asection *input_section;
494      Elf_Internal_Rela *relocation;
495      bfd_byte *contents;
496      bfd_vma value;
497 {
498   bfd_vma insn;
499   bfd_vma gp;
500   struct bfd_link_hash_entry *h;
501
502   h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
503
504   gp = (h->u.def.value
505         + h->u.def.section->output_section->vma
506         + h->u.def.section->output_offset);
507
508   value -= input_section->output_section->vma;
509   value -= (gp - input_section->output_section->vma);
510   value += relocation->r_addend;
511   value = value & 0xffff;
512
513   if ((long) value > 0xffff || (long) value < -0x10000)
514     return bfd_reloc_overflow;
515
516   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
517   insn = (insn & 0xffff0000) | value;
518
519   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
520
521  return bfd_reloc_ok;
522 }
523
524 static reloc_howto_type *
525 frv_reloc_type_lookup (abfd, code)
526      bfd * abfd ATTRIBUTE_UNUSED;
527      bfd_reloc_code_real_type code;
528 {
529   switch (code)
530     {
531     default:
532       break;
533
534     case BFD_RELOC_NONE:
535       return &elf32_frv_howto_table[ (int) R_FRV_NONE];
536   
537     case BFD_RELOC_32:
538     case BFD_RELOC_CTOR:
539       return &elf32_frv_howto_table[ (int) R_FRV_32];
540
541     case BFD_RELOC_FRV_LABEL16:
542       return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
543
544     case BFD_RELOC_FRV_LABEL24:
545       return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
546
547     case BFD_RELOC_FRV_LO16:
548       return &elf32_frv_howto_table[ (int) R_FRV_LO16];
549
550     case BFD_RELOC_FRV_HI16:
551       return &elf32_frv_howto_table[ (int) R_FRV_HI16];
552
553     case BFD_RELOC_FRV_GPREL12:
554       return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
555
556     case BFD_RELOC_FRV_GPRELU12:
557       return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
558
559     case BFD_RELOC_FRV_GPREL32:
560       return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
561
562     case BFD_RELOC_FRV_GPRELHI:
563       return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
564
565     case BFD_RELOC_FRV_GPRELLO:
566       return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
567
568     case BFD_RELOC_VTABLE_INHERIT:
569       return &elf32_frv_vtinherit_howto;
570
571     case BFD_RELOC_VTABLE_ENTRY:
572       return &elf32_frv_vtentry_howto;
573     }
574
575   return NULL;
576 }
577
578 /* Set the howto pointer for an FRV ELF reloc.  */
579
580 static void
581 frv_info_to_howto_rela (abfd, cache_ptr, dst)
582      bfd * abfd ATTRIBUTE_UNUSED;
583      arelent * cache_ptr;
584      Elf32_Internal_Rela * dst;
585 {
586   unsigned int r_type;
587
588   r_type = ELF32_R_TYPE (dst->r_info);
589   switch (r_type)
590     {
591     case R_FRV_GNU_VTINHERIT:
592       cache_ptr->howto = &elf32_frv_vtinherit_howto;
593       break;
594
595     case R_FRV_GNU_VTENTRY:
596       cache_ptr->howto = &elf32_frv_vtentry_howto;
597       break;
598
599     default:
600       cache_ptr->howto = & elf32_frv_howto_table [r_type];
601       break;
602     }
603 }
604 \f
605 /* Perform a single relocation.  By default we use the standard BFD
606    routines, but a few relocs, we have to do them ourselves.  */
607
608 static bfd_reloc_status_type
609 frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
610      reloc_howto_type *  howto;
611      bfd *               input_bfd;
612      asection *          input_section;
613      bfd_byte *          contents;
614      Elf_Internal_Rela * rel;
615      bfd_vma             relocation;
616 {
617   return _bfd_final_link_relocate (howto, input_bfd, input_section,
618                                    contents, rel->r_offset, relocation,
619                                    rel->r_addend);
620 }
621
622 \f
623 /* Relocate an FRV ELF section.
624
625    The RELOCATE_SECTION function is called by the new ELF backend linker
626    to handle the relocations for a section.
627
628    The relocs are always passed as Rela structures; if the section
629    actually uses Rel structures, the r_addend field will always be
630    zero.
631
632    This function is responsible for adjusting the section contents as
633    necessary, and (if using Rela relocs and generating a relocateable
634    output file) adjusting the reloc addend as necessary.
635
636    This function does not have to worry about setting the reloc
637    address or the reloc symbol index.
638
639    LOCAL_SYMS is a pointer to the swapped in local symbols.
640
641    LOCAL_SECTIONS is an array giving the section in the input file
642    corresponding to the st_shndx field of each local symbol.
643
644    The global hash table entry for the global symbols can be found
645    via elf_sym_hashes (input_bfd).
646
647    When generating relocateable output, this function must handle
648    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
649    going to be the section symbol corresponding to the output
650    section, which means that the addend must be adjusted
651    accordingly.  */
652
653 static boolean
654 elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
655                             contents, relocs, local_syms, local_sections)
656      bfd *                   output_bfd ATTRIBUTE_UNUSED;
657      struct bfd_link_info *  info;
658      bfd *                   input_bfd;
659      asection *              input_section;
660      bfd_byte *              contents;
661      Elf_Internal_Rela *     relocs;
662      Elf_Internal_Sym *      local_syms;
663      asection **             local_sections;
664 {
665   Elf_Internal_Shdr *           symtab_hdr;
666   struct elf_link_hash_entry ** sym_hashes;
667   Elf_Internal_Rela *           rel;
668   Elf_Internal_Rela *           relend;
669
670   if (info->relocateable)
671     return true;
672
673   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
674   sym_hashes = elf_sym_hashes (input_bfd);
675   relend     = relocs + input_section->reloc_count;
676
677   for (rel = relocs; rel < relend; rel ++)
678     {
679       reloc_howto_type *           howto;
680       unsigned long                r_symndx;
681       Elf_Internal_Sym *           sym;
682       asection *                   sec;
683       struct elf_link_hash_entry * h;
684       bfd_vma                      relocation;
685       bfd_reloc_status_type        r;
686       const char *                 name = NULL;
687       int                          r_type;
688       
689       r_type = ELF32_R_TYPE (rel->r_info);
690       
691       if (   r_type == R_FRV_GNU_VTINHERIT
692           || r_type == R_FRV_GNU_VTENTRY)
693         continue;
694       
695       /* This is a final link.  */
696       r_symndx = ELF32_R_SYM (rel->r_info);
697       howto  = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
698       h      = NULL;
699       sym    = NULL;
700       sec    = NULL;
701       
702       if (r_symndx < symtab_hdr->sh_info)
703         {
704           sym = local_syms + r_symndx;
705           sec = local_sections [r_symndx];
706           relocation = (sec->output_section->vma
707                         + sec->output_offset
708                         + sym->st_value);
709           
710           name = bfd_elf_string_from_elf_section
711             (input_bfd, symtab_hdr->sh_link, sym->st_name);
712           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
713         }
714       else
715         {
716           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
717           
718           while (h->root.type == bfd_link_hash_indirect
719                  || h->root.type == bfd_link_hash_warning)
720             h = (struct elf_link_hash_entry *) h->root.u.i.link;
721
722           name = h->root.root.string;
723           
724           if (h->root.type == bfd_link_hash_defined
725               || h->root.type == bfd_link_hash_defweak)
726             {
727               sec = h->root.u.def.section;
728               relocation = (h->root.u.def.value
729                             + sec->output_section->vma
730                             + sec->output_offset);
731             }
732           else if (h->root.type == bfd_link_hash_undefweak)
733             {
734               relocation = 0;
735             }
736           else
737             {
738               if (! ((*info->callbacks->undefined_symbol)
739                      (info, h->root.root.string, input_bfd,
740                       input_section, rel->r_offset, true)))
741                 return false;
742               relocation = 0;
743             }
744         }
745       
746      if (r_type == R_FRV_HI16)
747        r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
748
749      else if (r_type == R_FRV_LO16)
750        r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
751
752      else if (r_type == R_FRV_LABEL24)
753        r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
754
755      else if (r_type == R_FRV_GPREL12)
756        r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
757
758      else if (r_type == R_FRV_GPRELU12)
759        r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
760
761      else if (r_type == R_FRV_GPRELLO)
762        r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
763
764      else if (r_type == R_FRV_GPRELHI)
765        r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
766
767      else
768        r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
769
770       if (r != bfd_reloc_ok)
771         {
772           const char * msg = (const char *) NULL;
773
774           switch (r)
775             {
776             case bfd_reloc_overflow:
777               r = info->callbacks->reloc_overflow
778                 (info, name, howto->name, (bfd_vma) 0,
779                  input_bfd, input_section, rel->r_offset);
780               break;
781               
782             case bfd_reloc_undefined:
783               r = info->callbacks->undefined_symbol
784                 (info, name, input_bfd, input_section, rel->r_offset, true);
785               break;
786               
787             case bfd_reloc_outofrange:
788               msg = _("internal error: out of range error");
789               break;
790
791             case bfd_reloc_notsupported:
792               msg = _("internal error: unsupported relocation error");
793               break;
794
795             case bfd_reloc_dangerous:
796               msg = _("internal error: dangerous relocation");
797               break;
798
799             default:
800               msg = _("internal error: unknown error");
801               break;
802             }
803
804           if (msg)
805             r = info->callbacks->warning
806               (info, msg, name, input_bfd, input_section, rel->r_offset);
807
808           if (! r)
809             return false;
810         }
811     }
812
813   return true;
814 }
815 \f
816 /* Return the section that should be marked against GC for a given
817    relocation.  */
818
819 static asection *
820 elf32_frv_gc_mark_hook (sec, info, rel, h, sym)
821      asection *                   sec;
822      struct bfd_link_info *       info ATTRIBUTE_UNUSED;
823      Elf_Internal_Rela *          rel;
824      struct elf_link_hash_entry * h;
825      Elf_Internal_Sym *           sym;
826 {
827   if (h != NULL)
828     {
829       switch (ELF32_R_TYPE (rel->r_info))
830         {
831         case R_FRV_GNU_VTINHERIT:
832         case R_FRV_GNU_VTENTRY:
833           break;
834
835         default:
836           switch (h->root.type)
837             {
838             default:
839               break;
840
841             case bfd_link_hash_defined:
842             case bfd_link_hash_defweak:
843               return h->root.u.def.section;
844
845             case bfd_link_hash_common:
846               return h->root.u.c.p->section;
847             }
848         }
849     }
850   else
851     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
852
853   return NULL;
854 }
855
856 /* Update the got entry reference counts for the section being removed.  */
857
858 static boolean
859 elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
860      bfd *                     abfd ATTRIBUTE_UNUSED;
861      struct bfd_link_info *    info ATTRIBUTE_UNUSED;
862      asection *                sec ATTRIBUTE_UNUSED;
863      const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
864 {
865   return true;
866 }
867
868 \f
869 /* Hook called by the linker routine which adds symbols from an object
870    file.  We use it to put .comm items in .scomm, and not .comm.  */
871
872 static boolean
873 elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
874      bfd *abfd;
875      struct bfd_link_info *info;
876      const Elf_Internal_Sym *sym;
877      const char **namep ATTRIBUTE_UNUSED;
878      flagword *flagsp ATTRIBUTE_UNUSED;
879      asection **secp;
880      bfd_vma *valp;
881 {
882   if (sym->st_shndx == SHN_COMMON
883       && !info->relocateable
884       && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
885     {
886       /* Common symbols less than or equal to -G nn bytes are
887          automatically put into .sbss.  */
888
889       asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
890
891       if (scomm == NULL)
892         {
893           scomm = bfd_make_section (abfd, ".scommon");
894           if (scomm == NULL
895               || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
896                                                        | SEC_IS_COMMON
897                                                        | SEC_LINKER_CREATED)))
898             return false;
899         }
900
901       *secp = scomm;
902       *valp = sym->st_size;
903     }
904
905   return true;
906 }
907 /* Look through the relocs for a section during the first phase.
908    Since we don't do .gots or .plts, we just need to consider the
909    virtual table relocs for gc.  */
910  
911 static boolean
912 elf32_frv_check_relocs (abfd, info, sec, relocs)
913      bfd *abfd;
914      struct bfd_link_info *info;
915      asection *sec;
916      const Elf_Internal_Rela *relocs;
917 {
918   Elf_Internal_Shdr *symtab_hdr;
919   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
920   const Elf_Internal_Rela *rel;
921   const Elf_Internal_Rela *rel_end;
922  
923   if (info->relocateable)
924     return true;
925  
926   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
927   sym_hashes = elf_sym_hashes (abfd);
928   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
929   if (!elf_bad_symtab (abfd))
930     sym_hashes_end -= symtab_hdr->sh_info;
931  
932   rel_end = relocs + sec->reloc_count;
933   for (rel = relocs; rel < rel_end; rel++)
934     {
935       struct elf_link_hash_entry *h;
936       unsigned long r_symndx;
937  
938       r_symndx = ELF32_R_SYM (rel->r_info);
939       if (r_symndx < symtab_hdr->sh_info)
940         h = NULL;
941       else
942         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
943  
944       switch (ELF32_R_TYPE (rel->r_info))
945         {
946         /* This relocation describes the C++ object vtable hierarchy.
947            Reconstruct it for later use during GC.  */
948         case R_FRV_GNU_VTINHERIT:
949           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
950             return false;
951           break;
952  
953         /* This relocation describes which C++ vtable entries are actually
954            used.  Record for later use during GC.  */
955         case R_FRV_GNU_VTENTRY:
956           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
957             return false;
958           break;
959         }
960     }
961  
962   return true;
963 }
964
965 \f
966 /* Return the machine subcode from the ELF e_flags header.  */
967
968 static int
969 elf32_frv_machine (abfd)
970      bfd *abfd;
971 {
972   switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
973     {
974     default:                break;
975     case EF_FRV_CPU_FR500:  return bfd_mach_fr500;
976     case EF_FRV_CPU_FR400:  return bfd_mach_fr400;
977     case EF_FRV_CPU_FR300:  return bfd_mach_fr300;
978     case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
979     case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
980     }
981
982   return bfd_mach_frv;
983 }
984
985 /* Set the right machine number for a FRV ELF file.  */
986
987 static boolean
988 elf32_frv_object_p (abfd)
989      bfd *abfd;
990 {
991   bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
992   return true;
993 }
994 \f
995 /* Function to set the ELF flag bits.  */
996
997 static boolean
998 frv_elf_set_private_flags (abfd, flags)
999      bfd *abfd;
1000      flagword flags;
1001 {
1002   elf_elfheader (abfd)->e_flags = flags;
1003   elf_flags_init (abfd) = true;
1004   return true;
1005 }
1006
1007 /* Copy backend specific data from one object module to another.  */
1008
1009 static boolean
1010 frv_elf_copy_private_bfd_data (ibfd, obfd)
1011      bfd *ibfd;
1012      bfd *obfd;
1013 {
1014   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1015       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1016     return true;
1017
1018   BFD_ASSERT (!elf_flags_init (obfd)
1019               || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
1020
1021   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1022   elf_flags_init (obfd) = true;
1023   return true;
1024 }
1025
1026 /* Merge backend specific data from an object file to the output
1027    object file when linking.  */
1028
1029 static boolean
1030 frv_elf_merge_private_bfd_data (ibfd, obfd)
1031      bfd *ibfd;
1032      bfd *obfd;
1033 {
1034   flagword old_flags, old_partial;
1035   flagword new_flags, new_partial;
1036   boolean error = false;
1037   char new_opt[80];
1038   char old_opt[80];
1039
1040   new_opt[0] = old_opt[0] = '\0';
1041   new_flags = elf_elfheader (ibfd)->e_flags;
1042   old_flags = elf_elfheader (obfd)->e_flags;
1043
1044 #ifdef DEBUG
1045   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
1046                          old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
1047                          bfd_get_filename (ibfd));
1048 #endif
1049
1050   if (!elf_flags_init (obfd))                   /* First call, no flags set.  */
1051     {
1052       elf_flags_init (obfd) = true;
1053       old_flags = new_flags;
1054     }
1055
1056   else if (new_flags == old_flags)              /* Compatible flags are ok.  */
1057     ;
1058
1059   else                                          /* Possibly incompatible flags.  */
1060     {
1061       /* Warn if different # of gprs are used.  Note, 0 means nothing is
1062          said about the size of gprs.  */
1063       new_partial = (new_flags & EF_FRV_GPR_MASK);
1064       old_partial = (old_flags & EF_FRV_GPR_MASK);
1065       if (new_partial == old_partial)
1066         ;
1067
1068       else if (new_partial == 0)
1069         ;
1070
1071       else if (old_partial == 0)
1072         old_flags |= new_partial;
1073
1074       else
1075         {
1076           switch (new_partial)
1077             {
1078             default:            strcat (new_opt, " -mgpr-??"); break;
1079             case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
1080             case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
1081             }
1082
1083           switch (old_partial)
1084             {
1085             default:            strcat (old_opt, " -mgpr-??"); break;
1086             case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
1087             case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
1088             }
1089         }
1090
1091       /* Warn if different # of fprs are used.  Note, 0 means nothing is
1092          said about the size of fprs.  */
1093       new_partial = (new_flags & EF_FRV_FPR_MASK);
1094       old_partial = (old_flags & EF_FRV_FPR_MASK);
1095       if (new_partial == old_partial)
1096         ;
1097
1098       else if (new_partial == 0)
1099         ;
1100
1101       else if (old_partial == 0)
1102         old_flags |= new_partial;
1103
1104       else
1105         {
1106           switch (new_partial)
1107             {
1108             default:              strcat (new_opt, " -mfpr-?");      break;
1109             case EF_FRV_FPR_32:   strcat (new_opt, " -mfpr-32");     break;
1110             case EF_FRV_FPR_64:   strcat (new_opt, " -mfpr-64");     break;
1111             case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
1112             }
1113
1114           switch (old_partial)
1115             {
1116             default:              strcat (old_opt, " -mfpr-?");      break;
1117             case EF_FRV_FPR_32:   strcat (old_opt, " -mfpr-32");     break;
1118             case EF_FRV_FPR_64:   strcat (old_opt, " -mfpr-64");     break;
1119             case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
1120             }
1121         }
1122
1123       /* Warn if different dword support was used.  Note, 0 means nothing is
1124          said about the dword support.  */
1125       new_partial = (new_flags & EF_FRV_DWORD_MASK);
1126       old_partial = (old_flags & EF_FRV_DWORD_MASK);
1127       if (new_partial == old_partial)
1128         ;
1129
1130       else if (new_partial == 0)
1131         ;
1132
1133       else if (old_partial == 0)
1134         old_flags |= new_partial;
1135
1136       else
1137         {
1138           switch (new_partial)
1139             {
1140             default:               strcat (new_opt, " -mdword-?");  break;
1141             case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword");    break;
1142             case EF_FRV_DWORD_NO:  strcat (new_opt, " -mno-dword"); break;
1143             }
1144
1145           switch (old_partial)
1146             {
1147             default:               strcat (old_opt, " -mdword-?");  break;
1148             case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword");    break;
1149             case EF_FRV_DWORD_NO:  strcat (old_opt, " -mno-dword"); break;
1150             }
1151         }
1152
1153       /* Or in flags that accumulate (ie, if one module uses it, mark that the
1154          feature is used.  */
1155       old_flags |= new_flags & (EF_FRV_DOUBLE
1156                                 | EF_FRV_MEDIA
1157                                 | EF_FRV_MULADD
1158                                 | EF_FRV_NON_PIC_RELOCS);
1159
1160       /* If any module was compiled without -G0, clear the G0 bit.  */
1161       old_flags = ((old_flags & ~ EF_FRV_G0)
1162                    | (old_flags & new_flags & EF_FRV_G0));
1163
1164       /* If any module was compiled without -mnopack, clear the mnopack bit.  */
1165       old_flags = ((old_flags & ~ EF_FRV_NOPACK)
1166                    | (old_flags & new_flags & EF_FRV_NOPACK));
1167
1168       /* We don't have to do anything if the pic flags are the same, or the new
1169          module(s) were compiled with -mlibrary-pic.  */
1170       new_partial = (new_flags & EF_FRV_PIC_FLAGS);
1171       old_partial = (old_flags & EF_FRV_PIC_FLAGS);
1172       if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
1173         ;
1174
1175       /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
1176          flags if any from the new module.  */
1177       else if ((old_partial & EF_FRV_LIBPIC) != 0)
1178         old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
1179
1180       /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
1181       else if (new_partial != 0 && old_partial != 0)
1182         old_flags |= new_partial;
1183
1184       /* One module was compiled for pic and the other was not, see if we have
1185          had any relocations that are not pic-safe.  */
1186       else
1187         {
1188           if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
1189             old_flags |= new_partial;
1190           else
1191             {
1192               old_flags &= ~ EF_FRV_PIC_FLAGS;
1193 #ifndef FRV_NO_PIC_ERROR
1194               error = true;
1195               (*_bfd_error_handler)
1196                 (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
1197                  bfd_get_filename (ibfd),
1198                  (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
1199 #endif
1200             }
1201         }
1202
1203       /* Warn if different cpu is used (allow a specific cpu to override
1204          the generic cpu).  */
1205       new_partial = (new_flags & EF_FRV_CPU_MASK);
1206       old_partial = (old_flags & EF_FRV_CPU_MASK);
1207       if (new_partial == old_partial)
1208         ;
1209
1210       else if (new_partial == EF_FRV_CPU_GENERIC)
1211         ;
1212
1213       else if (old_partial == EF_FRV_CPU_GENERIC)
1214         old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
1215
1216       else
1217         {
1218           switch (new_partial)
1219             {
1220             default:                 strcat (new_opt, " -mcpu=?");      break;
1221             case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv");    break;
1222             case EF_FRV_CPU_SIMPLE:  strcat (new_opt, " -mcpu=simple"); break;
1223             case EF_FRV_CPU_FR500:   strcat (new_opt, " -mcpu=fr500");  break;
1224             case EF_FRV_CPU_FR400:   strcat (new_opt, " -mcpu=fr400");  break;
1225             case EF_FRV_CPU_FR300:   strcat (new_opt, " -mcpu=fr300");  break;
1226             case EF_FRV_CPU_TOMCAT:  strcat (new_opt, " -mcpu=tomcat"); break;
1227             }
1228
1229           switch (old_partial)
1230             {
1231             default:                 strcat (old_opt, " -mcpu=?");      break;
1232             case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv");    break;
1233             case EF_FRV_CPU_SIMPLE:  strcat (old_opt, " -mcpu=simple"); break;
1234             case EF_FRV_CPU_FR500:   strcat (old_opt, " -mcpu=fr500");  break;
1235             case EF_FRV_CPU_FR400:   strcat (old_opt, " -mcpu=fr400");  break;
1236             case EF_FRV_CPU_FR300:   strcat (old_opt, " -mcpu=fr300");  break;
1237             case EF_FRV_CPU_TOMCAT:  strcat (old_opt, " -mcpu=tomcat"); break;
1238             }
1239         }
1240       
1241       /* Print out any mismatches from above.  */
1242       if (new_opt[0])
1243         {
1244           error = true;
1245           (*_bfd_error_handler)
1246             (_("%s: compiled with %s and linked with modules compiled with %s"),
1247              bfd_get_filename (ibfd), new_opt, old_opt);
1248         }
1249
1250       /* Warn about any other mismatches */
1251       new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
1252       old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
1253       if (new_partial != old_partial)
1254         {
1255           old_flags |= new_partial;
1256           error = true;
1257           (*_bfd_error_handler)
1258             (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
1259              bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
1260         }
1261     }
1262
1263   /* If the cpu is -mcpu=simple, then set the -mnopack bit.  */
1264   if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
1265     old_flags |= EF_FRV_NOPACK;
1266
1267   /* Update the old flags now with changes made above.  */
1268   old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
1269   elf_elfheader (obfd)->e_flags = old_flags;
1270   if (old_partial != (old_flags & EF_FRV_CPU_MASK))
1271     bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
1272
1273   if (error)
1274     bfd_set_error (bfd_error_bad_value);
1275
1276   return !error;
1277 }
1278
1279 \f
1280 boolean
1281 frv_elf_print_private_bfd_data (abfd, ptr)
1282      bfd *abfd;
1283      PTR ptr;
1284 {
1285   FILE *file = (FILE *) ptr;
1286   flagword flags;
1287
1288   BFD_ASSERT (abfd != NULL && ptr != NULL);
1289
1290   /* Print normal ELF private data.  */
1291   _bfd_elf_print_private_bfd_data (abfd, ptr);
1292
1293   flags = elf_elfheader (abfd)->e_flags;
1294   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
1295
1296   switch (flags & EF_FRV_CPU_MASK)
1297     {
1298     default:                                                    break;
1299     case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple");    break;
1300     case EF_FRV_CPU_FR500:  fprintf (file, " -mcpu=fr500");     break;
1301     case EF_FRV_CPU_FR400:  fprintf (file, " -mcpu=fr400");     break;
1302     case EF_FRV_CPU_FR300:  fprintf (file, " -mcpu=fr300");     break;
1303     case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat");    break;
1304     }
1305
1306   switch (flags & EF_FRV_GPR_MASK)
1307     {
1308     default:                                                    break;
1309     case EF_FRV_GPR_32: fprintf (file, " -mgpr-32");            break;
1310     case EF_FRV_GPR_64: fprintf (file, " -mgpr-64");            break;
1311     }
1312
1313   switch (flags & EF_FRV_FPR_MASK)
1314     {
1315     default:                                                    break;
1316     case EF_FRV_FPR_32:   fprintf (file, " -mfpr-32");          break;
1317     case EF_FRV_FPR_64:   fprintf (file, " -mfpr-64");          break;
1318     case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float");      break;
1319     }
1320
1321   switch (flags & EF_FRV_DWORD_MASK)
1322     {
1323     default:                                                    break;
1324     case EF_FRV_DWORD_YES: fprintf (file, " -mdword");          break;
1325     case EF_FRV_DWORD_NO:  fprintf (file, " -mno-dword");       break;
1326     }
1327
1328   if (flags & EF_FRV_DOUBLE)
1329     fprintf (file, " -mdouble");
1330
1331   if (flags & EF_FRV_MEDIA)
1332     fprintf (file, " -mmedia");
1333
1334   if (flags & EF_FRV_MULADD)
1335     fprintf (file, " -mmuladd");
1336
1337   if (flags & EF_FRV_PIC)
1338     fprintf (file, " -fpic");
1339
1340   if (flags & EF_FRV_BIGPIC)
1341     fprintf (file, " -fPIC");
1342
1343   if (flags & EF_FRV_NON_PIC_RELOCS)
1344     fprintf (file, " non-pic relocations");
1345
1346   if (flags & EF_FRV_G0)
1347     fprintf (file, " -G0");
1348
1349   fputc ('\n', file);
1350   return true;
1351 }
1352
1353 \f
1354 #define ELF_ARCH                bfd_arch_frv
1355 #define ELF_MACHINE_CODE        EM_CYGNUS_FRV
1356 #define ELF_MAXPAGESIZE         0x1000
1357
1358 #define TARGET_BIG_SYM          bfd_elf32_frv_vec
1359 #define TARGET_BIG_NAME         "elf32-frv"
1360
1361 #define elf_info_to_howto_rel                   NULL
1362 #define elf_info_to_howto                       frv_info_to_howto_rela
1363 #define elf_backend_relocate_section            elf32_frv_relocate_section
1364 #define elf_backend_gc_mark_hook                elf32_frv_gc_mark_hook
1365 #define elf_backend_gc_sweep_hook               elf32_frv_gc_sweep_hook
1366 #define elf_backend_check_relocs                elf32_frv_check_relocs
1367 #define elf_backend_object_p                    elf32_frv_object_p
1368 #define elf_backend_add_symbol_hook             elf32_frv_add_symbol_hook
1369
1370 #define elf_backend_can_gc_sections             1
1371 #define elf_backend_rela_normal                 1
1372
1373 #define bfd_elf32_bfd_reloc_type_lookup         frv_reloc_type_lookup
1374 #define bfd_elf32_bfd_set_private_flags         frv_elf_set_private_flags
1375 #define bfd_elf32_bfd_copy_private_bfd_data     frv_elf_copy_private_bfd_data
1376 #define bfd_elf32_bfd_merge_private_bfd_data    frv_elf_merge_private_bfd_data
1377 #define bfd_elf32_bfd_print_private_bfd_data    frv_elf_print_private_bfd_data
1378
1379 #include "elf32-target.h"