1
/* FRV-specific support for 32-bit ELF.
2
Copyright (C) 2002 Free Software Foundation, Inc.
4
This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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));
64
static reloc_howto_type elf32_frv_howto_table [] =
66
/* This reloc does nothing. */
67
HOWTO (R_FRV_NONE, /* type */
69
2, /* size (0 = byte, 1 = short, 2 = long) */
71
false, /* pc_relative */
73
complain_overflow_bitfield, /* complain_on_overflow */
74
bfd_elf_generic_reloc, /* special_function */
75
"R_FRV_NONE", /* name */
76
false, /* partial_inplace */
79
false), /* pcrel_offset */
81
/* A 32 bit absolute relocation. */
82
HOWTO (R_FRV_32, /* type */
84
2, /* size (0 = byte, 1 = short, 2 = long) */
86
false, /* pc_relative */
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 */
96
/* A 16 bit pc-relative relocation. */
97
HOWTO (R_FRV_LABEL16, /* type */
99
2, /* size (0 = byte, 1 = short, 2 = long) */
101
true, /* pc_relative */
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 */
111
/* A 24-bit pc-relative relocation. */
112
HOWTO (R_FRV_LABEL24, /* type */
114
2, /* size (0 = byte, 1 = short, 2 = long) */
116
true, /* pc_relative */
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 */
126
HOWTO (R_FRV_LO16, /* type */
128
2, /* size (0 = byte, 1 = short, 2 = long) */
130
false, /* pc_relative */
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 */
140
HOWTO (R_FRV_HI16, /* type */
142
2, /* size (0 = byte, 1 = short, 2 = long) */
144
false, /* pc_relative */
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 */
154
HOWTO (R_FRV_GPREL12, /* type */
156
2, /* size (0 = byte, 1 = short, 2 = long) */
158
false, /* pc_relative */
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 */
168
HOWTO (R_FRV_GPRELU12, /* type */
170
2, /* size (0 = byte, 1 = short, 2 = long) */
172
false, /* pc_relative */
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 */
182
HOWTO (R_FRV_GPREL32, /* type */
184
2, /* size (0 = byte, 1 = short, 2 = long) */
186
false, /* pc_relative */
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 */
196
HOWTO (R_FRV_GPRELHI, /* type */
198
2, /* size (0 = byte, 1 = short, 2 = long) */
200
false, /* pc_relative */
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 */
210
HOWTO (R_FRV_GPRELLO, /* type */
212
2, /* size (0 = byte, 1 = short, 2 = long) */
214
false, /* pc_relative */
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 */
225
/* GNU extension to record C++ vtable hierarchy. */
226
static reloc_howto_type elf32_frv_vtinherit_howto =
227
HOWTO (R_FRV_GNU_VTINHERIT, /* type */
229
2, /* size (0 = byte, 1 = short, 2 = long) */
231
false, /* pc_relative */
233
complain_overflow_dont, /* complain_on_overflow */
234
NULL, /* special_function */
235
"R_FRV_GNU_VTINHERIT", /* name */
236
false, /* partial_inplace */
239
false); /* pcrel_offset */
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 */
245
2, /* size (0 = byte, 1 = short, 2 = long) */
247
false, /* pc_relative */
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 */
255
false); /* pcrel_offset */
257
/* Map BFD reloc types to FRV ELF reloc types. */
261
unsigned int bfd_reloc_val;
262
unsigned int frv_reloc_val;
265
static const struct frv_reloc_map frv_reloc_map [] =
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 },
283
/* Handle an FRV small data reloc. */
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;
289
asection *input_section;
290
Elf_Internal_Rela *relocation;
296
struct bfd_link_hash_entry *h;
298
h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
301
+ h->u.def.section->output_section->vma
302
+ h->u.def.section->output_offset);
304
value -= input_section->output_section->vma;
305
value -= (gp - input_section->output_section->vma);
307
insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
309
value += relocation->r_addend;
311
if ((long) value > 0x7ff || (long) value < -0x800)
312
return bfd_reloc_overflow;
314
bfd_put_32 (input_bfd,
315
(insn & 0xfffff000) | (value & 0xfff),
316
contents + relocation->r_offset);
321
/* Handle an FRV small data reloc. for the u12 field. */
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;
327
asection *input_section;
328
Elf_Internal_Rela *relocation;
334
struct bfd_link_hash_entry *h;
337
h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
340
+ h->u.def.section->output_section->vma
341
+ h->u.def.section->output_offset);
343
value -= input_section->output_section->vma;
344
value -= (gp - input_section->output_section->vma);
346
insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
348
value += relocation->r_addend;
350
if ((long) value > 0x7ff || (long) value < -0x800)
351
return bfd_reloc_overflow;
353
/* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0. */
355
insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
357
bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
362
/* Handle an FRV ELF HI16 reloc. */
364
static bfd_reloc_status_type
365
elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
367
Elf_Internal_Rela *relhi;
373
insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
375
value += relhi->r_addend;
376
value = ((value >> 16) & 0xffff);
378
insn = (insn & 0xffff0000) | value;
380
if ((long) value > 0xffff || (long) value < -0x10000)
381
return bfd_reloc_overflow;
383
bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
387
static bfd_reloc_status_type
388
elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
390
Elf_Internal_Rela *rello;
396
insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
398
value += rello->r_addend;
399
value = value & 0xffff;
401
insn = (insn & 0xffff0000) | value;
403
if ((long) value > 0xffff || (long) value < -0x10000)
404
return bfd_reloc_overflow;
406
bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
410
/* Perform the relocation for the CALL label24 instruction. */
412
static bfd_reloc_status_type
413
elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
415
asection *input_section;
416
Elf_Internal_Rela *rello;
424
/* The format for the call instruction is:
426
0 000000 0001111 000000000000000000
427
label6 opcode label18
429
The branch calculation is: pc + (4*label24)
430
where label24 is the concatenation of label6 and label18. */
432
/* Grab the instruction. */
433
insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
435
value -= input_section->output_section->vma + input_section->output_offset;
436
value -= rello->r_offset;
437
value += rello->r_addend;
441
label6 = value & 0xfc0000;
442
label6 = label6 << 7;
444
label18 = value & 0x3ffff;
446
insn = insn & 0x803c0000;
447
insn = insn | label6;
448
insn = insn | label18;
450
bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
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;
459
asection *input_section;
460
Elf_Internal_Rela *relocation;
466
struct bfd_link_hash_entry *h;
468
h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
471
+ h->u.def.section->output_section->vma
472
+ h->u.def.section->output_offset);
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);
479
if ((long) value > 0xffff || (long) value < -0x10000)
480
return bfd_reloc_overflow;
482
insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
483
insn = (insn & 0xffff0000) | value;
485
bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
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;
493
asection *input_section;
494
Elf_Internal_Rela *relocation;
500
struct bfd_link_hash_entry *h;
502
h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
505
+ h->u.def.section->output_section->vma
506
+ h->u.def.section->output_offset);
508
value -= input_section->output_section->vma;
509
value -= (gp - input_section->output_section->vma);
510
value += relocation->r_addend;
511
value = value & 0xffff;
513
if ((long) value > 0xffff || (long) value < -0x10000)
514
return bfd_reloc_overflow;
516
insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
517
insn = (insn & 0xffff0000) | value;
519
bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
524
static reloc_howto_type *
525
frv_reloc_type_lookup (abfd, code)
526
bfd * abfd ATTRIBUTE_UNUSED;
527
bfd_reloc_code_real_type code;
535
return &elf32_frv_howto_table[ (int) R_FRV_NONE];
539
return &elf32_frv_howto_table[ (int) R_FRV_32];
541
case BFD_RELOC_FRV_LABEL16:
542
return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
544
case BFD_RELOC_FRV_LABEL24:
545
return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
547
case BFD_RELOC_FRV_LO16:
548
return &elf32_frv_howto_table[ (int) R_FRV_LO16];
550
case BFD_RELOC_FRV_HI16:
551
return &elf32_frv_howto_table[ (int) R_FRV_HI16];
553
case BFD_RELOC_FRV_GPREL12:
554
return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
556
case BFD_RELOC_FRV_GPRELU12:
557
return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
559
case BFD_RELOC_FRV_GPREL32:
560
return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
562
case BFD_RELOC_FRV_GPRELHI:
563
return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
565
case BFD_RELOC_FRV_GPRELLO:
566
return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
568
case BFD_RELOC_VTABLE_INHERIT:
569
return &elf32_frv_vtinherit_howto;
571
case BFD_RELOC_VTABLE_ENTRY:
572
return &elf32_frv_vtentry_howto;
578
/* Set the howto pointer for an FRV ELF reloc. */
581
frv_info_to_howto_rela (abfd, cache_ptr, dst)
582
bfd * abfd ATTRIBUTE_UNUSED;
584
Elf32_Internal_Rela * dst;
588
r_type = ELF32_R_TYPE (dst->r_info);
591
case R_FRV_GNU_VTINHERIT:
592
cache_ptr->howto = &elf32_frv_vtinherit_howto;
595
case R_FRV_GNU_VTENTRY:
596
cache_ptr->howto = &elf32_frv_vtentry_howto;
600
cache_ptr->howto = & elf32_frv_howto_table [r_type];
605
/* Perform a single relocation. By default we use the standard BFD
606
routines, but a few relocs, we have to do them ourselves. */
608
static bfd_reloc_status_type
609
frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
610
reloc_howto_type * howto;
612
asection * input_section;
614
Elf_Internal_Rela * rel;
617
return _bfd_final_link_relocate (howto, input_bfd, input_section,
618
contents, rel->r_offset, relocation,
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.
628
The RELOCATE_SECTION function is called by the new ELF backend linker
629
to handle the relocations for a section.
631
The relocs are always passed as Rela structures; if the section
632
actually uses Rel structures, the r_addend field will always be
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.
639
This function does not have to worry about setting the reloc
640
address or the reloc symbol index.
642
LOCAL_SYMS is a pointer to the swapped in local symbols.
644
LOCAL_SECTIONS is an array giving the section in the input file
645
corresponding to the st_shndx field of each local symbol.
647
The global hash table entry for the global symbols can be found
648
via elf_sym_hashes (input_bfd).
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
657
elf32_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;
662
asection * input_section;
664
Elf_Internal_Rela * relocs;
665
Elf_Internal_Sym * local_syms;
666
asection ** local_sections;
668
Elf_Internal_Shdr * symtab_hdr;
669
struct elf_link_hash_entry ** sym_hashes;
670
Elf_Internal_Rela * rel;
671
Elf_Internal_Rela * relend;
673
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
674
sym_hashes = elf_sym_hashes (input_bfd);
675
relend = relocs + input_section->reloc_count;
677
for (rel = relocs; rel < relend; rel ++)
679
reloc_howto_type * howto;
680
unsigned long r_symndx;
681
Elf_Internal_Sym * sym;
683
struct elf_link_hash_entry * h;
685
bfd_reloc_status_type r;
686
const char * name = NULL;
689
r_type = ELF32_R_TYPE (rel->r_info);
691
if ( r_type == R_FRV_GNU_VTINHERIT
692
|| r_type == R_FRV_GNU_VTENTRY)
695
r_symndx = ELF32_R_SYM (rel->r_info);
697
if (info->relocateable)
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)
705
sym = local_syms + r_symndx;
707
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
709
sec = local_sections [r_symndx];
710
rel->r_addend += sec->output_offset + sym->st_value;
717
/* This is a final link. */
718
howto = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
723
if (r_symndx < symtab_hdr->sh_info)
725
sym = local_syms + r_symndx;
726
sec = local_sections [r_symndx];
727
relocation = (sec->output_section->vma
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;
737
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
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;
743
name = h->root.root.string;
745
if (h->root.type == bfd_link_hash_defined
746
|| h->root.type == bfd_link_hash_defweak)
748
sec = h->root.u.def.section;
749
relocation = (h->root.u.def.value
750
+ sec->output_section->vma
751
+ sec->output_offset);
753
else if (h->root.type == bfd_link_hash_undefweak)
759
if (! ((*info->callbacks->undefined_symbol)
760
(info, h->root.root.string, input_bfd,
761
input_section, rel->r_offset, true)))
767
if (r_type == R_FRV_HI16)
768
r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
770
else if (r_type == R_FRV_LO16)
771
r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
773
else if (r_type == R_FRV_LABEL24)
774
r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
776
else if (r_type == R_FRV_GPREL12)
777
r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
779
else if (r_type == R_FRV_GPRELU12)
780
r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
782
else if (r_type == R_FRV_GPRELLO)
783
r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
785
else if (r_type == R_FRV_GPRELHI)
786
r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
789
r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
791
if (r != bfd_reloc_ok)
793
const char * msg = (const char *) NULL;
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);
803
case bfd_reloc_undefined:
804
r = info->callbacks->undefined_symbol
805
(info, name, input_bfd, input_section, rel->r_offset, true);
808
case bfd_reloc_outofrange:
809
msg = _("internal error: out of range error");
812
case bfd_reloc_notsupported:
813
msg = _("internal error: unsupported relocation error");
816
case bfd_reloc_dangerous:
817
msg = _("internal error: dangerous relocation");
821
msg = _("internal error: unknown error");
826
r = info->callbacks->warning
827
(info, msg, name, input_bfd, input_section, rel->r_offset);
837
/* Return the section that should be marked against GC for a given
841
elf32_frv_gc_mark_hook (sec, info, rel, h, sym)
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;
850
switch (ELF32_R_TYPE (rel->r_info))
852
case R_FRV_GNU_VTINHERIT:
853
case R_FRV_GNU_VTENTRY:
857
switch (h->root.type)
862
case bfd_link_hash_defined:
863
case bfd_link_hash_defweak:
864
return h->root.u.def.section;
866
case bfd_link_hash_common:
867
return h->root.u.c.p->section;
872
return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
877
/* Update the got entry reference counts for the section being removed. */
880
elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
881
bfd * abfd ATTRIBUTE_UNUSED;
882
struct bfd_link_info * info ATTRIBUTE_UNUSED;
883
asection * sec ATTRIBUTE_UNUSED;
884
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
890
/* Hook called by the linker routine which adds symbols from an object
891
file. We use it to put .comm items in .scomm, and not .comm. */
894
elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
896
struct bfd_link_info *info;
897
const Elf_Internal_Sym *sym;
898
const char **namep ATTRIBUTE_UNUSED;
899
flagword *flagsp ATTRIBUTE_UNUSED;
903
if (sym->st_shndx == SHN_COMMON
904
&& !info->relocateable
905
&& (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
907
/* Common symbols less than or equal to -G nn bytes are
908
automatically put into .sbss. */
910
asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
914
scomm = bfd_make_section (abfd, ".scommon");
916
|| !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
918
| SEC_LINKER_CREATED)))
923
*valp = sym->st_size;
928
/* Look through the relocs for a section during the first phase.
929
Since we don't do .gots or .plts, we just need to consider the
930
virtual table relocs for gc. */
933
elf32_frv_check_relocs (abfd, info, sec, relocs)
935
struct bfd_link_info *info;
937
const Elf_Internal_Rela *relocs;
939
Elf_Internal_Shdr *symtab_hdr;
940
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
941
const Elf_Internal_Rela *rel;
942
const Elf_Internal_Rela *rel_end;
944
if (info->relocateable)
947
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
948
sym_hashes = elf_sym_hashes (abfd);
949
sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
950
if (!elf_bad_symtab (abfd))
951
sym_hashes_end -= symtab_hdr->sh_info;
953
rel_end = relocs + sec->reloc_count;
954
for (rel = relocs; rel < rel_end; rel++)
956
struct elf_link_hash_entry *h;
957
unsigned long r_symndx;
959
r_symndx = ELF32_R_SYM (rel->r_info);
960
if (r_symndx < symtab_hdr->sh_info)
963
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
965
switch (ELF32_R_TYPE (rel->r_info))
967
/* This relocation describes the C++ object vtable hierarchy.
968
Reconstruct it for later use during GC. */
969
case R_FRV_GNU_VTINHERIT:
970
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
974
/* This relocation describes which C++ vtable entries are actually
975
used. Record for later use during GC. */
976
case R_FRV_GNU_VTENTRY:
977
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
987
/* Return the machine subcode from the ELF e_flags header. */
990
elf32_frv_machine (abfd)
993
switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
996
case EF_FRV_CPU_FR500: return bfd_mach_fr500;
997
case EF_FRV_CPU_FR400: return bfd_mach_fr400;
998
case EF_FRV_CPU_FR300: return bfd_mach_fr300;
999
case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
1000
case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
1003
return bfd_mach_frv;
1006
/* Set the right machine number for a FRV ELF file. */
1009
elf32_frv_object_p (abfd)
1012
bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
1016
/* Function to set the ELF flag bits. */
1019
frv_elf_set_private_flags (abfd, flags)
1023
elf_elfheader (abfd)->e_flags = flags;
1024
elf_flags_init (abfd) = true;
1028
/* Copy backend specific data from one object module to another. */
1031
frv_elf_copy_private_bfd_data (ibfd, obfd)
1035
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1036
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1039
BFD_ASSERT (!elf_flags_init (obfd)
1040
|| elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
1042
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1043
elf_flags_init (obfd) = true;
1047
/* Merge backend specific data from an object file to the output
1048
object file when linking. */
1051
frv_elf_merge_private_bfd_data (ibfd, obfd)
1055
flagword old_flags, old_partial;
1056
flagword new_flags, new_partial;
1057
boolean error = false;
1061
new_opt[0] = old_opt[0] = '\0';
1062
new_flags = elf_elfheader (ibfd)->e_flags;
1063
old_flags = elf_elfheader (obfd)->e_flags;
1066
(*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
1067
old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
1068
bfd_get_filename (ibfd));
1071
if (!elf_flags_init (obfd)) /* First call, no flags set. */
1073
elf_flags_init (obfd) = true;
1074
old_flags = new_flags;
1077
else if (new_flags == old_flags) /* Compatible flags are ok. */
1080
else /* Possibly incompatible flags. */
1082
/* Warn if different # of gprs are used. Note, 0 means nothing is
1083
said about the size of gprs. */
1084
new_partial = (new_flags & EF_FRV_GPR_MASK);
1085
old_partial = (old_flags & EF_FRV_GPR_MASK);
1086
if (new_partial == old_partial)
1089
else if (new_partial == 0)
1092
else if (old_partial == 0)
1093
old_flags |= new_partial;
1097
switch (new_partial)
1099
default: strcat (new_opt, " -mgpr-??"); break;
1100
case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
1101
case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
1104
switch (old_partial)
1106
default: strcat (old_opt, " -mgpr-??"); break;
1107
case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
1108
case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
1112
/* Warn if different # of fprs are used. Note, 0 means nothing is
1113
said about the size of fprs. */
1114
new_partial = (new_flags & EF_FRV_FPR_MASK);
1115
old_partial = (old_flags & EF_FRV_FPR_MASK);
1116
if (new_partial == old_partial)
1119
else if (new_partial == 0)
1122
else if (old_partial == 0)
1123
old_flags |= new_partial;
1127
switch (new_partial)
1129
default: strcat (new_opt, " -mfpr-?"); break;
1130
case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break;
1131
case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break;
1132
case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
1135
switch (old_partial)
1137
default: strcat (old_opt, " -mfpr-?"); break;
1138
case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break;
1139
case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break;
1140
case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
1144
/* Warn if different dword support was used. Note, 0 means nothing is
1145
said about the dword support. */
1146
new_partial = (new_flags & EF_FRV_DWORD_MASK);
1147
old_partial = (old_flags & EF_FRV_DWORD_MASK);
1148
if (new_partial == old_partial)
1151
else if (new_partial == 0)
1154
else if (old_partial == 0)
1155
old_flags |= new_partial;
1159
switch (new_partial)
1161
default: strcat (new_opt, " -mdword-?"); break;
1162
case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break;
1163
case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break;
1166
switch (old_partial)
1168
default: strcat (old_opt, " -mdword-?"); break;
1169
case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break;
1170
case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break;
1174
/* Or in flags that accumulate (ie, if one module uses it, mark that the
1176
old_flags |= new_flags & (EF_FRV_DOUBLE
1179
| EF_FRV_NON_PIC_RELOCS);
1181
/* If any module was compiled without -G0, clear the G0 bit. */
1182
old_flags = ((old_flags & ~ EF_FRV_G0)
1183
| (old_flags & new_flags & EF_FRV_G0));
1185
/* If any module was compiled without -mnopack, clear the mnopack bit. */
1186
old_flags = ((old_flags & ~ EF_FRV_NOPACK)
1187
| (old_flags & new_flags & EF_FRV_NOPACK));
1189
/* We don't have to do anything if the pic flags are the same, or the new
1190
module(s) were compiled with -mlibrary-pic. */
1191
new_partial = (new_flags & EF_FRV_PIC_FLAGS);
1192
old_partial = (old_flags & EF_FRV_PIC_FLAGS);
1193
if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
1196
/* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
1197
flags if any from the new module. */
1198
else if ((old_partial & EF_FRV_LIBPIC) != 0)
1199
old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
1201
/* If we have mixtures of -fpic and -fPIC, or in both bits. */
1202
else if (new_partial != 0 && old_partial != 0)
1203
old_flags |= new_partial;
1205
/* One module was compiled for pic and the other was not, see if we have
1206
had any relocations that are not pic-safe. */
1209
if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
1210
old_flags |= new_partial;
1213
old_flags &= ~ EF_FRV_PIC_FLAGS;
1214
#ifndef FRV_NO_PIC_ERROR
1216
(*_bfd_error_handler)
1217
(_("%s: compiled with %s and linked with modules that use non-pic relocations"),
1218
bfd_get_filename (ibfd),
1219
(new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
1224
/* Warn if different cpu is used (allow a specific cpu to override
1225
the generic cpu). */
1226
new_partial = (new_flags & EF_FRV_CPU_MASK);
1227
old_partial = (old_flags & EF_FRV_CPU_MASK);
1228
if (new_partial == old_partial)
1231
else if (new_partial == EF_FRV_CPU_GENERIC)
1234
else if (old_partial == EF_FRV_CPU_GENERIC)
1235
old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
1239
switch (new_partial)
1241
default: strcat (new_opt, " -mcpu=?"); break;
1242
case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break;
1243
case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
1244
case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
1245
case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
1246
case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
1247
case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
1250
switch (old_partial)
1252
default: strcat (old_opt, " -mcpu=?"); break;
1253
case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break;
1254
case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
1255
case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
1256
case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
1257
case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
1258
case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
1262
/* Print out any mismatches from above. */
1266
(*_bfd_error_handler)
1267
(_("%s: compiled with %s and linked with modules compiled with %s"),
1268
bfd_get_filename (ibfd), new_opt, old_opt);
1271
/* Warn about any other mismatches */
1272
new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
1273
old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
1274
if (new_partial != old_partial)
1276
old_flags |= new_partial;
1278
(*_bfd_error_handler)
1279
(_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
1280
bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
1284
/* If the cpu is -mcpu=simple, then set the -mnopack bit. */
1285
if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
1286
old_flags |= EF_FRV_NOPACK;
1288
/* Update the old flags now with changes made above. */
1289
old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
1290
elf_elfheader (obfd)->e_flags = old_flags;
1291
if (old_partial != (old_flags & EF_FRV_CPU_MASK))
1292
bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
1295
bfd_set_error (bfd_error_bad_value);
1302
frv_elf_print_private_bfd_data (abfd, ptr)
1306
FILE *file = (FILE *) ptr;
1309
BFD_ASSERT (abfd != NULL && ptr != NULL);
1311
/* Print normal ELF private data. */
1312
_bfd_elf_print_private_bfd_data (abfd, ptr);
1314
flags = elf_elfheader (abfd)->e_flags;
1315
fprintf (file, _("private flags = 0x%lx:"), (long)flags);
1317
switch (flags & EF_FRV_CPU_MASK)
1320
case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
1321
case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
1322
case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
1323
case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
1324
case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
1327
switch (flags & EF_FRV_GPR_MASK)
1330
case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break;
1331
case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break;
1334
switch (flags & EF_FRV_FPR_MASK)
1337
case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break;
1338
case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break;
1339
case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break;
1342
switch (flags & EF_FRV_DWORD_MASK)
1345
case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break;
1346
case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break;
1349
if (flags & EF_FRV_DOUBLE)
1350
fprintf (file, " -mdouble");
1352
if (flags & EF_FRV_MEDIA)
1353
fprintf (file, " -mmedia");
1355
if (flags & EF_FRV_MULADD)
1356
fprintf (file, " -mmuladd");
1358
if (flags & EF_FRV_PIC)
1359
fprintf (file, " -fpic");
1361
if (flags & EF_FRV_BIGPIC)
1362
fprintf (file, " -fPIC");
1364
if (flags & EF_FRV_NON_PIC_RELOCS)
1365
fprintf (file, " non-pic relocations");
1367
if (flags & EF_FRV_G0)
1368
fprintf (file, " -G0");
1375
#define ELF_ARCH bfd_arch_frv
1376
#define ELF_MACHINE_CODE EM_CYGNUS_FRV
1377
#define ELF_MAXPAGESIZE 0x1000
1379
#define TARGET_BIG_SYM bfd_elf32_frv_vec
1380
#define TARGET_BIG_NAME "elf32-frv"
1382
#define elf_info_to_howto_rel NULL
1383
#define elf_info_to_howto frv_info_to_howto_rela
1384
#define elf_backend_relocate_section elf32_frv_relocate_section
1385
#define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook
1386
#define elf_backend_gc_sweep_hook elf32_frv_gc_sweep_hook
1387
#define elf_backend_check_relocs elf32_frv_check_relocs
1388
#define elf_backend_object_p elf32_frv_object_p
1389
#define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook
1391
#define elf_backend_can_gc_sections 1
1393
#define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup
1394
#define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags
1395
#define bfd_elf32_bfd_copy_private_bfd_data frv_elf_copy_private_bfd_data
1396
#define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data
1397
#define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data
1399
#include "elf32-target.h"