1 |
/* Motorola MCore specific support for 32-bit ELF |
/* Motorola MCore specific support for 32-bit ELF |
2 |
Copyright 1994, 1995, 1999, 2000, 2001, 2002 |
Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004 |
3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
29 |
#include "elf/mcore.h" |
#include "elf/mcore.h" |
30 |
#include <assert.h> |
#include <assert.h> |
31 |
|
|
32 |
#define USE_RELA /* Only USE_REL is actually significant, but this is |
/* RELA relocs are used here... */ |
|
here are a reminder... */ |
|
33 |
|
|
34 |
static void mcore_elf_howto_init |
static void mcore_elf_howto_init |
35 |
PARAMS ((void)); |
PARAMS ((void)); |
36 |
static reloc_howto_type * mcore_elf_reloc_type_lookup |
static reloc_howto_type * mcore_elf_reloc_type_lookup |
37 |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
38 |
static void mcore_elf_info_to_howto |
static void mcore_elf_info_to_howto |
39 |
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
40 |
static boolean mcore_elf_set_private_flags |
static bfd_boolean mcore_elf_set_private_flags |
41 |
PARAMS ((bfd *, flagword)); |
PARAMS ((bfd *, flagword)); |
42 |
static boolean mcore_elf_merge_private_bfd_data |
static bfd_boolean mcore_elf_merge_private_bfd_data |
43 |
PARAMS ((bfd *, bfd *)); |
PARAMS ((bfd *, bfd *)); |
44 |
static bfd_reloc_status_type mcore_elf_unsupported_reloc |
static bfd_reloc_status_type mcore_elf_unsupported_reloc |
45 |
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
46 |
static boolean mcore_elf_relocate_section |
static bfd_boolean mcore_elf_relocate_section |
47 |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
48 |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
49 |
static asection * mcore_elf_gc_mark_hook |
static asection * mcore_elf_gc_mark_hook |
50 |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
51 |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
52 |
static boolean mcore_elf_gc_sweep_hook |
static bfd_boolean mcore_elf_gc_sweep_hook |
53 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
54 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
55 |
static boolean mcore_elf_check_relocs |
static bfd_boolean mcore_elf_check_relocs |
56 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
57 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
58 |
|
|
65 |
0, /* rightshift */ |
0, /* rightshift */ |
66 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
67 |
32, /* bitsize */ |
32, /* bitsize */ |
68 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
69 |
0, /* bitpos */ |
0, /* bitpos */ |
70 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
71 |
NULL, /* special_function */ |
NULL, /* special_function */ |
72 |
"R_MCORE_NONE", /* name */ |
"R_MCORE_NONE", /* name */ |
73 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
74 |
0, /* src_mask */ |
0, /* src_mask */ |
75 |
0, /* dst_mask */ |
0, /* dst_mask */ |
76 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
77 |
|
|
78 |
/* A standard 32 bit relocation. */ |
/* A standard 32 bit relocation. */ |
79 |
HOWTO (R_MCORE_ADDR32, /* type */ |
HOWTO (R_MCORE_ADDR32, /* type */ |
80 |
0, /* rightshift */ |
0, /* rightshift */ |
81 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
82 |
32, /* bitsize */ |
32, /* bitsize */ |
83 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
84 |
0, /* bitpos */ |
0, /* bitpos */ |
85 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
86 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
87 |
"ADDR32", /* name *//* For compatability with coff/pe port. */ |
"ADDR32", /* name *//* For compatibility with coff/pe port. */ |
88 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
89 |
0x0, /* src_mask */ |
0x0, /* src_mask */ |
90 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
91 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
92 |
|
|
93 |
/* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions. |
/* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions. |
94 |
Should not appear in object files. */ |
Should not appear in object files. */ |
96 |
2, /* rightshift */ |
2, /* rightshift */ |
97 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
98 |
8, /* bitsize */ |
8, /* bitsize */ |
99 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
100 |
0, /* bitpos */ |
0, /* bitpos */ |
101 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
102 |
mcore_elf_unsupported_reloc, /* special_function */ |
mcore_elf_unsupported_reloc, /* special_function */ |
103 |
"R_MCORE_PCRELIMM8BY4",/* name */ |
"R_MCORE_PCRELIMM8BY4",/* name */ |
104 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
105 |
0, /* src_mask */ |
0, /* src_mask */ |
106 |
0, /* dst_mask */ |
0, /* dst_mask */ |
107 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
108 |
|
|
109 |
/* bsr/bt/bf/br instructions; 11 bits + 1 zero bit |
/* bsr/bt/bf/br instructions; 11 bits + 1 zero bit |
110 |
Span 2k instructions == 4k bytes. |
Span 2k instructions == 4k bytes. |
113 |
1, /* rightshift */ |
1, /* rightshift */ |
114 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
115 |
11, /* bitsize */ |
11, /* bitsize */ |
116 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
117 |
0, /* bitpos */ |
0, /* bitpos */ |
118 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
119 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
120 |
"R_MCORE_PCRELIMM11BY2",/* name */ |
"R_MCORE_PCRELIMM11BY2",/* name */ |
121 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
122 |
0x0, /* src_mask */ |
0x0, /* src_mask */ |
123 |
0x7ff, /* dst_mask */ |
0x7ff, /* dst_mask */ |
124 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
125 |
|
|
126 |
/* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */ |
/* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */ |
127 |
HOWTO (R_MCORE_PCRELIMM4BY2, /* type */ |
HOWTO (R_MCORE_PCRELIMM4BY2, /* type */ |
128 |
1, /* rightshift */ |
1, /* rightshift */ |
129 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
130 |
4, /* bitsize */ |
4, /* bitsize */ |
131 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
132 |
0, /* bitpos */ |
0, /* bitpos */ |
133 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
134 |
mcore_elf_unsupported_reloc,/* special_function */ |
mcore_elf_unsupported_reloc,/* special_function */ |
135 |
"R_MCORE_PCRELIMM4BY2",/* name */ |
"R_MCORE_PCRELIMM4BY2",/* name */ |
136 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
137 |
0, /* src_mask */ |
0, /* src_mask */ |
138 |
0, /* dst_mask */ |
0, /* dst_mask */ |
139 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
140 |
|
|
141 |
/* 32-bit pc-relative. Eventually this will help support PIC code. */ |
/* 32-bit pc-relative. Eventually this will help support PIC code. */ |
142 |
HOWTO (R_MCORE_PCREL32, /* type */ |
HOWTO (R_MCORE_PCREL32, /* type */ |
143 |
0, /* rightshift */ |
0, /* rightshift */ |
144 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
145 |
32, /* bitsize */ |
32, /* bitsize */ |
146 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
147 |
0, /* bitpos */ |
0, /* bitpos */ |
148 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
149 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
150 |
"R_MCORE_PCREL32", /* name */ |
"R_MCORE_PCREL32", /* name */ |
151 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
152 |
0x0, /* src_mask */ |
0x0, /* src_mask */ |
153 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
154 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
155 |
|
|
156 |
/* Like PCRELIMM11BY2, this relocation indicates that there is a |
/* Like PCRELIMM11BY2, this relocation indicates that there is a |
157 |
'jsri' at the specified address. There is a separate relocation |
'jsri' at the specified address. There is a separate relocation |
164 |
1, /* rightshift */ |
1, /* rightshift */ |
165 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
166 |
11, /* bitsize */ |
11, /* bitsize */ |
167 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
168 |
0, /* bitpos */ |
0, /* bitpos */ |
169 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
170 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
171 |
"R_MCORE_PCRELJSR_IMM11BY2", /* name */ |
"R_MCORE_PCRELJSR_IMM11BY2", /* name */ |
172 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
173 |
0x0, /* src_mask */ |
0x0, /* src_mask */ |
174 |
0x7ff, /* dst_mask */ |
0x7ff, /* dst_mask */ |
175 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
176 |
|
|
177 |
/* GNU extension to record C++ vtable hierarchy */ |
/* GNU extension to record C++ vtable hierarchy */ |
178 |
HOWTO (R_MCORE_GNU_VTINHERIT, /* type */ |
HOWTO (R_MCORE_GNU_VTINHERIT, /* type */ |
179 |
0, /* rightshift */ |
0, /* rightshift */ |
180 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
181 |
0, /* bitsize */ |
0, /* bitsize */ |
182 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
183 |
0, /* bitpos */ |
0, /* bitpos */ |
184 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
185 |
NULL, /* special_function */ |
NULL, /* special_function */ |
186 |
"R_MCORE_GNU_VTINHERIT", /* name */ |
"R_MCORE_GNU_VTINHERIT", /* name */ |
187 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
188 |
0, /* src_mask */ |
0, /* src_mask */ |
189 |
0, /* dst_mask */ |
0, /* dst_mask */ |
190 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
191 |
|
|
192 |
/* GNU extension to record C++ vtable member usage */ |
/* GNU extension to record C++ vtable member usage */ |
193 |
HOWTO (R_MCORE_GNU_VTENTRY, /* type */ |
HOWTO (R_MCORE_GNU_VTENTRY, /* type */ |
194 |
0, /* rightshift */ |
0, /* rightshift */ |
195 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
196 |
0, /* bitsize */ |
0, /* bitsize */ |
197 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
198 |
0, /* bitpos */ |
0, /* bitpos */ |
199 |
complain_overflow_dont,/* complain_on_overflow */ |
complain_overflow_dont,/* complain_on_overflow */ |
200 |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
201 |
"R_MCORE_GNU_VTENTRY", /* name */ |
"R_MCORE_GNU_VTENTRY", /* name */ |
202 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
203 |
0, /* src_mask */ |
0, /* src_mask */ |
204 |
0, /* dst_mask */ |
0, /* dst_mask */ |
205 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
206 |
|
|
207 |
HOWTO (R_MCORE_RELATIVE, /* type */ |
HOWTO (R_MCORE_RELATIVE, /* type */ |
208 |
0, /* rightshift */ |
0, /* rightshift */ |
209 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
210 |
32, /* bitsize */ |
32, /* bitsize */ |
211 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
212 |
0, /* bitpos */ |
0, /* bitpos */ |
213 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
214 |
NULL, /* special_function */ |
NULL, /* special_function */ |
215 |
"R_MCORE_RELATIVE", /* name */ |
"R_MCORE_RELATIVE", /* name */ |
216 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
217 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
218 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
219 |
false) /* pcrel_offset */ |
FALSE) /* pcrel_offset */ |
220 |
}; |
}; |
221 |
|
|
222 |
#ifndef NUM_ELEM |
#ifndef NUM_ELEM |
275 |
mcore_elf_info_to_howto (abfd, cache_ptr, dst) |
mcore_elf_info_to_howto (abfd, cache_ptr, dst) |
276 |
bfd * abfd ATTRIBUTE_UNUSED; |
bfd * abfd ATTRIBUTE_UNUSED; |
277 |
arelent * cache_ptr; |
arelent * cache_ptr; |
278 |
Elf32_Internal_Rela * dst; |
Elf_Internal_Rela * dst; |
279 |
{ |
{ |
280 |
if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ |
if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ |
281 |
mcore_elf_howto_init (); |
mcore_elf_howto_init (); |
286 |
} |
} |
287 |
|
|
288 |
/* Function to set whether a module needs the -mrelocatable bit set. */ |
/* Function to set whether a module needs the -mrelocatable bit set. */ |
289 |
static boolean |
static bfd_boolean |
290 |
mcore_elf_set_private_flags (abfd, flags) |
mcore_elf_set_private_flags (abfd, flags) |
291 |
bfd * abfd; |
bfd * abfd; |
292 |
flagword flags; |
flagword flags; |
295 |
|| elf_elfheader (abfd)->e_flags == flags); |
|| elf_elfheader (abfd)->e_flags == flags); |
296 |
|
|
297 |
elf_elfheader (abfd)->e_flags = flags; |
elf_elfheader (abfd)->e_flags = flags; |
298 |
elf_flags_init (abfd) = true; |
elf_flags_init (abfd) = TRUE; |
299 |
return true; |
return TRUE; |
300 |
} |
} |
301 |
|
|
302 |
/* Merge backend specific data from an object file to the output |
/* Merge backend specific data from an object file to the output |
303 |
object file when linking. */ |
object file when linking. */ |
304 |
static boolean |
static bfd_boolean |
305 |
mcore_elf_merge_private_bfd_data (ibfd, obfd) |
mcore_elf_merge_private_bfd_data (ibfd, obfd) |
306 |
bfd * ibfd; |
bfd * ibfd; |
307 |
bfd * obfd; |
bfd * obfd; |
311 |
|
|
312 |
/* Check if we have the same endianess */ |
/* Check if we have the same endianess */ |
313 |
if (! _bfd_generic_verify_endian_match (ibfd, obfd)) |
if (! _bfd_generic_verify_endian_match (ibfd, obfd)) |
314 |
return false; |
return FALSE; |
315 |
|
|
316 |
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
317 |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
318 |
return true; |
return TRUE; |
319 |
|
|
320 |
new_flags = elf_elfheader (ibfd)->e_flags; |
new_flags = elf_elfheader (ibfd)->e_flags; |
321 |
old_flags = elf_elfheader (obfd)->e_flags; |
old_flags = elf_elfheader (obfd)->e_flags; |
322 |
|
|
323 |
if (! elf_flags_init (obfd)) /* First call, no flags set */ |
if (! elf_flags_init (obfd)) /* First call, no flags set */ |
324 |
{ |
{ |
325 |
elf_flags_init (obfd) = true; |
elf_flags_init (obfd) = TRUE; |
326 |
elf_elfheader (obfd)->e_flags = new_flags; |
elf_elfheader (obfd)->e_flags = new_flags; |
327 |
} |
} |
328 |
else if (new_flags == old_flags) /* Compatible flags are ok */ |
else if (new_flags == old_flags) /* Compatible flags are ok */ |
332 |
/* FIXME */ |
/* FIXME */ |
333 |
} |
} |
334 |
|
|
335 |
return true; |
return TRUE; |
336 |
} |
} |
337 |
|
|
338 |
/* Don't pretend we can deal with unsupported relocs. */ |
/* Don't pretend we can deal with unsupported relocs. */ |
350 |
{ |
{ |
351 |
BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); |
BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); |
352 |
|
|
353 |
_bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"), |
_bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"), |
354 |
bfd_archive_filename (abfd), |
abfd, |
355 |
reloc_entry->howto->name, |
reloc_entry->howto->name, |
356 |
reloc_entry->howto->type); |
reloc_entry->howto->type); |
357 |
|
|
367 |
|
|
368 |
This function is responsible for adjust the section contents as |
This function is responsible for adjust the section contents as |
369 |
necessary, and (if using Rela relocs and generating a |
necessary, and (if using Rela relocs and generating a |
370 |
relocateable output file) adjusting the reloc addend as |
relocatable output file) adjusting the reloc addend as |
371 |
necessary. |
necessary. |
372 |
|
|
373 |
This function does not have to worry about setting the reloc |
This function does not have to worry about setting the reloc |
381 |
The global hash table entry for the global symbols can be found |
The global hash table entry for the global symbols can be found |
382 |
via elf_sym_hashes (input_bfd). |
via elf_sym_hashes (input_bfd). |
383 |
|
|
384 |
When generating relocateable output, this function must handle |
When generating relocatable output, this function must handle |
385 |
STB_LOCAL/STT_SECTION symbols specially. The output symbol is |
STB_LOCAL/STT_SECTION symbols specially. The output symbol is |
386 |
going to be the section symbol corresponding to the output |
going to be the section symbol corresponding to the output |
387 |
section, which means that the addend must be adjusted |
section, which means that the addend must be adjusted |
388 |
accordingly. */ |
accordingly. */ |
389 |
|
|
390 |
static boolean |
static bfd_boolean |
391 |
mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, |
mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, |
392 |
contents, relocs, local_syms, local_sections) |
contents, relocs, local_syms, local_sections) |
393 |
bfd * output_bfd; |
bfd * output_bfd; |
394 |
struct bfd_link_info * info; |
struct bfd_link_info * info; |
395 |
bfd * input_bfd; |
bfd * input_bfd; |
399 |
Elf_Internal_Sym * local_syms; |
Elf_Internal_Sym * local_syms; |
400 |
asection ** local_sections; |
asection ** local_sections; |
401 |
{ |
{ |
402 |
Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
403 |
struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd); |
struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd); |
404 |
Elf_Internal_Rela * rel = relocs; |
Elf_Internal_Rela * rel = relocs; |
405 |
Elf_Internal_Rela * relend = relocs + input_section->reloc_count; |
Elf_Internal_Rela * relend = relocs + input_section->reloc_count; |
406 |
boolean ret = true; |
bfd_boolean ret = TRUE; |
407 |
|
|
408 |
#ifdef DEBUG |
#ifdef DEBUG |
409 |
fprintf (stderr, |
_bfd_error_handler |
410 |
"mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n", |
("mcore_elf_relocate_section called for %B section %A, %ld relocations%s", |
411 |
bfd_archive_filename (input_bfd), |
input_bfd, |
412 |
bfd_section_name(input_bfd, input_section), |
input_section, |
413 |
(long) input_section->reloc_count, |
(long) input_section->reloc_count, |
414 |
(info->relocateable) ? " (relocatable)" : ""); |
(info->relocatable) ? " (relocatable)" : ""); |
415 |
#endif |
#endif |
416 |
|
|
417 |
if (info->relocateable) |
if (info->relocatable) |
418 |
return true; |
return TRUE; |
419 |
|
|
420 |
if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ |
if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ |
421 |
mcore_elf_howto_init (); |
mcore_elf_howto_init (); |
438 |
if ((unsigned) r_type >= (unsigned) R_MCORE_max |
if ((unsigned) r_type >= (unsigned) R_MCORE_max |
439 |
|| ! mcore_elf_howto_table [(int)r_type]) |
|| ! mcore_elf_howto_table [(int)r_type]) |
440 |
{ |
{ |
441 |
_bfd_error_handler (_("%s: Unknown relocation type %d\n"), |
_bfd_error_handler (_("%B: Unknown relocation type %d\n"), |
442 |
bfd_archive_filename (input_bfd), |
input_bfd, (int) r_type); |
|
(int) r_type); |
|
443 |
|
|
444 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
445 |
ret = false; |
ret = FALSE; |
446 |
continue; |
continue; |
447 |
} |
} |
448 |
|
|
452 |
/* Complain about known relocation that are not yet supported. */ |
/* Complain about known relocation that are not yet supported. */ |
453 |
if (howto->special_function == mcore_elf_unsupported_reloc) |
if (howto->special_function == mcore_elf_unsupported_reloc) |
454 |
{ |
{ |
455 |
_bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"), |
_bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"), |
456 |
bfd_archive_filename (input_bfd), |
input_bfd, |
457 |
howto->name, |
howto->name, |
458 |
(int)r_type); |
(int)r_type); |
459 |
|
|
460 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
461 |
ret = false; |
ret = FALSE; |
462 |
continue; |
continue; |
463 |
} |
} |
464 |
|
|
466 |
{ |
{ |
467 |
sym = local_syms + r_symndx; |
sym = local_syms + r_symndx; |
468 |
sec = local_sections [r_symndx]; |
sec = local_sections [r_symndx]; |
469 |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
470 |
addend = rel->r_addend; |
addend = rel->r_addend; |
471 |
} |
} |
472 |
else |
else |
473 |
{ |
{ |
474 |
h = sym_hashes [r_symndx - symtab_hdr->sh_info]; |
bfd_boolean unresolved_reloc, warned; |
|
if ( h->root.type == bfd_link_hash_defined |
|
|
|| h->root.type == bfd_link_hash_defweak) |
|
|
{ |
|
|
sec = h->root.u.def.section; |
|
|
relocation = (h->root.u.def.value |
|
|
+ sec->output_section->vma |
|
|
+ sec->output_offset); |
|
|
} |
|
|
else if (h->root.type == bfd_link_hash_undefweak) |
|
|
relocation = 0; |
|
|
else if (info->shared |
|
|
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) |
|
|
relocation = 0; |
|
|
else |
|
|
{ |
|
|
if (! ((*info->callbacks->undefined_symbol) |
|
|
(info, h->root.root.string, input_bfd, |
|
|
input_section, rel->r_offset, true))) |
|
|
return false; |
|
475 |
|
|
476 |
ret = false; |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
477 |
continue; |
r_symndx, symtab_hdr, sym_hashes, |
478 |
} |
h, sec, relocation, |
479 |
|
unresolved_reloc, warned); |
480 |
} |
} |
481 |
|
|
482 |
switch (r_type) |
switch (r_type) |
508 |
|
|
509 |
if (r != bfd_reloc_ok) |
if (r != bfd_reloc_ok) |
510 |
{ |
{ |
511 |
ret = false; |
ret = FALSE; |
512 |
|
|
513 |
switch (r) |
switch (r) |
514 |
{ |
{ |
520 |
const char * name; |
const char * name; |
521 |
|
|
522 |
if (h != NULL) |
if (h != NULL) |
523 |
name = h->root.root.string; |
name = NULL; |
524 |
else |
else |
525 |
{ |
{ |
526 |
name = bfd_elf_string_from_elf_section |
name = bfd_elf_string_from_elf_section |
534 |
} |
} |
535 |
|
|
536 |
(*info->callbacks->reloc_overflow) |
(*info->callbacks->reloc_overflow) |
537 |
(info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, |
(info, (h ? &h->root : NULL), name, howto->name, |
538 |
offset); |
(bfd_vma) 0, input_bfd, input_section, offset); |
539 |
} |
} |
540 |
break; |
break; |
541 |
} |
} |
591 |
|
|
592 |
/* Update the got entry reference counts for the section being removed. */ |
/* Update the got entry reference counts for the section being removed. */ |
593 |
|
|
594 |
static boolean |
static bfd_boolean |
595 |
mcore_elf_gc_sweep_hook (abfd, info, sec, relocs) |
mcore_elf_gc_sweep_hook (abfd, info, sec, relocs) |
596 |
bfd * abfd ATTRIBUTE_UNUSED; |
bfd * abfd ATTRIBUTE_UNUSED; |
597 |
struct bfd_link_info * info ATTRIBUTE_UNUSED; |
struct bfd_link_info * info ATTRIBUTE_UNUSED; |
598 |
asection * sec ATTRIBUTE_UNUSED; |
asection * sec ATTRIBUTE_UNUSED; |
599 |
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; |
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; |
600 |
{ |
{ |
601 |
return true; |
return TRUE; |
602 |
} |
} |
603 |
|
|
604 |
/* Look through the relocs for a section during the first phase. |
/* Look through the relocs for a section during the first phase. |
605 |
Since we don't do .gots or .plts, we just need to consider the |
Since we don't do .gots or .plts, we just need to consider the |
606 |
virtual table relocs for gc. */ |
virtual table relocs for gc. */ |
607 |
|
|
608 |
static boolean |
static bfd_boolean |
609 |
mcore_elf_check_relocs (abfd, info, sec, relocs) |
mcore_elf_check_relocs (abfd, info, sec, relocs) |
610 |
bfd * abfd; |
bfd * abfd; |
611 |
struct bfd_link_info * info; |
struct bfd_link_info * info; |
612 |
asection * sec; |
asection * sec; |
613 |
const Elf_Internal_Rela * relocs; |
const Elf_Internal_Rela * relocs; |
614 |
{ |
{ |
615 |
Elf_Internal_Shdr * symtab_hdr; |
Elf_Internal_Shdr * symtab_hdr; |
616 |
struct elf_link_hash_entry ** sym_hashes; |
struct elf_link_hash_entry ** sym_hashes; |
617 |
struct elf_link_hash_entry ** sym_hashes_end; |
struct elf_link_hash_entry ** sym_hashes_end; |
618 |
const Elf_Internal_Rela * rel; |
const Elf_Internal_Rela * rel; |
619 |
const Elf_Internal_Rela * rel_end; |
const Elf_Internal_Rela * rel_end; |
620 |
|
|
621 |
if (info->relocateable) |
if (info->relocatable) |
622 |
return true; |
return TRUE; |
623 |
|
|
624 |
symtab_hdr = & elf_tdata (abfd)->symtab_hdr; |
symtab_hdr = & elf_tdata (abfd)->symtab_hdr; |
625 |
sym_hashes = elf_sym_hashes (abfd); |
sym_hashes = elf_sym_hashes (abfd); |
646 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
647 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
648 |
case R_MCORE_GNU_VTINHERIT: |
case R_MCORE_GNU_VTINHERIT: |
649 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
650 |
return false; |
return FALSE; |
651 |
break; |
break; |
652 |
|
|
653 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
654 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
655 |
case R_MCORE_GNU_VTENTRY: |
case R_MCORE_GNU_VTENTRY: |
656 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
657 |
return false; |
return FALSE; |
658 |
break; |
break; |
659 |
} |
} |
660 |
} |
} |
661 |
|
|
662 |
return true; |
return TRUE; |
663 |
} |
} |
664 |
|
|
665 |
|
static struct bfd_elf_special_section const mcore_elf_special_sections[]= |
666 |
|
{ |
667 |
|
{ ".ctors", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
668 |
|
{ ".dtors", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
669 |
|
{ NULL, 0, 0, 0, 0 } |
670 |
|
}; |
671 |
|
|
672 |
#define TARGET_BIG_SYM bfd_elf32_mcore_big_vec |
#define TARGET_BIG_SYM bfd_elf32_mcore_big_vec |
673 |
#define TARGET_BIG_NAME "elf32-mcore-big" |
#define TARGET_BIG_NAME "elf32-mcore-big" |
674 |
#define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec |
#define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec |
687 |
#define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook |
#define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook |
688 |
#define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook |
#define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook |
689 |
#define elf_backend_check_relocs mcore_elf_check_relocs |
#define elf_backend_check_relocs mcore_elf_check_relocs |
690 |
|
#define elf_backend_special_sections mcore_elf_special_sections |
691 |
|
|
692 |
#define elf_backend_can_gc_sections 1 |
#define elf_backend_can_gc_sections 1 |
693 |
#define elf_backend_rela_normal 1 |
#define elf_backend_rela_normal 1 |