source: trunk/src/binutils/bfd/elf32-frv.c@ 2013

Last change on this file since 2013 was 607, checked in by bird, 22 years ago

Initial revision

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