* configure.in (vax-*-netbsd*): Set COREFILE to netbsd-core.lo.
[deliverable/binutils-gdb.git] / bfd / elf32-frv.c
CommitLineData
4e5ba5b7
DB
1/* FRV-specific support for 32-bit ELF.
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 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. */
27static bfd_reloc_status_type elf32_frv_relocate_lo16
28 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
29static bfd_reloc_status_type elf32_frv_relocate_hi16
30 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
31static bfd_reloc_status_type elf32_frv_relocate_label24
32 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
33static bfd_reloc_status_type elf32_frv_relocate_gprel12
34 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
35static bfd_reloc_status_type elf32_frv_relocate_gprelu12
36 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
37static bfd_reloc_status_type elf32_frv_relocate_gprello
38 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
39static bfd_reloc_status_type elf32_frv_relocate_gprelhi
40 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41static reloc_howto_type *frv_reloc_type_lookup
42 PARAMS ((bfd *, bfd_reloc_code_real_type));
43static void frv_info_to_howto_rela
44 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
45static boolean elf32_frv_relocate_section
46 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
47static boolean elf32_frv_add_symbol_hook
48 PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *));
49static bfd_reloc_status_type frv_final_link_relocate
50 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
51static boolean elf32_frv_gc_sweep_hook
52 PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
53static asection * elf32_frv_gc_mark_hook
54 PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
55static boolean elf32_frv_check_relocs
56 PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
57static int elf32_frv_machine PARAMS ((bfd *));
58static boolean elf32_frv_object_p PARAMS ((bfd *));
59static boolean frv_elf_set_private_flags PARAMS ((bfd *, flagword));
60static boolean frv_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
61static boolean frv_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
62static boolean frv_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
63
64static 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. */
226static 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. */
242static 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
259struct frv_reloc_map
260{
261 unsigned int bfd_reloc_val;
262 unsigned int frv_reloc_val;
263};
264
265static 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
285static bfd_reloc_status_type
286elf32_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
323static bfd_reloc_status_type
324elf32_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
364static bfd_reloc_status_type
365elf32_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}
387static bfd_reloc_status_type
388elf32_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
412static bfd_reloc_status_type
413elf32_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
455static bfd_reloc_status_type
456elf32_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
489static bfd_reloc_status_type
490elf32_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
524static reloc_howto_type *
525frv_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
580static void
581frv_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
608static bfd_reloc_status_type
609frv_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 There is some attempt to make this function usable for many architectures,
625 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
626 if only to serve as a learning tool.
627
628 The RELOCATE_SECTION function is called by the new ELF backend linker
629 to handle the relocations for a section.
630
631 The relocs are always passed as Rela structures; if the section
632 actually uses Rel structures, the r_addend field will always be
633 zero.
634
635 This function is responsible for adjusting the section contents as
636 necessary, and (if using Rela relocs and generating a relocateable
637 output file) adjusting the reloc addend as necessary.
638
639 This function does not have to worry about setting the reloc
640 address or the reloc symbol index.
641
642 LOCAL_SYMS is a pointer to the swapped in local symbols.
643
644 LOCAL_SECTIONS is an array giving the section in the input file
645 corresponding to the st_shndx field of each local symbol.
646
647 The global hash table entry for the global symbols can be found
648 via elf_sym_hashes (input_bfd).
649
650 When generating relocateable output, this function must handle
651 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
652 going to be the section symbol corresponding to the output
653 section, which means that the addend must be adjusted
654 accordingly. */
655
656static boolean
657elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
658 contents, relocs, local_syms, local_sections)
659 bfd * output_bfd ATTRIBUTE_UNUSED;
660 struct bfd_link_info * info;
661 bfd * input_bfd;
662 asection * input_section;
663 bfd_byte * contents;
664 Elf_Internal_Rela * relocs;
665 Elf_Internal_Sym * local_syms;
666 asection ** local_sections;
667{
668 Elf_Internal_Shdr * symtab_hdr;
669 struct elf_link_hash_entry ** sym_hashes;
670 Elf_Internal_Rela * rel;
671 Elf_Internal_Rela * relend;
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 r_symndx = ELF32_R_SYM (rel->r_info);
696
697 if (info->relocateable)
698 {
699 /* This is a relocateable link. We don't have to change
700 anything, unless the reloc is against a section symbol,
701 in which case we have to adjust according to where the
702 section symbol winds up in the output section. */
703 if (r_symndx < symtab_hdr->sh_info)
704 {
705 sym = local_syms + r_symndx;
706
707 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
708 {
709 sec = local_sections [r_symndx];
710 rel->r_addend += sec->output_offset + sym->st_value;
711 }
712 }
713
714 continue;
715 }
716
717 /* This is a final link. */
718 howto = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
719 h = NULL;
720 sym = NULL;
721 sec = NULL;
722
723 if (r_symndx < symtab_hdr->sh_info)
724 {
725 sym = local_syms + r_symndx;
726 sec = local_sections [r_symndx];
727 relocation = (sec->output_section->vma
728 + sec->output_offset
729 + sym->st_value);
730
731 name = bfd_elf_string_from_elf_section
732 (input_bfd, symtab_hdr->sh_link, sym->st_name);
733 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
734 }
735 else
736 {
737 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
738
739 while (h->root.type == bfd_link_hash_indirect
740 || h->root.type == bfd_link_hash_warning)
741 h = (struct elf_link_hash_entry *) h->root.u.i.link;
742
743 name = h->root.root.string;
744
745 if (h->root.type == bfd_link_hash_defined
746 || h->root.type == bfd_link_hash_defweak)
747 {
748 sec = h->root.u.def.section;
749 relocation = (h->root.u.def.value
750 + sec->output_section->vma
751 + sec->output_offset);
752 }
753 else if (h->root.type == bfd_link_hash_undefweak)
754 {
755 relocation = 0;
756 }
757 else
758 {
759 if (! ((*info->callbacks->undefined_symbol)
760 (info, h->root.root.string, input_bfd,
761 input_section, rel->r_offset, true)))
762 return false;
763 relocation = 0;
764 }
765 }
766
767 if (r_type == R_FRV_HI16)
768 r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
769
770 else if (r_type == R_FRV_LO16)
771 r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
772
773 else if (r_type == R_FRV_LABEL24)
774 r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
775
776 else if (r_type == R_FRV_GPREL12)
777 r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
778
779 else if (r_type == R_FRV_GPRELU12)
780 r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
781
782 else if (r_type == R_FRV_GPRELLO)
783 r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
784
785 else if (r_type == R_FRV_GPRELHI)
786 r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
787
788 else
789 r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
790
791 if (r != bfd_reloc_ok)
792 {
793 const char * msg = (const char *) NULL;
794
795 switch (r)
796 {
797 case bfd_reloc_overflow:
798 r = info->callbacks->reloc_overflow
799 (info, name, howto->name, (bfd_vma) 0,
800 input_bfd, input_section, rel->r_offset);
801 break;
802
803 case bfd_reloc_undefined:
804 r = info->callbacks->undefined_symbol
805 (info, name, input_bfd, input_section, rel->r_offset, true);
806 break;
807
808 case bfd_reloc_outofrange:
809 msg = _("internal error: out of range error");
810 break;
811
812 case bfd_reloc_notsupported:
813 msg = _("internal error: unsupported relocation error");
814 break;
815
816 case bfd_reloc_dangerous:
817 msg = _("internal error: dangerous relocation");
818 break;
819
820 default:
821 msg = _("internal error: unknown error");
822 break;
823 }
824
825 if (msg)
826 r = info->callbacks->warning
827 (info, msg, name, input_bfd, input_section, rel->r_offset);
828
829 if (! r)
830 return false;
831 }
832 }
833
834 return true;
835}
836\f
837/* Return the section that should be marked against GC for a given
838 relocation. */
839
840static asection *
841elf32_frv_gc_mark_hook (abfd, info, rel, h, sym)
842 bfd * abfd;
843 struct bfd_link_info * info ATTRIBUTE_UNUSED;
844 Elf_Internal_Rela * rel;
845 struct elf_link_hash_entry * h;
846 Elf_Internal_Sym * sym;
847{
848 if (h != NULL)
849 {
850 switch (ELF32_R_TYPE (rel->r_info))
851 {
852 case R_FRV_GNU_VTINHERIT:
853 case R_FRV_GNU_VTENTRY:
854 break;
855
856 default:
857 switch (h->root.type)
858 {
859 default:
860 break;
861
862 case bfd_link_hash_defined:
863 case bfd_link_hash_defweak:
864 return h->root.u.def.section;
865
866 case bfd_link_hash_common:
867 return h->root.u.c.p->section;
868 }
869 }
870 }
871 else
872 {
873 if (!(elf_bad_symtab (abfd)
874 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
875 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
876 && sym->st_shndx != SHN_COMMON))
877 return bfd_section_from_elf_index (abfd, sym->st_shndx);
878 }
879
880 return NULL;
881}
882
883/* Update the got entry reference counts for the section being removed. */
884
885static boolean
886elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
887 bfd * abfd ATTRIBUTE_UNUSED;
888 struct bfd_link_info * info ATTRIBUTE_UNUSED;
889 asection * sec ATTRIBUTE_UNUSED;
890 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
891{
892 return true;
893}
894
895\f
896/* Hook called by the linker routine which adds symbols from an object
897 file. We use it to put .comm items in .scomm, and not .comm. */
898
899static boolean
900elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
901 bfd *abfd;
902 struct bfd_link_info *info;
903 const Elf_Internal_Sym *sym;
904 const char **namep ATTRIBUTE_UNUSED;
905 flagword *flagsp ATTRIBUTE_UNUSED;
906 asection **secp;
907 bfd_vma *valp;
908{
909 if (sym->st_shndx == SHN_COMMON
910 && !info->relocateable
911 && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
912 {
913 /* Common symbols less than or equal to -G nn bytes are
914 automatically put into .sbss. */
915
916 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
917
918 if (scomm == NULL)
919 {
920 scomm = bfd_make_section (abfd, ".scommon");
921 if (scomm == NULL
922 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
923 | SEC_IS_COMMON
924 | SEC_LINKER_CREATED)))
925 return false;
926 }
927
928 *secp = scomm;
929 *valp = sym->st_size;
930 }
931
932 return true;
933}
934/* Look through the relocs for a section during the first phase.
935 Since we don't do .gots or .plts, we just need to consider the
936 virtual table relocs for gc. */
937
938static boolean
939elf32_frv_check_relocs (abfd, info, sec, relocs)
940 bfd *abfd;
941 struct bfd_link_info *info;
942 asection *sec;
943 const Elf_Internal_Rela *relocs;
944{
945 Elf_Internal_Shdr *symtab_hdr;
946 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
947 const Elf_Internal_Rela *rel;
948 const Elf_Internal_Rela *rel_end;
949
950 if (info->relocateable)
951 return true;
952
953 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
954 sym_hashes = elf_sym_hashes (abfd);
955 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
956 if (!elf_bad_symtab (abfd))
957 sym_hashes_end -= symtab_hdr->sh_info;
958
959 rel_end = relocs + sec->reloc_count;
960 for (rel = relocs; rel < rel_end; rel++)
961 {
962 struct elf_link_hash_entry *h;
963 unsigned long r_symndx;
964
965 r_symndx = ELF32_R_SYM (rel->r_info);
966 if (r_symndx < symtab_hdr->sh_info)
967 h = NULL;
968 else
969 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
970
971 switch (ELF32_R_TYPE (rel->r_info))
972 {
973 /* This relocation describes the C++ object vtable hierarchy.
974 Reconstruct it for later use during GC. */
975 case R_FRV_GNU_VTINHERIT:
976 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
977 return false;
978 break;
979
980 /* This relocation describes which C++ vtable entries are actually
981 used. Record for later use during GC. */
982 case R_FRV_GNU_VTENTRY:
983 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
984 return false;
985 break;
986 }
987 }
988
989 return true;
990}
991
992\f
993/* Return the machine subcode from the ELF e_flags header. */
994
995static int
996elf32_frv_machine (abfd)
997 bfd *abfd;
998{
999 switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
1000 {
1001 default: break;
1002 case EF_FRV_CPU_FR500: return bfd_mach_fr500;
1003 case EF_FRV_CPU_FR400: return bfd_mach_fr400;
1004 case EF_FRV_CPU_FR300: return bfd_mach_fr300;
1005 case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
1006 case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
1007 }
1008
1009 return bfd_mach_frv;
1010}
1011
1012/* Set the right machine number for a FRV ELF file. */
1013
1014static boolean
1015elf32_frv_object_p (abfd)
1016 bfd *abfd;
1017{
1018 bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
1019 return true;
1020}
1021\f
1022/* Function to set the ELF flag bits. */
1023
1024static boolean
1025frv_elf_set_private_flags (abfd, flags)
1026 bfd *abfd;
1027 flagword flags;
1028{
1029 elf_elfheader (abfd)->e_flags = flags;
1030 elf_flags_init (abfd) = true;
1031 return true;
1032}
1033
1034/* Copy backend specific data from one object module to another. */
1035
1036static boolean
1037frv_elf_copy_private_bfd_data (ibfd, obfd)
1038 bfd *ibfd;
1039 bfd *obfd;
1040{
1041 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1042 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1043 return true;
1044
1045 BFD_ASSERT (!elf_flags_init (obfd)
1046 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
1047
1048 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1049 elf_flags_init (obfd) = true;
1050 return true;
1051}
1052
1053/* Merge backend specific data from an object file to the output
1054 object file when linking. */
1055
1056static boolean
1057frv_elf_merge_private_bfd_data (ibfd, obfd)
1058 bfd *ibfd;
1059 bfd *obfd;
1060{
1061 flagword old_flags, old_partial;
1062 flagword new_flags, new_partial;
1063 boolean error = false;
1064 char new_opt[80];
1065 char old_opt[80];
1066
1067 new_opt[0] = old_opt[0] = '\0';
1068 new_flags = elf_elfheader (ibfd)->e_flags;
1069 old_flags = elf_elfheader (obfd)->e_flags;
1070
1071#ifdef DEBUG
1072 (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
1073 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
1074 bfd_get_filename (ibfd));
1075#endif
1076
1077 if (!elf_flags_init (obfd)) /* First call, no flags set. */
1078 {
1079 elf_flags_init (obfd) = true;
1080 old_flags = new_flags;
1081 }
1082
1083 else if (new_flags == old_flags) /* Compatible flags are ok. */
1084 ;
1085
1086 else /* Possibly incompatible flags. */
1087 {
1088 /* Warn if different # of gprs are used. Note, 0 means nothing is
1089 said about the size of gprs. */
1090 new_partial = (new_flags & EF_FRV_GPR_MASK);
1091 old_partial = (old_flags & EF_FRV_GPR_MASK);
1092 if (new_partial == old_partial)
1093 ;
1094
1095 else if (new_partial == 0)
1096 ;
1097
1098 else if (old_partial == 0)
1099 old_flags |= new_partial;
1100
1101 else
1102 {
1103 switch (new_partial)
1104 {
1105 default: strcat (new_opt, " -mgpr-??"); break;
1106 case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
1107 case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
1108 }
1109
1110 switch (old_partial)
1111 {
1112 default: strcat (old_opt, " -mgpr-??"); break;
1113 case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
1114 case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
1115 }
1116 }
1117
1118 /* Warn if different # of fprs are used. Note, 0 means nothing is
1119 said about the size of fprs. */
1120 new_partial = (new_flags & EF_FRV_FPR_MASK);
1121 old_partial = (old_flags & EF_FRV_FPR_MASK);
1122 if (new_partial == old_partial)
1123 ;
1124
1125 else if (new_partial == 0)
1126 ;
1127
1128 else if (old_partial == 0)
1129 old_flags |= new_partial;
1130
1131 else
1132 {
1133 switch (new_partial)
1134 {
1135 default: strcat (new_opt, " -mfpr-?"); break;
1136 case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break;
1137 case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break;
1138 case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
1139 }
1140
1141 switch (old_partial)
1142 {
1143 default: strcat (old_opt, " -mfpr-?"); break;
1144 case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break;
1145 case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break;
1146 case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
1147 }
1148 }
1149
1150 /* Warn if different dword support was used. Note, 0 means nothing is
1151 said about the dword support. */
1152 new_partial = (new_flags & EF_FRV_DWORD_MASK);
1153 old_partial = (old_flags & EF_FRV_DWORD_MASK);
1154 if (new_partial == old_partial)
1155 ;
1156
1157 else if (new_partial == 0)
1158 ;
1159
1160 else if (old_partial == 0)
1161 old_flags |= new_partial;
1162
1163 else
1164 {
1165 switch (new_partial)
1166 {
1167 default: strcat (new_opt, " -mdword-?"); break;
1168 case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break;
1169 case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break;
1170 }
1171
1172 switch (old_partial)
1173 {
1174 default: strcat (old_opt, " -mdword-?"); break;
1175 case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break;
1176 case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break;
1177 }
1178 }
1179
1180 /* Or in flags that accumulate (ie, if one module uses it, mark that the
1181 feature is used. */
1182 old_flags |= new_flags & (EF_FRV_DOUBLE
1183 | EF_FRV_MEDIA
1184 | EF_FRV_MULADD
1185 | EF_FRV_NON_PIC_RELOCS);
1186
1187 /* If any module was compiled without -G0, clear the G0 bit. */
1188 old_flags = ((old_flags & ~ EF_FRV_G0)
1189 | (old_flags & new_flags & EF_FRV_G0));
1190
1191 /* If any module was compiled without -mnopack, clear the mnopack bit. */
1192 old_flags = ((old_flags & ~ EF_FRV_NOPACK)
1193 | (old_flags & new_flags & EF_FRV_NOPACK));
1194
1195 /* We don't have to do anything if the pic flags are the same, or the new
1196 module(s) were compiled with -mlibrary-pic. */
1197 new_partial = (new_flags & EF_FRV_PIC_FLAGS);
1198 old_partial = (old_flags & EF_FRV_PIC_FLAGS);
1199 if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
1200 ;
1201
1202 /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
1203 flags if any from the new module. */
1204 else if ((old_partial & EF_FRV_LIBPIC) != 0)
1205 old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
1206
1207 /* If we have mixtures of -fpic and -fPIC, or in both bits. */
1208 else if (new_partial != 0 && old_partial != 0)
1209 old_flags |= new_partial;
1210
1211 /* One module was compiled for pic and the other was not, see if we have
1212 had any relocations that are not pic-safe. */
1213 else
1214 {
1215 if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
1216 old_flags |= new_partial;
1217 else
1218 {
1219 old_flags &= ~ EF_FRV_PIC_FLAGS;
1220#ifndef FRV_NO_PIC_ERROR
1221 error = true;
1222 (*_bfd_error_handler)
1223 (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
1224 bfd_get_filename (ibfd),
1225 (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
1226#endif
1227 }
1228 }
1229
1230 /* Warn if different cpu is used (allow a specific cpu to override
1231 the generic cpu). */
1232 new_partial = (new_flags & EF_FRV_CPU_MASK);
1233 old_partial = (old_flags & EF_FRV_CPU_MASK);
1234 if (new_partial == old_partial)
1235 ;
1236
1237 else if (new_partial == EF_FRV_CPU_GENERIC)
1238 ;
1239
1240 else if (old_partial == EF_FRV_CPU_GENERIC)
1241 old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
1242
1243 else
1244 {
1245 switch (new_partial)
1246 {
1247 default: strcat (new_opt, " -mcpu=?"); break;
1248 case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break;
1249 case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
1250 case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
1251 case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
1252 case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
1253 case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
1254 }
1255
1256 switch (old_partial)
1257 {
1258 default: strcat (old_opt, " -mcpu=?"); break;
1259 case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break;
1260 case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
1261 case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
1262 case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
1263 case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
1264 case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
1265 }
1266 }
1267
1268 /* Print out any mismatches from above. */
1269 if (new_opt[0])
1270 {
1271 error = true;
1272 (*_bfd_error_handler)
1273 (_("%s: compiled with %s and linked with modules compiled with %s"),
1274 bfd_get_filename (ibfd), new_opt, old_opt);
1275 }
1276
1277 /* Warn about any other mismatches */
1278 new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
1279 old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
1280 if (new_partial != old_partial)
1281 {
1282 old_flags |= new_partial;
1283 error = true;
1284 (*_bfd_error_handler)
1285 (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
1286 bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
1287 }
1288 }
1289
1290 /* If the cpu is -mcpu=simple, then set the -mnopack bit. */
1291 if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
1292 old_flags |= EF_FRV_NOPACK;
1293
1294 /* Update the old flags now with changes made above. */
1295 old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
1296 elf_elfheader (obfd)->e_flags = old_flags;
1297 if (old_partial != (old_flags & EF_FRV_CPU_MASK))
1298 bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
1299
1300 if (error)
1301 bfd_set_error (bfd_error_bad_value);
1302
1303 return !error;
1304}
1305
1306\f
1307boolean
1308frv_elf_print_private_bfd_data (abfd, ptr)
1309 bfd *abfd;
1310 PTR ptr;
1311{
1312 FILE *file = (FILE *) ptr;
1313 flagword flags;
1314
1315 BFD_ASSERT (abfd != NULL && ptr != NULL);
1316
1317 /* Print normal ELF private data. */
1318 _bfd_elf_print_private_bfd_data (abfd, ptr);
1319
1320 flags = elf_elfheader (abfd)->e_flags;
1321 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
1322
1323 switch (flags & EF_FRV_CPU_MASK)
1324 {
1325 default: break;
1326 case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
1327 case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
1328 case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
1329 case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
1330 case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
1331 }
1332
1333 switch (flags & EF_FRV_GPR_MASK)
1334 {
1335 default: break;
1336 case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break;
1337 case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break;
1338 }
1339
1340 switch (flags & EF_FRV_FPR_MASK)
1341 {
1342 default: break;
1343 case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break;
1344 case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break;
1345 case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break;
1346 }
1347
1348 switch (flags & EF_FRV_DWORD_MASK)
1349 {
1350 default: break;
1351 case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break;
1352 case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break;
1353 }
1354
1355 if (flags & EF_FRV_DOUBLE)
1356 fprintf (file, " -mdouble");
1357
1358 if (flags & EF_FRV_MEDIA)
1359 fprintf (file, " -mmedia");
1360
1361 if (flags & EF_FRV_MULADD)
1362 fprintf (file, " -mmuladd");
1363
1364 if (flags & EF_FRV_PIC)
1365 fprintf (file, " -fpic");
1366
1367 if (flags & EF_FRV_BIGPIC)
1368 fprintf (file, " -fPIC");
1369
1370 if (flags & EF_FRV_NON_PIC_RELOCS)
1371 fprintf (file, " non-pic relocations");
1372
1373 if (flags & EF_FRV_G0)
1374 fprintf (file, " -G0");
1375
1376 fputc ('\n', file);
1377 return true;
1378}
1379
1380\f
1381#define ELF_ARCH bfd_arch_frv
1382#define ELF_MACHINE_CODE EM_CYGNUS_FRV
1383#define ELF_MAXPAGESIZE 0x1000
1384
1385#define TARGET_BIG_SYM bfd_elf32_frv_vec
1386#define TARGET_BIG_NAME "elf32-frv"
1387
1388#define elf_info_to_howto_rel NULL
1389#define elf_info_to_howto frv_info_to_howto_rela
1390#define elf_backend_relocate_section elf32_frv_relocate_section
1391#define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook
1392#define elf_backend_gc_sweep_hook elf32_frv_gc_sweep_hook
1393#define elf_backend_check_relocs elf32_frv_check_relocs
1394#define elf_backend_object_p elf32_frv_object_p
1395#define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook
1396
1397#define elf_backend_can_gc_sections 1
1398
1399#define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup
1400#define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags
1401#define bfd_elf32_bfd_copy_private_bfd_data frv_elf_copy_private_bfd_data
1402#define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data
1403#define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data
1404
1405#include "elf32-target.h"
This page took 0.071746 seconds and 4 git commands to generate.