1 |
/* XSTORMY16-specific support for 32-bit ELF. |
/* XSTORMY16-specific support for 32-bit ELF. |
2 |
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. |
Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
5 |
|
|
28 |
static reloc_howto_type * xstormy16_reloc_type_lookup |
static reloc_howto_type * xstormy16_reloc_type_lookup |
29 |
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); |
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); |
30 |
static void xstormy16_info_to_howto_rela |
static void xstormy16_info_to_howto_rela |
31 |
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
32 |
static bfd_reloc_status_type xstormy16_elf_24_reloc |
static bfd_reloc_status_type xstormy16_elf_24_reloc |
33 |
PARAMS ((bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
PARAMS ((bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
34 |
PTR data, asection *input_section, bfd *output_bfd, |
PTR data, asection *input_section, bfd *output_bfd, |
35 |
char **error_message)); |
char **error_message)); |
36 |
static boolean xstormy16_elf_check_relocs |
static bfd_boolean xstormy16_elf_check_relocs |
37 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
38 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
39 |
static boolean xstormy16_relax_plt_check |
static bfd_boolean xstormy16_relax_plt_check |
40 |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
41 |
static boolean xstormy16_relax_plt_realloc |
static bfd_boolean xstormy16_relax_plt_realloc |
42 |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
43 |
static boolean xstormy16_elf_relax_section |
static bfd_boolean xstormy16_elf_relax_section |
44 |
PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info, |
PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info, |
45 |
boolean *again)); |
bfd_boolean *again)); |
46 |
static boolean xstormy16_elf_always_size_sections |
static bfd_boolean xstormy16_elf_always_size_sections |
47 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
48 |
static boolean xstormy16_elf_relocate_section |
static bfd_boolean xstormy16_elf_relocate_section |
49 |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
50 |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
51 |
static boolean xstormy16_elf_finish_dynamic_sections |
static bfd_boolean xstormy16_elf_finish_dynamic_sections |
52 |
PARAMS((bfd *, struct bfd_link_info *)); |
PARAMS((bfd *, struct bfd_link_info *)); |
53 |
static boolean xstormy16_elf_gc_sweep_hook |
static bfd_boolean xstormy16_elf_gc_sweep_hook |
54 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
55 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
56 |
static asection * xstormy16_elf_gc_mark_hook |
static asection * xstormy16_elf_gc_mark_hook |
64 |
0, /* rightshift */ |
0, /* rightshift */ |
65 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
66 |
32, /* bitsize */ |
32, /* bitsize */ |
67 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
68 |
0, /* bitpos */ |
0, /* bitpos */ |
69 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
70 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
71 |
"R_XSTORMY16_NONE", /* name */ |
"R_XSTORMY16_NONE", /* name */ |
72 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
73 |
0, /* src_mask */ |
0, /* src_mask */ |
74 |
0, /* dst_mask */ |
0, /* dst_mask */ |
75 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
76 |
|
|
77 |
/* A 32 bit absolute relocation. */ |
/* A 32 bit absolute relocation. */ |
78 |
HOWTO (R_XSTORMY16_32, /* type */ |
HOWTO (R_XSTORMY16_32, /* type */ |
79 |
0, /* rightshift */ |
0, /* rightshift */ |
80 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
81 |
32, /* bitsize */ |
32, /* bitsize */ |
82 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
83 |
0, /* bitpos */ |
0, /* bitpos */ |
84 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
85 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
86 |
"R_XSTORMY16_32", /* name */ |
"R_XSTORMY16_32", /* name */ |
87 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
88 |
0, /* src_mask */ |
0, /* src_mask */ |
89 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
90 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
91 |
|
|
92 |
/* A 16 bit absolute relocation. */ |
/* A 16 bit absolute relocation. */ |
93 |
HOWTO (R_XSTORMY16_16, /* type */ |
HOWTO (R_XSTORMY16_16, /* type */ |
94 |
0, /* rightshift */ |
0, /* rightshift */ |
95 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
96 |
16, /* bitsize */ |
16, /* bitsize */ |
97 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
98 |
0, /* bitpos */ |
0, /* bitpos */ |
99 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
100 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
101 |
"R_XSTORMY16_16", /* name */ |
"R_XSTORMY16_16", /* name */ |
102 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
103 |
0, /* src_mask */ |
0, /* src_mask */ |
104 |
0xffffffff, /* dst_mask */ |
0xffff, /* dst_mask */ |
105 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
106 |
|
|
107 |
/* An 8 bit absolute relocation. */ |
/* An 8 bit absolute relocation. */ |
108 |
HOWTO (R_XSTORMY16_8, /* type */ |
HOWTO (R_XSTORMY16_8, /* type */ |
109 |
0, /* rightshift */ |
0, /* rightshift */ |
110 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
111 |
8, /* bitsize */ |
8, /* bitsize */ |
112 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
113 |
0, /* bitpos */ |
0, /* bitpos */ |
114 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_unsigned, /* complain_on_overflow */ |
115 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
116 |
"R_XSTORMY16_8", /* name */ |
"R_XSTORMY16_8", /* name */ |
117 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
118 |
0, /* src_mask */ |
0, /* src_mask */ |
119 |
0xffffffff, /* dst_mask */ |
0xff, /* dst_mask */ |
120 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
121 |
|
|
122 |
/* A 32 bit pc-relative relocation. */ |
/* A 32 bit pc-relative relocation. */ |
123 |
HOWTO (R_XSTORMY16_PC32, /* type */ |
HOWTO (R_XSTORMY16_PC32, /* type */ |
124 |
0, /* rightshift */ |
0, /* rightshift */ |
125 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
126 |
32, /* bitsize */ |
32, /* bitsize */ |
127 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
128 |
0, /* bitpos */ |
0, /* bitpos */ |
129 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
130 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
131 |
"R_XSTORMY16_PC32", /* name */ |
"R_XSTORMY16_PC32", /* name */ |
132 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
133 |
0, /* src_mask */ |
0, /* src_mask */ |
134 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
135 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
136 |
|
|
137 |
/* A 16 bit pc-relative relocation. */ |
/* A 16 bit pc-relative relocation. */ |
138 |
HOWTO (R_XSTORMY16_PC16, /* type */ |
HOWTO (R_XSTORMY16_PC16, /* type */ |
139 |
0, /* rightshift */ |
0, /* rightshift */ |
140 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
141 |
16, /* bitsize */ |
16, /* bitsize */ |
142 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
143 |
0, /* bitpos */ |
0, /* bitpos */ |
144 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
145 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
146 |
"R_XSTORMY16_PC16", /* name */ |
"R_XSTORMY16_PC16", /* name */ |
147 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
148 |
0, /* src_mask */ |
0, /* src_mask */ |
149 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
150 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
151 |
|
|
152 |
/* An 8 bit pc-relative relocation. */ |
/* An 8 bit pc-relative relocation. */ |
153 |
HOWTO (R_XSTORMY16_PC8, /* type */ |
HOWTO (R_XSTORMY16_PC8, /* type */ |
154 |
0, /* rightshift */ |
0, /* rightshift */ |
155 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
156 |
8, /* bitsize */ |
8, /* bitsize */ |
157 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
158 |
0, /* bitpos */ |
0, /* bitpos */ |
159 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
160 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
161 |
"R_XSTORMY16_PC8", /* name */ |
"R_XSTORMY16_PC8", /* name */ |
162 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
163 |
0, /* src_mask */ |
0, /* src_mask */ |
164 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
165 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
166 |
|
|
167 |
/* A 12-bit pc-relative relocation suitable for the branch instructions. */ |
/* A 12-bit pc-relative relocation suitable for the branch instructions. */ |
168 |
HOWTO (R_XSTORMY16_REL_12, /* type */ |
HOWTO (R_XSTORMY16_REL_12, /* type */ |
169 |
1, /* rightshift */ |
1, /* rightshift */ |
170 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
171 |
11, /* bitsize */ |
11, /* bitsize */ |
172 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
173 |
1, /* bitpos */ |
1, /* bitpos */ |
174 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
175 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
176 |
"R_XSTORMY16_REL_12", /* name */ |
"R_XSTORMY16_REL_12", /* name */ |
177 |
true, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
178 |
0, /* src_mask */ |
0, /* src_mask */ |
179 |
0x0fff, /* dst_mask */ |
0x0ffe, /* dst_mask */ |
180 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
181 |
|
|
182 |
/* A 24-bit absolute relocation suitable for the jump instructions. */ |
/* A 24-bit absolute relocation suitable for the jump instructions. */ |
183 |
HOWTO (R_XSTORMY16_24, /* type */ |
HOWTO (R_XSTORMY16_24, /* type */ |
184 |
0, /* rightshift */ |
0, /* rightshift */ |
185 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
186 |
24, /* bitsize */ |
24, /* bitsize */ |
187 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
188 |
0, /* bitpos */ |
0, /* bitpos */ |
189 |
complain_overflow_unsigned, /* complain_on_overflow */ |
complain_overflow_unsigned, /* complain_on_overflow */ |
190 |
xstormy16_elf_24_reloc, /* special_function */ |
xstormy16_elf_24_reloc, /* special_function */ |
191 |
"R_XSTORMY16_24", /* name */ |
"R_XSTORMY16_24", /* name */ |
192 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
193 |
0, /* src_mask */ |
0, /* src_mask */ |
194 |
0xffff00ff, /* dst_mask */ |
0xffff00ff, /* dst_mask */ |
195 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
196 |
|
|
197 |
/* A 16 bit absolute relocation to a function pointer. */ |
/* A 16 bit absolute relocation to a function pointer. */ |
198 |
HOWTO (R_XSTORMY16_FPTR16, /* type */ |
HOWTO (R_XSTORMY16_FPTR16, /* type */ |
199 |
0, /* rightshift */ |
0, /* rightshift */ |
200 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
201 |
16, /* bitsize */ |
16, /* bitsize */ |
202 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
203 |
0, /* bitpos */ |
0, /* bitpos */ |
204 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
205 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
206 |
"R_XSTORMY16_FPTR16", /* name */ |
"R_XSTORMY16_FPTR16", /* name */ |
207 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
208 |
0, /* src_mask */ |
0, /* src_mask */ |
209 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
210 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
211 |
|
|
212 |
|
/* Low order 16 bit value of a high memory address. */ |
213 |
|
HOWTO (R_XSTORMY16_LO16, /* type */ |
214 |
|
0, /* rightshift */ |
215 |
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
216 |
|
16, /* bitsize */ |
217 |
|
FALSE, /* pc_relative */ |
218 |
|
0, /* bitpos */ |
219 |
|
complain_overflow_dont, /* complain_on_overflow */ |
220 |
|
bfd_elf_generic_reloc, /* special_function */ |
221 |
|
"R_XSTORMY16_LO16", /* name */ |
222 |
|
FALSE, /* partial_inplace */ |
223 |
|
0, /* src_mask */ |
224 |
|
0xffff, /* dst_mask */ |
225 |
|
FALSE), /* pcrel_offset */ |
226 |
|
|
227 |
|
/* High order 16 bit value of a high memory address. */ |
228 |
|
HOWTO (R_XSTORMY16_HI16, /* type */ |
229 |
|
16, /* rightshift */ |
230 |
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
231 |
|
16, /* bitsize */ |
232 |
|
FALSE, /* pc_relative */ |
233 |
|
0, /* bitpos */ |
234 |
|
complain_overflow_dont, /* complain_on_overflow */ |
235 |
|
bfd_elf_generic_reloc, /* special_function */ |
236 |
|
"R_XSTORMY16_HI16", /* name */ |
237 |
|
FALSE, /* partial_inplace */ |
238 |
|
0, /* src_mask */ |
239 |
|
0xffff, /* dst_mask */ |
240 |
|
FALSE), /* pcrel_offset */ |
241 |
|
|
242 |
|
/* A 12 bit absolute relocation. */ |
243 |
|
HOWTO (R_XSTORMY16_12, /* type */ |
244 |
|
0, /* rightshift */ |
245 |
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
246 |
|
12, /* bitsize */ |
247 |
|
FALSE, /* pc_relative */ |
248 |
|
0, /* bitpos */ |
249 |
|
complain_overflow_signed, /* complain_on_overflow */ |
250 |
|
bfd_elf_generic_reloc, /* special_function */ |
251 |
|
"R_XSTORMY16_12", /* name */ |
252 |
|
FALSE, /* partial_inplace */ |
253 |
|
0x0000, /* src_mask */ |
254 |
|
0x0fff, /* dst_mask */ |
255 |
|
FALSE), /* pcrel_offset */ |
256 |
}; |
}; |
257 |
|
|
258 |
static reloc_howto_type xstormy16_elf_howto_table2 [] = |
static reloc_howto_type xstormy16_elf_howto_table2 [] = |
262 |
0, /* rightshift */ |
0, /* rightshift */ |
263 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
264 |
0, /* bitsize */ |
0, /* bitsize */ |
265 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
266 |
0, /* bitpos */ |
0, /* bitpos */ |
267 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
268 |
NULL, /* special_function */ |
NULL, /* special_function */ |
269 |
"R_XSTORMY16_GNU_VTINHERIT", /* name */ |
"R_XSTORMY16_GNU_VTINHERIT", /* name */ |
270 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
271 |
0, /* src_mask */ |
0, /* src_mask */ |
272 |
0, /* dst_mask */ |
0, /* dst_mask */ |
273 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
274 |
|
|
275 |
/* GNU extension to record C++ vtable member usage */ |
/* GNU extension to record C++ vtable member usage */ |
276 |
HOWTO (R_XSTORMY16_GNU_VTENTRY, /* type */ |
HOWTO (R_XSTORMY16_GNU_VTENTRY, /* type */ |
277 |
0, /* rightshift */ |
0, /* rightshift */ |
278 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
279 |
0, /* bitsize */ |
0, /* bitsize */ |
280 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
281 |
0, /* bitpos */ |
0, /* bitpos */ |
282 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
283 |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
284 |
"R_XSTORMY16_GNU_VTENTRY", /* name */ |
"R_XSTORMY16_GNU_VTENTRY", /* name */ |
285 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
286 |
0, /* src_mask */ |
0, /* src_mask */ |
287 |
0, /* dst_mask */ |
0, /* dst_mask */ |
288 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
289 |
|
|
290 |
}; |
}; |
291 |
|
|
310 |
{ BFD_RELOC_XSTORMY16_REL_12, R_XSTORMY16_REL_12, xstormy16_elf_howto_table }, |
{ BFD_RELOC_XSTORMY16_REL_12, R_XSTORMY16_REL_12, xstormy16_elf_howto_table }, |
311 |
{ BFD_RELOC_XSTORMY16_24, R_XSTORMY16_24, xstormy16_elf_howto_table }, |
{ BFD_RELOC_XSTORMY16_24, R_XSTORMY16_24, xstormy16_elf_howto_table }, |
312 |
{ BFD_RELOC_XSTORMY16_FPTR16, R_XSTORMY16_FPTR16, xstormy16_elf_howto_table }, |
{ BFD_RELOC_XSTORMY16_FPTR16, R_XSTORMY16_FPTR16, xstormy16_elf_howto_table }, |
313 |
|
{ BFD_RELOC_LO16, R_XSTORMY16_LO16, xstormy16_elf_howto_table }, |
314 |
|
{ BFD_RELOC_HI16, R_XSTORMY16_HI16, xstormy16_elf_howto_table }, |
315 |
|
{ BFD_RELOC_XSTORMY16_12, R_XSTORMY16_12, xstormy16_elf_howto_table }, |
316 |
{ BFD_RELOC_VTABLE_INHERIT, R_XSTORMY16_GNU_VTINHERIT, xstormy16_elf_howto_table2 }, |
{ BFD_RELOC_VTABLE_INHERIT, R_XSTORMY16_GNU_VTINHERIT, xstormy16_elf_howto_table2 }, |
317 |
{ BFD_RELOC_VTABLE_ENTRY, R_XSTORMY16_GNU_VTENTRY, xstormy16_elf_howto_table2 }, |
{ BFD_RELOC_VTABLE_ENTRY, R_XSTORMY16_GNU_VTENTRY, xstormy16_elf_howto_table2 }, |
318 |
}; |
}; |
344 |
xstormy16_info_to_howto_rela (abfd, cache_ptr, dst) |
xstormy16_info_to_howto_rela (abfd, cache_ptr, dst) |
345 |
bfd * abfd ATTRIBUTE_UNUSED; |
bfd * abfd ATTRIBUTE_UNUSED; |
346 |
arelent * cache_ptr; |
arelent * cache_ptr; |
347 |
Elf32_Internal_Rela * dst; |
Elf_Internal_Rela * dst; |
348 |
{ |
{ |
349 |
unsigned int r_type = ELF32_R_TYPE (dst->r_info); |
unsigned int r_type = ELF32_R_TYPE (dst->r_info); |
350 |
|
|
351 |
if (r_type <= (unsigned int) R_XSTORMY16_FPTR16) |
if (r_type <= (unsigned int) R_XSTORMY16_12) |
352 |
cache_ptr->howto = &xstormy16_elf_howto_table [r_type]; |
cache_ptr->howto = &xstormy16_elf_howto_table [r_type]; |
353 |
else if (r_type - R_XSTORMY16_GNU_VTINHERIT |
else if (r_type - R_XSTORMY16_GNU_VTINHERIT |
354 |
<= (unsigned int) R_XSTORMY16_GNU_VTENTRY) |
<= (unsigned int) R_XSTORMY16_GNU_VTENTRY) |
379 |
return bfd_reloc_ok; |
return bfd_reloc_ok; |
380 |
} |
} |
381 |
|
|
382 |
if (reloc_entry->address > input_section->_cooked_size) |
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
383 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
384 |
|
|
385 |
if (bfd_is_com_section (symbol->section)) |
if (bfd_is_com_section (symbol->section)) |
409 |
-relax switch is given, as otherwise we have no idea where the |
-relax switch is given, as otherwise we have no idea where the |
410 |
sections will fall in the address space. */ |
sections will fall in the address space. */ |
411 |
|
|
412 |
static boolean |
static bfd_boolean |
413 |
xstormy16_elf_check_relocs (abfd, info, sec, relocs) |
xstormy16_elf_check_relocs (abfd, info, sec, relocs) |
414 |
bfd *abfd; |
bfd *abfd; |
415 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
423 |
asection *splt; |
asection *splt; |
424 |
bfd *dynobj; |
bfd *dynobj; |
425 |
|
|
426 |
if (info->relocateable) |
if (info->relocatable) |
427 |
return true; |
return TRUE; |
428 |
|
|
429 |
symtab_hdr = &elf_tdata(abfd)->symtab_hdr; |
symtab_hdr = &elf_tdata(abfd)->symtab_hdr; |
430 |
sym_hashes = elf_sym_hashes (abfd); |
sym_hashes = elf_sym_hashes (abfd); |
481 |
| SEC_READONLY |
| SEC_READONLY |
482 |
| SEC_CODE)) |
| SEC_CODE)) |
483 |
|| ! bfd_set_section_alignment (dynobj, splt, 1)) |
|| ! bfd_set_section_alignment (dynobj, splt, 1)) |
484 |
return false; |
return FALSE; |
485 |
} |
} |
486 |
} |
} |
487 |
|
|
497 |
size = symtab_hdr->sh_info * sizeof (bfd_vma); |
size = symtab_hdr->sh_info * sizeof (bfd_vma); |
498 |
local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size); |
local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size); |
499 |
if (local_plt_offsets == NULL) |
if (local_plt_offsets == NULL) |
500 |
return false; |
return FALSE; |
501 |
elf_local_got_offsets (abfd) = local_plt_offsets; |
elf_local_got_offsets (abfd) = local_plt_offsets; |
502 |
|
|
503 |
for (i = 0; i < symtab_hdr->sh_info; i++) |
for (i = 0; i < symtab_hdr->sh_info; i++) |
508 |
|
|
509 |
if (*offset == (bfd_vma) -1) |
if (*offset == (bfd_vma) -1) |
510 |
{ |
{ |
511 |
*offset = splt->_raw_size; |
*offset = splt->size; |
512 |
splt->_raw_size += 4; |
splt->size += 4; |
513 |
} |
} |
514 |
break; |
break; |
515 |
|
|
516 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
517 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
518 |
case R_XSTORMY16_GNU_VTINHERIT: |
case R_XSTORMY16_GNU_VTINHERIT: |
519 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
520 |
return false; |
return FALSE; |
521 |
break; |
break; |
522 |
|
|
523 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
524 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
525 |
case R_XSTORMY16_GNU_VTENTRY: |
case R_XSTORMY16_GNU_VTENTRY: |
526 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
527 |
return false; |
return FALSE; |
528 |
break; |
break; |
529 |
} |
} |
530 |
} |
} |
531 |
|
|
532 |
return true; |
return TRUE; |
533 |
} |
} |
534 |
|
|
535 |
/* A subroutine of xstormy16_elf_relax_section. If the global symbol H |
/* A subroutine of xstormy16_elf_relax_section. If the global symbol H |
538 |
struct relax_plt_data |
struct relax_plt_data |
539 |
{ |
{ |
540 |
asection *splt; |
asection *splt; |
541 |
boolean *again; |
bfd_boolean *again; |
542 |
}; |
}; |
543 |
|
|
544 |
static boolean |
static bfd_boolean |
545 |
xstormy16_relax_plt_check (h, xdata) |
xstormy16_relax_plt_check (h, xdata) |
546 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
547 |
PTR xdata; |
PTR xdata; |
566 |
if (address <= 0xffff) |
if (address <= 0xffff) |
567 |
{ |
{ |
568 |
h->plt.offset = -1; |
h->plt.offset = -1; |
569 |
data->splt->_cooked_size -= 4; |
data->splt->size -= 4; |
570 |
*data->again = true; |
*data->again = TRUE; |
571 |
} |
} |
572 |
} |
} |
573 |
|
|
574 |
return true; |
return TRUE; |
575 |
} |
} |
576 |
|
|
577 |
/* A subroutine of xstormy16_elf_relax_section. If the global symbol H |
/* A subroutine of xstormy16_elf_relax_section. If the global symbol H |
578 |
previously had a plt entry, give it a new entry offset. */ |
previously had a plt entry, give it a new entry offset. */ |
579 |
|
|
580 |
static boolean |
static bfd_boolean |
581 |
xstormy16_relax_plt_realloc (h, xdata) |
xstormy16_relax_plt_realloc (h, xdata) |
582 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
583 |
PTR xdata; |
PTR xdata; |
593 |
*entry += 4; |
*entry += 4; |
594 |
} |
} |
595 |
|
|
596 |
return true; |
return TRUE; |
597 |
} |
} |
598 |
|
|
599 |
static boolean |
static bfd_boolean |
600 |
xstormy16_elf_relax_section (dynobj, splt, info, again) |
xstormy16_elf_relax_section (dynobj, splt, info, again) |
601 |
bfd *dynobj; |
bfd *dynobj; |
602 |
asection *splt; |
asection *splt; |
603 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
604 |
boolean *again; |
bfd_boolean *again; |
605 |
{ |
{ |
606 |
struct relax_plt_data relax_plt_data; |
struct relax_plt_data relax_plt_data; |
607 |
bfd *ibfd; |
bfd *ibfd; |
608 |
|
|
609 |
/* Assume nothing changes. */ |
/* Assume nothing changes. */ |
610 |
*again = false; |
*again = FALSE; |
611 |
|
|
612 |
if (info->relocateable) |
if (info->relocatable) |
613 |
return true; |
return TRUE; |
614 |
|
|
615 |
/* We only relax the .plt section at the moment. */ |
/* We only relax the .plt section at the moment. */ |
616 |
if (dynobj != elf_hash_table (info)->dynobj |
if (dynobj != elf_hash_table (info)->dynobj |
617 |
|| strcmp (splt->name, ".plt") != 0) |
|| strcmp (splt->name, ".plt") != 0) |
618 |
return true; |
return TRUE; |
619 |
|
|
620 |
/* Quick check for an empty plt. */ |
/* Quick check for an empty plt. */ |
621 |
if (splt->_raw_size == 0) |
if (splt->size == 0) |
622 |
return true; |
return TRUE; |
|
|
|
|
/* If this is the first time we have been called for this section, |
|
|
initialize the cooked size. */ |
|
|
if (splt->_cooked_size == 0) |
|
|
splt->_cooked_size = splt->_raw_size; |
|
623 |
|
|
624 |
/* Map across all global symbols; see which ones happen to |
/* Map across all global symbols; see which ones happen to |
625 |
fall in the low 64k. */ |
fall in the low 64k. */ |
649 |
symtab_hdr->sh_info, 0, |
symtab_hdr->sh_info, 0, |
650 |
NULL, NULL, NULL); |
NULL, NULL, NULL); |
651 |
if (isymbuf == NULL) |
if (isymbuf == NULL) |
652 |
return false; |
return FALSE; |
653 |
} |
} |
654 |
|
|
655 |
for (idx = 0; idx < symtab_hdr->sh_info; ++idx) |
for (idx = 0; idx < symtab_hdr->sh_info; ++idx) |
677 |
if (address <= 0xffff) |
if (address <= 0xffff) |
678 |
{ |
{ |
679 |
local_plt_offsets[idx] = -1; |
local_plt_offsets[idx] = -1; |
680 |
splt->_cooked_size -= 4; |
splt->size -= 4; |
681 |
*again = true; |
*again = TRUE; |
682 |
} |
} |
683 |
} |
} |
684 |
|
|
697 |
|
|
698 |
/* If we changed anything, walk the symbols again to reallocate |
/* If we changed anything, walk the symbols again to reallocate |
699 |
.plt entry addresses. */ |
.plt entry addresses. */ |
700 |
if (*again && splt->_cooked_size > 0) |
if (*again && splt->size > 0) |
701 |
{ |
{ |
702 |
bfd_vma entry = 0; |
bfd_vma entry = 0; |
703 |
|
|
722 |
} |
} |
723 |
} |
} |
724 |
|
|
725 |
splt->_raw_size = splt->_cooked_size; |
return TRUE; |
|
return true; |
|
726 |
} |
} |
727 |
|
|
728 |
static boolean |
static bfd_boolean |
729 |
xstormy16_elf_always_size_sections (output_bfd, info) |
xstormy16_elf_always_size_sections (output_bfd, info) |
730 |
bfd *output_bfd ATTRIBUTE_UNUSED; |
bfd *output_bfd ATTRIBUTE_UNUSED; |
731 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
733 |
bfd *dynobj; |
bfd *dynobj; |
734 |
asection *splt; |
asection *splt; |
735 |
|
|
736 |
if (info->relocateable) |
if (info->relocatable) |
737 |
return true; |
return TRUE; |
738 |
|
|
739 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
740 |
if (dynobj == NULL) |
if (dynobj == NULL) |
741 |
return true; |
return TRUE; |
742 |
|
|
743 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
744 |
BFD_ASSERT (splt != NULL); |
BFD_ASSERT (splt != NULL); |
745 |
|
|
746 |
splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->_raw_size); |
splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size); |
747 |
if (splt->contents == NULL) |
if (splt->contents == NULL) |
748 |
return false; |
return FALSE; |
749 |
|
|
750 |
return true; |
return TRUE; |
751 |
} |
} |
752 |
|
|
753 |
/* Relocate an XSTORMY16 ELF section. |
/* Relocate an XSTORMY16 ELF section. |
|
There is some attempt to make this function usable for many architectures, |
|
|
both USE_REL and USE_RELA ['twould be nice if such a critter existed], |
|
|
if only to serve as a learning tool. |
|
754 |
|
|
755 |
The RELOCATE_SECTION function is called by the new ELF backend linker |
The RELOCATE_SECTION function is called by the new ELF backend linker |
756 |
to handle the relocations for a section. |
to handle the relocations for a section. |
760 |
zero. |
zero. |
761 |
|
|
762 |
This function is responsible for adjusting the section contents as |
This function is responsible for adjusting the section contents as |
763 |
necessary, and (if using Rela relocs and generating a relocateable |
necessary, and (if using Rela relocs and generating a relocatable |
764 |
output file) adjusting the reloc addend as necessary. |
output file) adjusting the reloc addend as necessary. |
765 |
|
|
766 |
This function does not have to worry about setting the reloc |
This function does not have to worry about setting the reloc |
774 |
The global hash table entry for the global symbols can be found |
The global hash table entry for the global symbols can be found |
775 |
via elf_sym_hashes (input_bfd). |
via elf_sym_hashes (input_bfd). |
776 |
|
|
777 |
When generating relocateable output, this function must handle |
When generating relocatable output, this function must handle |
778 |
STB_LOCAL/STT_SECTION symbols specially. The output symbol is |
STB_LOCAL/STT_SECTION symbols specially. The output symbol is |
779 |
going to be the section symbol corresponding to the output |
going to be the section symbol corresponding to the output |
780 |
section, which means that the addend must be adjusted |
section, which means that the addend must be adjusted |
781 |
accordingly. */ |
accordingly. */ |
782 |
|
|
783 |
static boolean |
static bfd_boolean |
784 |
xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section, |
xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section, |
785 |
contents, relocs, local_syms, local_sections) |
contents, relocs, local_syms, local_sections) |
786 |
bfd * output_bfd ATTRIBUTE_UNUSED; |
bfd * output_bfd ATTRIBUTE_UNUSED; |
799 |
bfd *dynobj; |
bfd *dynobj; |
800 |
asection *splt; |
asection *splt; |
801 |
|
|
802 |
if (info->relocateable) |
if (info->relocatable) |
803 |
return true; |
return TRUE; |
804 |
|
|
805 |
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
806 |
sym_hashes = elf_sym_hashes (input_bfd); |
sym_hashes = elf_sym_hashes (input_bfd); |
839 |
{ |
{ |
840 |
sym = local_syms + r_symndx; |
sym = local_syms + r_symndx; |
841 |
sec = local_sections [r_symndx]; |
sec = local_sections [r_symndx]; |
842 |
relocation = (sec->output_section->vma |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
|
+ sec->output_offset |
|
|
+ sym->st_value); |
|
|
|
|
|
name = bfd_elf_string_from_elf_section |
|
|
(input_bfd, symtab_hdr->sh_link, sym->st_name); |
|
|
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; |
|
843 |
} |
} |
844 |
else |
else |
845 |
{ |
{ |
846 |
h = sym_hashes [r_symndx - symtab_hdr->sh_info]; |
bfd_boolean unresolved_reloc, warned; |
|
|
|
|
while (h->root.type == bfd_link_hash_indirect |
|
|
|| h->root.type == bfd_link_hash_warning) |
|
|
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
|
847 |
|
|
848 |
name = h->root.root.string; |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
849 |
|
r_symndx, symtab_hdr, sym_hashes, |
850 |
|
h, sec, relocation, |
851 |
|
unresolved_reloc, warned); |
852 |
|
} |
853 |
|
|
854 |
if (h->root.type == bfd_link_hash_defined |
if (h != NULL) |
855 |
|| h->root.type == bfd_link_hash_defweak) |
name = h->root.root.string; |
856 |
{ |
else |
857 |
sec = h->root.u.def.section; |
{ |
858 |
relocation = (h->root.u.def.value |
name = (bfd_elf_string_from_elf_section |
859 |
+ sec->output_section->vma |
(input_bfd, symtab_hdr->sh_link, sym->st_name)); |
860 |
+ sec->output_offset); |
if (name == NULL || *name == '\0') |
861 |
} |
name = bfd_section_name (input_bfd, sec); |
|
else if (h->root.type == bfd_link_hash_undefweak) |
|
|
{ |
|
|
relocation = 0; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (! ((*info->callbacks->undefined_symbol) |
|
|
(info, h->root.root.string, input_bfd, |
|
|
input_section, rel->r_offset, true))) |
|
|
return false; |
|
|
relocation = 0; |
|
|
} |
|
862 |
} |
} |
863 |
|
|
864 |
switch (ELF32_R_TYPE (rel->r_info)) |
switch (ELF32_R_TYPE (rel->r_info)) |
940 |
{ |
{ |
941 |
case bfd_reloc_overflow: |
case bfd_reloc_overflow: |
942 |
r = info->callbacks->reloc_overflow |
r = info->callbacks->reloc_overflow |
943 |
(info, name, howto->name, (bfd_vma) 0, |
(info, (h ? &h->root : NULL), name, howto->name, |
944 |
input_bfd, input_section, rel->r_offset); |
(bfd_vma) 0, input_bfd, input_section, rel->r_offset); |
945 |
break; |
break; |
946 |
|
|
947 |
case bfd_reloc_undefined: |
case bfd_reloc_undefined: |
948 |
r = info->callbacks->undefined_symbol |
r = info->callbacks->undefined_symbol |
949 |
(info, name, input_bfd, input_section, rel->r_offset, |
(info, name, input_bfd, input_section, rel->r_offset, |
950 |
true); |
TRUE); |
951 |
break; |
break; |
952 |
|
|
953 |
case bfd_reloc_outofrange: |
case bfd_reloc_outofrange: |
972 |
(info, msg, name, input_bfd, input_section, rel->r_offset); |
(info, msg, name, input_bfd, input_section, rel->r_offset); |
973 |
|
|
974 |
if (! r) |
if (! r) |
975 |
return false; |
return FALSE; |
976 |
} |
} |
977 |
} |
} |
978 |
|
|
979 |
return true; |
return TRUE; |
980 |
} |
} |
981 |
|
|
982 |
/* This must exist if dynobj is ever set. */ |
/* This must exist if dynobj is ever set. */ |
983 |
|
|
984 |
static boolean |
static bfd_boolean |
985 |
xstormy16_elf_finish_dynamic_sections (abfd, info) |
xstormy16_elf_finish_dynamic_sections (abfd, info) |
986 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
987 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
996 |
&& (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL) |
&& (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL) |
997 |
{ |
{ |
998 |
bfd_byte *contents = splt->contents; |
bfd_byte *contents = splt->contents; |
999 |
unsigned int i, size = splt->_raw_size; |
unsigned int i, size = splt->size; |
1000 |
for (i = 0; i < size; i += 4) |
for (i = 0; i < size; i += 4) |
1001 |
{ |
{ |
1002 |
unsigned int x = bfd_get_32 (dynobj, contents + i); |
unsigned int x = bfd_get_32 (dynobj, contents + i); |
1004 |
} |
} |
1005 |
} |
} |
1006 |
|
|
1007 |
return true; |
return TRUE; |
1008 |
} |
} |
1009 |
|
|
1010 |
/* Return the section that should be marked against GC for a given |
/* Return the section that should be marked against GC for a given |
1049 |
|
|
1050 |
/* Update the got entry reference counts for the section being removed. */ |
/* Update the got entry reference counts for the section being removed. */ |
1051 |
|
|
1052 |
static boolean |
static bfd_boolean |
1053 |
xstormy16_elf_gc_sweep_hook (abfd, info, sec, relocs) |
xstormy16_elf_gc_sweep_hook (abfd, info, sec, relocs) |
1054 |
bfd * abfd ATTRIBUTE_UNUSED; |
bfd * abfd ATTRIBUTE_UNUSED; |
1055 |
struct bfd_link_info * info ATTRIBUTE_UNUSED; |
struct bfd_link_info * info ATTRIBUTE_UNUSED; |
1056 |
asection * sec ATTRIBUTE_UNUSED; |
asection * sec ATTRIBUTE_UNUSED; |
1057 |
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; |
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; |
1058 |
{ |
{ |
1059 |
return true; |
return TRUE; |
1060 |
} |
} |
1061 |
|
|
1062 |
#define ELF_ARCH bfd_arch_xstormy16 |
#define ELF_ARCH bfd_arch_xstormy16 |