/src/binutils-gdb/bfd/elf32-vax.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* VAX series support for 32-bit ELF |
2 | | Copyright (C) 1993-2025 Free Software Foundation, Inc. |
3 | | Contributed by Matt Thomas <matt@3am-software.com>. |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | #include "sysdep.h" |
23 | | #include "bfd.h" |
24 | | #include "bfdlink.h" |
25 | | #include "libbfd.h" |
26 | | #include "elf-bfd.h" |
27 | | #include "elf/vax.h" |
28 | | |
29 | | static reloc_howto_type *reloc_type_lookup (bfd *, bfd_reloc_code_real_type); |
30 | | static bool rtype_to_howto (bfd *, arelent *, Elf_Internal_Rela *); |
31 | | static struct bfd_hash_entry *elf_vax_link_hash_newfunc (struct bfd_hash_entry *, |
32 | | struct bfd_hash_table *, |
33 | | const char *); |
34 | | static struct bfd_link_hash_table *elf_vax_link_hash_table_create (bfd *); |
35 | | static bool elf_vax_check_relocs (bfd *, struct bfd_link_info *, |
36 | | asection *, const Elf_Internal_Rela *); |
37 | | static bool elf_vax_adjust_dynamic_symbol (struct bfd_link_info *, |
38 | | struct elf_link_hash_entry *); |
39 | | static int elf_vax_relocate_section (bfd *, struct bfd_link_info *, |
40 | | bfd *, asection *, bfd_byte *, |
41 | | Elf_Internal_Rela *, |
42 | | Elf_Internal_Sym *, asection **); |
43 | | static bool elf_vax_finish_dynamic_symbol (bfd *, struct bfd_link_info *, |
44 | | struct elf_link_hash_entry *, |
45 | | Elf_Internal_Sym *); |
46 | | static bool elf_vax_finish_dynamic_sections (bfd *, struct bfd_link_info *); |
47 | | static bfd_vma elf_vax_plt_sym_val (bfd_vma, const asection *, |
48 | | const arelent *); |
49 | | |
50 | | static bool elf32_vax_set_private_flags (bfd *, flagword); |
51 | | static bool elf32_vax_print_private_bfd_data (bfd *, void *); |
52 | | |
53 | | static reloc_howto_type howto_table[] = { |
54 | | HOWTO (R_VAX_NONE, /* type */ |
55 | | 0, /* rightshift */ |
56 | | 0, /* size */ |
57 | | 0, /* bitsize */ |
58 | | false, /* pc_relative */ |
59 | | 0, /* bitpos */ |
60 | | complain_overflow_dont, /* complain_on_overflow */ |
61 | | bfd_elf_generic_reloc, /* special_function */ |
62 | | "R_VAX_NONE", /* name */ |
63 | | false, /* partial_inplace */ |
64 | | 0, /* src_mask */ |
65 | | 0x00000000, /* dst_mask */ |
66 | | false), /* pcrel_offset */ |
67 | | |
68 | | HOWTO (R_VAX_32, /* type */ |
69 | | 0, /* rightshift */ |
70 | | 4, /* size */ |
71 | | 32, /* bitsize */ |
72 | | false, /* pc_relative */ |
73 | | 0, /* bitpos */ |
74 | | complain_overflow_bitfield, /* complain_on_overflow */ |
75 | | bfd_elf_generic_reloc, /* special_function */ |
76 | | "R_VAX_32", /* name */ |
77 | | false, /* partial_inplace */ |
78 | | 0, /* src_mask */ |
79 | | 0xffffffff, /* dst_mask */ |
80 | | false), /* pcrel_offset */ |
81 | | |
82 | | HOWTO (R_VAX_16, /* type */ |
83 | | 0, /* rightshift */ |
84 | | 2, /* size */ |
85 | | 16, /* bitsize */ |
86 | | false, /* pc_relative */ |
87 | | 0, /* bitpos */ |
88 | | complain_overflow_bitfield, /* complain_on_overflow */ |
89 | | bfd_elf_generic_reloc, /* special_function */ |
90 | | "R_VAX_16", /* name */ |
91 | | false, /* partial_inplace */ |
92 | | 0, /* src_mask */ |
93 | | 0x0000ffff, /* dst_mask */ |
94 | | false), /* pcrel_offset */ |
95 | | |
96 | | HOWTO (R_VAX_8, /* type */ |
97 | | 0, /* rightshift */ |
98 | | 1, /* size */ |
99 | | 8, /* bitsize */ |
100 | | false, /* pc_relative */ |
101 | | 0, /* bitpos */ |
102 | | complain_overflow_bitfield, /* complain_on_overflow */ |
103 | | bfd_elf_generic_reloc, /* special_function */ |
104 | | "R_VAX_8", /* name */ |
105 | | false, /* partial_inplace */ |
106 | | 0, /* src_mask */ |
107 | | 0x000000ff, /* dst_mask */ |
108 | | false), /* pcrel_offset */ |
109 | | |
110 | | HOWTO (R_VAX_PC32, /* type */ |
111 | | 0, /* rightshift */ |
112 | | 4, /* size */ |
113 | | 32, /* bitsize */ |
114 | | true, /* pc_relative */ |
115 | | 0, /* bitpos */ |
116 | | complain_overflow_bitfield, /* complain_on_overflow */ |
117 | | bfd_elf_generic_reloc, /* special_function */ |
118 | | "R_VAX_PC32", /* name */ |
119 | | false, /* partial_inplace */ |
120 | | 0, /* src_mask */ |
121 | | 0xffffffff, /* dst_mask */ |
122 | | true), /* pcrel_offset */ |
123 | | |
124 | | HOWTO (R_VAX_PC16, /* type */ |
125 | | 0, /* rightshift */ |
126 | | 2, /* size */ |
127 | | 16, /* bitsize */ |
128 | | true, /* pc_relative */ |
129 | | 0, /* bitpos */ |
130 | | complain_overflow_signed, /* complain_on_overflow */ |
131 | | bfd_elf_generic_reloc, /* special_function */ |
132 | | "R_VAX_PC16", /* name */ |
133 | | false, /* partial_inplace */ |
134 | | 0, /* src_mask */ |
135 | | 0x0000ffff, /* dst_mask */ |
136 | | true), /* pcrel_offset */ |
137 | | |
138 | | HOWTO (R_VAX_PC8, /* type */ |
139 | | 0, /* rightshift */ |
140 | | 1, /* size */ |
141 | | 8, /* bitsize */ |
142 | | true, /* pc_relative */ |
143 | | 0, /* bitpos */ |
144 | | complain_overflow_signed, /* complain_on_overflow */ |
145 | | bfd_elf_generic_reloc, /* special_function */ |
146 | | "R_VAX_PC8", /* name */ |
147 | | false, /* partial_inplace */ |
148 | | 0, /* src_mask */ |
149 | | 0x000000ff, /* dst_mask */ |
150 | | true), /* pcrel_offset */ |
151 | | |
152 | | HOWTO (R_VAX_GOT32, /* type */ |
153 | | 0, /* rightshift */ |
154 | | 4, /* size */ |
155 | | 32, /* bitsize */ |
156 | | true, /* pc_relative */ |
157 | | 0, /* bitpos */ |
158 | | complain_overflow_bitfield, /* complain_on_overflow */ |
159 | | bfd_elf_generic_reloc, /* special_function */ |
160 | | "R_VAX_GOT32", /* name */ |
161 | | false, /* partial_inplace */ |
162 | | 0, /* src_mask */ |
163 | | 0xffffffff, /* dst_mask */ |
164 | | true), /* pcrel_offset */ |
165 | | |
166 | | EMPTY_HOWTO (-1), |
167 | | EMPTY_HOWTO (-1), |
168 | | EMPTY_HOWTO (-1), |
169 | | EMPTY_HOWTO (-1), |
170 | | EMPTY_HOWTO (-1), |
171 | | |
172 | | HOWTO (R_VAX_PLT32, /* type */ |
173 | | 0, /* rightshift */ |
174 | | 4, /* size */ |
175 | | 32, /* bitsize */ |
176 | | true, /* pc_relative */ |
177 | | 0, /* bitpos */ |
178 | | complain_overflow_bitfield, /* complain_on_overflow */ |
179 | | bfd_elf_generic_reloc, /* special_function */ |
180 | | "R_VAX_PLT32", /* name */ |
181 | | false, /* partial_inplace */ |
182 | | 0, /* src_mask */ |
183 | | 0xffffffff, /* dst_mask */ |
184 | | true), /* pcrel_offset */ |
185 | | |
186 | | EMPTY_HOWTO (-1), |
187 | | EMPTY_HOWTO (-1), |
188 | | EMPTY_HOWTO (-1), |
189 | | EMPTY_HOWTO (-1), |
190 | | EMPTY_HOWTO (-1), |
191 | | |
192 | | HOWTO (R_VAX_COPY, /* type */ |
193 | | 0, /* rightshift */ |
194 | | 0, /* size */ |
195 | | 0, /* bitsize */ |
196 | | false, /* pc_relative */ |
197 | | 0, /* bitpos */ |
198 | | complain_overflow_dont, /* complain_on_overflow */ |
199 | | bfd_elf_generic_reloc, /* special_function */ |
200 | | "R_VAX_COPY", /* name */ |
201 | | false, /* partial_inplace */ |
202 | | 0, /* src_mask */ |
203 | | 0xffffffff, /* dst_mask */ |
204 | | false), /* pcrel_offset */ |
205 | | |
206 | | HOWTO (R_VAX_GLOB_DAT, /* type */ |
207 | | 0, /* rightshift */ |
208 | | 4, /* size */ |
209 | | 32, /* bitsize */ |
210 | | false, /* pc_relative */ |
211 | | 0, /* bitpos */ |
212 | | complain_overflow_dont, /* complain_on_overflow */ |
213 | | bfd_elf_generic_reloc, /* special_function */ |
214 | | "R_VAX_GLOB_DAT", /* name */ |
215 | | false, /* partial_inplace */ |
216 | | 0, /* src_mask */ |
217 | | 0xffffffff, /* dst_mask */ |
218 | | false), /* pcrel_offset */ |
219 | | |
220 | | HOWTO (R_VAX_JMP_SLOT, /* type */ |
221 | | 0, /* rightshift */ |
222 | | 4, /* size */ |
223 | | 32, /* bitsize */ |
224 | | false, /* pc_relative */ |
225 | | 0, /* bitpos */ |
226 | | complain_overflow_dont, /* complain_on_overflow */ |
227 | | bfd_elf_generic_reloc, /* special_function */ |
228 | | "R_VAX_JMP_SLOT", /* name */ |
229 | | false, /* partial_inplace */ |
230 | | 0, /* src_mask */ |
231 | | 0xffffffff, /* dst_mask */ |
232 | | false), /* pcrel_offset */ |
233 | | |
234 | | HOWTO (R_VAX_RELATIVE, /* type */ |
235 | | 0, /* rightshift */ |
236 | | 4, /* size */ |
237 | | 32, /* bitsize */ |
238 | | false, /* pc_relative */ |
239 | | 0, /* bitpos */ |
240 | | complain_overflow_dont, /* complain_on_overflow */ |
241 | | bfd_elf_generic_reloc, /* special_function */ |
242 | | "R_VAX_RELATIVE", /* name */ |
243 | | false, /* partial_inplace */ |
244 | | 0, /* src_mask */ |
245 | | 0xffffffff, /* dst_mask */ |
246 | | false), /* pcrel_offset */ |
247 | | |
248 | | /* GNU extension to record C++ vtable hierarchy */ |
249 | | HOWTO (R_VAX_GNU_VTINHERIT, /* type */ |
250 | | 0, /* rightshift */ |
251 | | 4, /* size */ |
252 | | 0, /* bitsize */ |
253 | | false, /* pc_relative */ |
254 | | 0, /* bitpos */ |
255 | | complain_overflow_dont, /* complain_on_overflow */ |
256 | | NULL, /* special_function */ |
257 | | "R_VAX_GNU_VTINHERIT", /* name */ |
258 | | false, /* partial_inplace */ |
259 | | 0, /* src_mask */ |
260 | | 0, /* dst_mask */ |
261 | | false), /* pcrel_offset */ |
262 | | |
263 | | /* GNU extension to record C++ vtable member usage */ |
264 | | HOWTO (R_VAX_GNU_VTENTRY, /* type */ |
265 | | 0, /* rightshift */ |
266 | | 4, /* size */ |
267 | | 0, /* bitsize */ |
268 | | false, /* pc_relative */ |
269 | | 0, /* bitpos */ |
270 | | complain_overflow_dont, /* complain_on_overflow */ |
271 | | _bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
272 | | "R_VAX_GNU_VTENTRY", /* name */ |
273 | | false, /* partial_inplace */ |
274 | | 0, /* src_mask */ |
275 | | 0, /* dst_mask */ |
276 | | false), /* pcrel_offset */ |
277 | | }; |
278 | | |
279 | | static bool |
280 | | rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) |
281 | 37 | { |
282 | 37 | unsigned int r_type; |
283 | | |
284 | 37 | r_type = ELF32_R_TYPE (dst->r_info); |
285 | 37 | if (r_type >= R_VAX_max) |
286 | 4 | { |
287 | | /* xgettext:c-format */ |
288 | 4 | _bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
289 | 4 | abfd, r_type); |
290 | 4 | bfd_set_error (bfd_error_bad_value); |
291 | 4 | return false; |
292 | 4 | } |
293 | 33 | cache_ptr->howto = &howto_table[r_type]; |
294 | 33 | return true; |
295 | 37 | } |
296 | | |
297 | | #define elf_info_to_howto rtype_to_howto |
298 | | |
299 | | static const struct |
300 | | { |
301 | | bfd_reloc_code_real_type bfd_val; |
302 | | int elf_val; |
303 | | } reloc_map[] = { |
304 | | { BFD_RELOC_NONE, R_VAX_NONE }, |
305 | | { BFD_RELOC_32, R_VAX_32 }, |
306 | | { BFD_RELOC_16, R_VAX_16 }, |
307 | | { BFD_RELOC_8, R_VAX_8 }, |
308 | | { BFD_RELOC_32_PCREL, R_VAX_PC32 }, |
309 | | { BFD_RELOC_16_PCREL, R_VAX_PC16 }, |
310 | | { BFD_RELOC_8_PCREL, R_VAX_PC8 }, |
311 | | { BFD_RELOC_32_GOT_PCREL, R_VAX_GOT32 }, |
312 | | { BFD_RELOC_32_PLT_PCREL, R_VAX_PLT32 }, |
313 | | { BFD_RELOC_NONE, R_VAX_COPY }, |
314 | | { BFD_RELOC_VAX_GLOB_DAT, R_VAX_GLOB_DAT }, |
315 | | { BFD_RELOC_VAX_JMP_SLOT, R_VAX_JMP_SLOT }, |
316 | | { BFD_RELOC_VAX_RELATIVE, R_VAX_RELATIVE }, |
317 | | { BFD_RELOC_CTOR, R_VAX_32 }, |
318 | | { BFD_RELOC_VTABLE_INHERIT, R_VAX_GNU_VTINHERIT }, |
319 | | { BFD_RELOC_VTABLE_ENTRY, R_VAX_GNU_VTENTRY }, |
320 | | }; |
321 | | |
322 | | static reloc_howto_type * |
323 | | reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) |
324 | 0 | { |
325 | 0 | unsigned int i; |
326 | 0 | for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++) |
327 | 0 | { |
328 | 0 | if (reloc_map[i].bfd_val == code) |
329 | 0 | return &howto_table[reloc_map[i].elf_val]; |
330 | 0 | } |
331 | 0 | return 0; |
332 | 0 | } |
333 | | |
334 | | static reloc_howto_type * |
335 | | reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
336 | | const char *r_name) |
337 | 0 | { |
338 | 0 | unsigned int i; |
339 | |
|
340 | 0 | for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++) |
341 | 0 | if (howto_table[i].name != NULL |
342 | 0 | && strcasecmp (howto_table[i].name, r_name) == 0) |
343 | 0 | return &howto_table[i]; |
344 | | |
345 | 0 | return NULL; |
346 | 0 | } |
347 | | |
348 | | #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup |
349 | | #define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup |
350 | | #define ELF_ARCH bfd_arch_vax |
351 | | /* end code generated by elf.el */ |
352 | | |
353 | | /* Functions for the VAX ELF linker. */ |
354 | | |
355 | | /* The name of the dynamic interpreter. This is put in the .interp |
356 | | section. */ |
357 | | |
358 | 0 | #define ELF_DYNAMIC_INTERPRETER "/usr/libexec/ld.elf_so" |
359 | | |
360 | | /* The size in bytes of an entry in the procedure linkage table. */ |
361 | | |
362 | 0 | #define PLT_ENTRY_SIZE 12 |
363 | | |
364 | | /* The first entry in a procedure linkage table looks like this. See |
365 | | the SVR4 ABI VAX supplement to see how this works. */ |
366 | | |
367 | | static const bfd_byte elf_vax_plt0_entry[PLT_ENTRY_SIZE] = |
368 | | { |
369 | | 0xdd, 0xef, /* pushl l^ */ |
370 | | 0, 0, 0, 0, /* offset to .plt.got + 4 */ |
371 | | 0x17, 0xff, /* jmp @L^(pc) */ |
372 | | 0, 0, 0, 0, /* offset to .plt.got + 8 */ |
373 | | }; |
374 | | |
375 | | /* Subsequent entries in a procedure linkage table look like this. */ |
376 | | |
377 | | static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] = |
378 | | { |
379 | | 0xfc, 0x0f, /* .word ^M<r11:r2> */ |
380 | | 0x16, 0xef, /* jsb L^(pc) */ |
381 | | 0, 0, 0, 0, /* replaced with offset to start of .plt */ |
382 | | 0, 0, 0, 0, /* index into .rela.plt */ |
383 | | }; |
384 | | |
385 | | /* The VAX linker needs to keep track of the number of relocs that it |
386 | | decides to copy in check_relocs for each symbol. This is so that it |
387 | | can discard PC relative relocs if it doesn't need them when linking |
388 | | with -Bsymbolic. We store the information in a field extending the |
389 | | regular ELF linker hash table. */ |
390 | | |
391 | | /* This structure keeps track of the number of PC relative relocs we have |
392 | | copied for a given symbol. */ |
393 | | |
394 | | struct elf_vax_pcrel_relocs_copied |
395 | | { |
396 | | /* Next section. */ |
397 | | struct elf_vax_pcrel_relocs_copied *next; |
398 | | /* A section in dynobj. */ |
399 | | asection *section; |
400 | | /* Number of relocs copied in this section. */ |
401 | | bfd_size_type count; |
402 | | }; |
403 | | |
404 | | /* VAX ELF linker hash entry. */ |
405 | | |
406 | | struct elf_vax_link_hash_entry |
407 | | { |
408 | | struct elf_link_hash_entry root; |
409 | | |
410 | | /* Number of PC relative relocs copied for this symbol. */ |
411 | | struct elf_vax_pcrel_relocs_copied *pcrel_relocs_copied; |
412 | | |
413 | | bfd_vma got_addend; |
414 | | }; |
415 | | |
416 | | /* Declare this now that the above structures are defined. */ |
417 | | |
418 | | static bool elf_vax_discard_copies (struct elf_vax_link_hash_entry *, |
419 | | void *); |
420 | | |
421 | | /* Declare this now that the above structures are defined. */ |
422 | | |
423 | | static bool elf_vax_instantiate_got_entries (struct elf_link_hash_entry *, |
424 | | void *); |
425 | | |
426 | | /* Traverse an VAX ELF linker hash table. */ |
427 | | |
428 | | #define elf_vax_link_hash_traverse(table, func, info) \ |
429 | 0 | (elf_link_hash_traverse \ |
430 | 0 | ((table), \ |
431 | 0 | (bool (*) (struct elf_link_hash_entry *, void *)) (func), \ |
432 | 0 | (info))) |
433 | | |
434 | | /* Create an entry in an VAX ELF linker hash table. */ |
435 | | |
436 | | static struct bfd_hash_entry * |
437 | | elf_vax_link_hash_newfunc (struct bfd_hash_entry *entry, |
438 | | struct bfd_hash_table *table, |
439 | | const char *string) |
440 | 0 | { |
441 | 0 | struct elf_vax_link_hash_entry *ret = |
442 | 0 | (struct elf_vax_link_hash_entry *) entry; |
443 | | |
444 | | /* Allocate the structure if it has not already been allocated by a |
445 | | subclass. */ |
446 | 0 | if (ret == NULL) |
447 | 0 | ret = ((struct elf_vax_link_hash_entry *) |
448 | 0 | bfd_hash_allocate (table, |
449 | 0 | sizeof (struct elf_vax_link_hash_entry))); |
450 | 0 | if (ret == NULL) |
451 | 0 | return (struct bfd_hash_entry *) ret; |
452 | | |
453 | | /* Call the allocation method of the superclass. */ |
454 | 0 | ret = ((struct elf_vax_link_hash_entry *) |
455 | 0 | _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, |
456 | 0 | table, string)); |
457 | 0 | if (ret != NULL) |
458 | 0 | { |
459 | 0 | ret->pcrel_relocs_copied = NULL; |
460 | 0 | } |
461 | |
|
462 | 0 | return (struct bfd_hash_entry *) ret; |
463 | 0 | } |
464 | | |
465 | | /* Create an VAX ELF linker hash table. */ |
466 | | |
467 | | static struct bfd_link_hash_table * |
468 | | elf_vax_link_hash_table_create (bfd *abfd) |
469 | 0 | { |
470 | 0 | struct elf_link_hash_table *ret; |
471 | 0 | size_t amt = sizeof (struct elf_link_hash_table); |
472 | |
|
473 | 0 | ret = bfd_zmalloc (amt); |
474 | 0 | if (ret == NULL) |
475 | 0 | return NULL; |
476 | | |
477 | 0 | if (!_bfd_elf_link_hash_table_init (ret, abfd, |
478 | 0 | elf_vax_link_hash_newfunc, |
479 | 0 | sizeof (struct elf_vax_link_hash_entry))) |
480 | 0 | { |
481 | 0 | free (ret); |
482 | 0 | return NULL; |
483 | 0 | } |
484 | | |
485 | 0 | return &ret->root; |
486 | 0 | } |
487 | | |
488 | | /* Keep vax-specific flags in the ELF header */ |
489 | | static bool |
490 | | elf32_vax_set_private_flags (bfd *abfd, flagword flags) |
491 | 0 | { |
492 | 0 | elf_elfheader (abfd)->e_flags = flags; |
493 | 0 | elf_flags_init (abfd) = true; |
494 | 0 | return true; |
495 | 0 | } |
496 | | |
497 | | /* Merge backend specific data from an object file to the output |
498 | | object file when linking. */ |
499 | | static bool |
500 | | elf32_vax_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) |
501 | 0 | { |
502 | 0 | bfd *obfd = info->output_bfd; |
503 | 0 | flagword in_flags; |
504 | |
|
505 | 0 | if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
506 | 0 | || bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
507 | 0 | return true; |
508 | | |
509 | 0 | in_flags = elf_elfheader (ibfd)->e_flags; |
510 | |
|
511 | 0 | if (!elf_flags_init (obfd)) |
512 | 0 | { |
513 | 0 | elf_flags_init (obfd) = true; |
514 | 0 | elf_elfheader (obfd)->e_flags = in_flags; |
515 | 0 | } |
516 | |
|
517 | 0 | return true; |
518 | 0 | } |
519 | | |
520 | | /* Display the flags field */ |
521 | | static bool |
522 | | elf32_vax_print_private_bfd_data (bfd *abfd, void * ptr) |
523 | 3 | { |
524 | 3 | FILE *file = (FILE *) ptr; |
525 | | |
526 | 3 | BFD_ASSERT (abfd != NULL && ptr != NULL); |
527 | | |
528 | | /* Print normal ELF private data. */ |
529 | 3 | _bfd_elf_print_private_bfd_data (abfd, ptr); |
530 | | |
531 | | /* Ignore init flag - it may not be set, despite the flags field containing valid data. */ |
532 | | |
533 | | /* xgettext:c-format */ |
534 | 3 | fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); |
535 | | |
536 | 3 | if (elf_elfheader (abfd)->e_flags & EF_VAX_NONPIC) |
537 | 1 | fprintf (file, _(" [nonpic]")); |
538 | | |
539 | 3 | if (elf_elfheader (abfd)->e_flags & EF_VAX_DFLOAT) |
540 | 2 | fprintf (file, _(" [d-float]")); |
541 | | |
542 | 3 | if (elf_elfheader (abfd)->e_flags & EF_VAX_GFLOAT) |
543 | 1 | fprintf (file, _(" [g-float]")); |
544 | | |
545 | 3 | fputc ('\n', file); |
546 | | |
547 | 3 | return true; |
548 | 3 | } |
549 | | /* Look through the relocs for a section during the first phase, and |
550 | | allocate space in the global offset table or procedure linkage |
551 | | table. */ |
552 | | |
553 | | static bool |
554 | | elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, |
555 | | const Elf_Internal_Rela *relocs) |
556 | 0 | { |
557 | 0 | bfd *dynobj; |
558 | 0 | Elf_Internal_Shdr *symtab_hdr; |
559 | 0 | struct elf_link_hash_entry **sym_hashes; |
560 | 0 | const Elf_Internal_Rela *rel; |
561 | 0 | const Elf_Internal_Rela *rel_end; |
562 | 0 | asection *sreloc; |
563 | |
|
564 | 0 | if (bfd_link_relocatable (info)) |
565 | 0 | return true; |
566 | | |
567 | 0 | dynobj = elf_hash_table (info)->dynobj; |
568 | 0 | symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
569 | 0 | sym_hashes = elf_sym_hashes (abfd); |
570 | |
|
571 | 0 | sreloc = NULL; |
572 | |
|
573 | 0 | rel_end = relocs + sec->reloc_count; |
574 | 0 | for (rel = relocs; rel < rel_end; rel++) |
575 | 0 | { |
576 | 0 | unsigned long r_symndx; |
577 | 0 | struct elf_link_hash_entry *h; |
578 | |
|
579 | 0 | r_symndx = ELF32_R_SYM (rel->r_info); |
580 | |
|
581 | 0 | if (r_symndx < symtab_hdr->sh_info) |
582 | 0 | h = NULL; |
583 | 0 | else |
584 | 0 | { |
585 | 0 | h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
586 | 0 | while (h->root.type == bfd_link_hash_indirect |
587 | 0 | || h->root.type == bfd_link_hash_warning) |
588 | 0 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
589 | 0 | } |
590 | |
|
591 | 0 | switch (ELF32_R_TYPE (rel->r_info)) |
592 | 0 | { |
593 | 0 | case R_VAX_GOT32: |
594 | 0 | BFD_ASSERT (h != NULL); |
595 | | |
596 | | /* If this is a local symbol, we resolve it directly without |
597 | | creating a global offset table entry. */ |
598 | 0 | if (SYMBOL_REFERENCES_LOCAL (info, h) |
599 | 0 | || h == elf_hash_table (info)->hgot |
600 | 0 | || h == elf_hash_table (info)->hplt) |
601 | 0 | break; |
602 | | |
603 | | /* This symbol requires a global offset table entry. */ |
604 | | |
605 | 0 | if (dynobj == NULL) |
606 | 0 | { |
607 | | /* Create the .got section. */ |
608 | 0 | elf_hash_table (info)->dynobj = dynobj = abfd; |
609 | 0 | if (!_bfd_elf_create_got_section (dynobj, info)) |
610 | 0 | return false; |
611 | 0 | } |
612 | | |
613 | 0 | if (h != NULL) |
614 | 0 | { |
615 | 0 | struct elf_vax_link_hash_entry *eh; |
616 | |
|
617 | 0 | eh = (struct elf_vax_link_hash_entry *) h; |
618 | 0 | if (h->got.refcount == -1) |
619 | 0 | { |
620 | 0 | h->got.refcount = 1; |
621 | 0 | eh->got_addend = rel->r_addend; |
622 | 0 | } |
623 | 0 | else |
624 | 0 | { |
625 | 0 | h->got.refcount++; |
626 | 0 | if (eh->got_addend != (bfd_vma) rel->r_addend) |
627 | 0 | _bfd_error_handler |
628 | | /* xgettext:c-format */ |
629 | 0 | (_("%pB: warning: GOT addend of %" PRId64 " to `%s' does" |
630 | 0 | " not match previous GOT addend of %" PRId64), |
631 | 0 | abfd, (int64_t) rel->r_addend, h->root.root.string, |
632 | 0 | (int64_t) eh->got_addend); |
633 | |
|
634 | 0 | } |
635 | 0 | } |
636 | 0 | break; |
637 | | |
638 | 0 | case R_VAX_PLT32: |
639 | | /* This symbol requires a procedure linkage table entry. We |
640 | | actually build the entry in adjust_dynamic_symbol, |
641 | | because this might be a case of linking PIC code which is |
642 | | never referenced by a dynamic object, in which case we |
643 | | don't need to generate a procedure linkage table entry |
644 | | after all. */ |
645 | 0 | BFD_ASSERT (h != NULL); |
646 | | |
647 | | /* If this is a local symbol, we resolve it directly without |
648 | | creating a procedure linkage table entry. */ |
649 | 0 | if (h->forced_local) |
650 | 0 | break; |
651 | | |
652 | 0 | h->needs_plt = 1; |
653 | 0 | if (h->plt.refcount == -1) |
654 | 0 | h->plt.refcount = 1; |
655 | 0 | else |
656 | 0 | h->plt.refcount++; |
657 | 0 | break; |
658 | | |
659 | 0 | case R_VAX_PC8: |
660 | 0 | case R_VAX_PC16: |
661 | 0 | case R_VAX_PC32: |
662 | | /* If we are creating a shared library and this is not a local |
663 | | symbol, we need to copy the reloc into the shared library. |
664 | | However when linking with -Bsymbolic and this is a global |
665 | | symbol which is defined in an object we are including in the |
666 | | link (i.e., DEF_REGULAR is set), then we can resolve the |
667 | | reloc directly. At this point we have not seen all the input |
668 | | files, so it is possible that DEF_REGULAR is not set now but |
669 | | will be set later (it is never cleared). We account for that |
670 | | possibility below by storing information in the |
671 | | pcrel_relocs_copied field of the hash table entry. */ |
672 | 0 | if (!(bfd_link_pic (info) |
673 | 0 | && (sec->flags & SEC_ALLOC) != 0 |
674 | 0 | && h != NULL |
675 | 0 | && (!info->symbolic |
676 | 0 | || !h->def_regular))) |
677 | 0 | { |
678 | 0 | if (h != NULL |
679 | 0 | && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
680 | 0 | && !h->forced_local) |
681 | 0 | { |
682 | | /* Make sure a plt entry is created for this symbol if |
683 | | it turns out to be a function defined by a dynamic |
684 | | object. */ |
685 | 0 | if (h->plt.refcount == -1) |
686 | 0 | h->plt.refcount = 1; |
687 | 0 | else |
688 | 0 | h->plt.refcount++; |
689 | 0 | } |
690 | 0 | break; |
691 | 0 | } |
692 | | /* If this is a local symbol, we can resolve it directly. */ |
693 | 0 | if (h != NULL |
694 | 0 | && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
695 | 0 | || h->forced_local)) |
696 | 0 | break; |
697 | | |
698 | | /* Fall through. */ |
699 | 0 | case R_VAX_8: |
700 | 0 | case R_VAX_16: |
701 | 0 | case R_VAX_32: |
702 | 0 | if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) |
703 | 0 | { |
704 | | /* Make sure a plt entry is created for this symbol if it |
705 | | turns out to be a function defined by a dynamic object. */ |
706 | 0 | if (h->plt.refcount == -1) |
707 | 0 | h->plt.refcount = 1; |
708 | 0 | else |
709 | 0 | h->plt.refcount++; |
710 | 0 | } |
711 | | |
712 | | /* Non-GOT reference may need a copy reloc in executable or |
713 | | a dynamic reloc in shared library. */ |
714 | 0 | if (h != NULL) |
715 | 0 | h->non_got_ref = 1; |
716 | | |
717 | | /* If we are creating a shared library, we need to copy the |
718 | | reloc into the shared library. */ |
719 | 0 | if (bfd_link_pic (info) |
720 | 0 | && (sec->flags & SEC_ALLOC) != 0) |
721 | 0 | { |
722 | | /* When creating a shared object, we must copy these |
723 | | reloc types into the output file. We create a reloc |
724 | | section in dynobj and make room for this reloc. */ |
725 | 0 | if (sreloc == NULL) |
726 | 0 | { |
727 | 0 | sreloc = _bfd_elf_make_dynamic_reloc_section |
728 | 0 | (sec, dynobj, 2, abfd, /*rela?*/ true); |
729 | |
|
730 | 0 | if (sreloc == NULL) |
731 | 0 | return false; |
732 | | |
733 | 0 | if (sec->flags & SEC_READONLY) |
734 | 0 | info->flags |= DF_TEXTREL; |
735 | 0 | } |
736 | | |
737 | 0 | sreloc->size += sizeof (Elf32_External_Rela); |
738 | | |
739 | | /* If we are linking with -Bsymbolic, we count the number of |
740 | | PC relative relocations we have entered for this symbol, |
741 | | so that we can discard them again if the symbol is later |
742 | | defined by a regular object. Note that this function is |
743 | | only called if we are using a vaxelf linker hash table, |
744 | | which means that h is really a pointer to an |
745 | | elf_vax_link_hash_entry. */ |
746 | 0 | if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8 |
747 | 0 | || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16 |
748 | 0 | || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32) |
749 | 0 | && info->symbolic) |
750 | 0 | { |
751 | 0 | struct elf_vax_link_hash_entry *eh; |
752 | 0 | struct elf_vax_pcrel_relocs_copied *p; |
753 | |
|
754 | 0 | eh = (struct elf_vax_link_hash_entry *) h; |
755 | |
|
756 | 0 | for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next) |
757 | 0 | if (p->section == sreloc) |
758 | 0 | break; |
759 | |
|
760 | 0 | if (p == NULL) |
761 | 0 | { |
762 | 0 | p = ((struct elf_vax_pcrel_relocs_copied *) |
763 | 0 | bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); |
764 | 0 | if (p == NULL) |
765 | 0 | return false; |
766 | 0 | p->next = eh->pcrel_relocs_copied; |
767 | 0 | eh->pcrel_relocs_copied = p; |
768 | 0 | p->section = sreloc; |
769 | 0 | p->count = 0; |
770 | 0 | } |
771 | | |
772 | 0 | ++p->count; |
773 | 0 | } |
774 | 0 | } |
775 | | |
776 | 0 | break; |
777 | | |
778 | | /* This relocation describes the C++ object vtable hierarchy. |
779 | | Reconstruct it for later use during GC. */ |
780 | 0 | case R_VAX_GNU_VTINHERIT: |
781 | 0 | if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
782 | 0 | return false; |
783 | 0 | break; |
784 | | |
785 | | /* This relocation describes which C++ vtable entries are actually |
786 | | used. Record for later use during GC. */ |
787 | 0 | case R_VAX_GNU_VTENTRY: |
788 | 0 | if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
789 | 0 | return false; |
790 | 0 | break; |
791 | | |
792 | 0 | default: |
793 | 0 | break; |
794 | 0 | } |
795 | 0 | } |
796 | | |
797 | 0 | return true; |
798 | 0 | } |
799 | | |
800 | | /* Return the section that should be marked against GC for a given |
801 | | relocation. */ |
802 | | |
803 | | static asection * |
804 | | elf_vax_gc_mark_hook (asection *sec, |
805 | | struct bfd_link_info *info, |
806 | | Elf_Internal_Rela *rel, |
807 | | struct elf_link_hash_entry *h, |
808 | | Elf_Internal_Sym *sym) |
809 | 0 | { |
810 | 0 | if (h != NULL) |
811 | 0 | switch (ELF32_R_TYPE (rel->r_info)) |
812 | 0 | { |
813 | 0 | case R_VAX_GNU_VTINHERIT: |
814 | 0 | case R_VAX_GNU_VTENTRY: |
815 | 0 | return NULL; |
816 | 0 | } |
817 | | |
818 | 0 | return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); |
819 | 0 | } |
820 | | |
821 | | /* Adjust a symbol defined by a dynamic object and referenced by a |
822 | | regular object. The current definition is in some section of the |
823 | | dynamic object, but we're not including those sections. We have to |
824 | | change the definition to something the rest of the link can |
825 | | understand. */ |
826 | | |
827 | | static bool |
828 | | elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info, |
829 | | struct elf_link_hash_entry *h) |
830 | 0 | { |
831 | 0 | bfd *dynobj; |
832 | 0 | asection *s; |
833 | |
|
834 | 0 | dynobj = elf_hash_table (info)->dynobj; |
835 | | |
836 | | /* Make sure we know what is going on here. */ |
837 | 0 | BFD_ASSERT (dynobj != NULL |
838 | 0 | && (h->needs_plt |
839 | 0 | || h->is_weakalias |
840 | 0 | || (h->def_dynamic |
841 | 0 | && h->ref_regular |
842 | 0 | && !h->def_regular))); |
843 | | |
844 | | /* If this is a function, put it in the procedure linkage table. We |
845 | | will fill in the contents of the procedure linkage table later, |
846 | | when we know the address of the .got section. */ |
847 | 0 | if (h->type == STT_FUNC |
848 | 0 | || h->needs_plt) |
849 | 0 | { |
850 | 0 | if (h->plt.refcount <= 0 |
851 | 0 | || SYMBOL_CALLS_LOCAL (info, h) |
852 | 0 | || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
853 | 0 | && h->root.type == bfd_link_hash_undefweak)) |
854 | 0 | { |
855 | | /* This case can occur if we saw a PLTxx reloc in an input |
856 | | file, but the symbol was never referred to by a dynamic |
857 | | object, or if all references were garbage collected. In |
858 | | such a case, we don't actually need to build a procedure |
859 | | linkage table, and we can just do a PCxx reloc instead. */ |
860 | 0 | h->plt.offset = (bfd_vma) -1; |
861 | 0 | h->needs_plt = 0; |
862 | 0 | return true; |
863 | 0 | } |
864 | | |
865 | 0 | s = elf_hash_table (info)->splt; |
866 | 0 | BFD_ASSERT (s != NULL); |
867 | | |
868 | | /* If this is the first .plt entry, make room for the special |
869 | | first entry. */ |
870 | 0 | if (s->size == 0) |
871 | 0 | { |
872 | 0 | s->size += PLT_ENTRY_SIZE; |
873 | 0 | } |
874 | | |
875 | | /* If this symbol is not defined in a regular file, and we are |
876 | | not generating a shared library, then set the symbol to this |
877 | | location in the .plt. This is required to make function |
878 | | pointers compare as equal between the normal executable and |
879 | | the shared library. */ |
880 | 0 | if (!bfd_link_pic (info) |
881 | 0 | && !h->def_regular) |
882 | 0 | { |
883 | 0 | h->root.u.def.section = s; |
884 | 0 | h->root.u.def.value = s->size; |
885 | 0 | } |
886 | |
|
887 | 0 | h->plt.offset = s->size; |
888 | | |
889 | | /* Make room for this entry. */ |
890 | 0 | s->size += PLT_ENTRY_SIZE; |
891 | | |
892 | | /* We also need to make an entry in the .got.plt section, which |
893 | | will be placed in the .got section by the linker script. */ |
894 | |
|
895 | 0 | s = elf_hash_table (info)->sgotplt; |
896 | 0 | BFD_ASSERT (s != NULL); |
897 | 0 | s->size += 4; |
898 | | |
899 | | /* We also need to make an entry in the .rela.plt section. */ |
900 | |
|
901 | 0 | s = elf_hash_table (info)->srelplt; |
902 | 0 | BFD_ASSERT (s != NULL); |
903 | 0 | s->size += sizeof (Elf32_External_Rela); |
904 | |
|
905 | 0 | return true; |
906 | 0 | } |
907 | | |
908 | | /* Reinitialize the plt offset now that it is not used as a reference |
909 | | count any more. */ |
910 | 0 | h->plt.offset = (bfd_vma) -1; |
911 | | |
912 | | /* If this is a weak symbol, and there is a real definition, the |
913 | | processor independent code will have arranged for us to see the |
914 | | real definition first, and we can just use the same value. */ |
915 | 0 | if (h->is_weakalias) |
916 | 0 | { |
917 | 0 | struct elf_link_hash_entry *def = weakdef (h); |
918 | 0 | BFD_ASSERT (def->root.type == bfd_link_hash_defined); |
919 | 0 | h->root.u.def.section = def->root.u.def.section; |
920 | 0 | h->root.u.def.value = def->root.u.def.value; |
921 | 0 | return true; |
922 | 0 | } |
923 | | |
924 | | /* This is a reference to a symbol defined by a dynamic object which |
925 | | is not a function. */ |
926 | | |
927 | | /* If we are creating a shared library, we must presume that the |
928 | | only references to the symbol are via the global offset table. |
929 | | For such cases we need not do anything here; the relocations will |
930 | | be handled correctly by relocate_section. */ |
931 | 0 | if (bfd_link_pic (info)) |
932 | 0 | return true; |
933 | | |
934 | | /* If there are no references to this symbol that do not use the |
935 | | GOT relocation, we don't need to generate a copy reloc. */ |
936 | 0 | if (!h->non_got_ref) |
937 | 0 | return true; |
938 | | |
939 | | /* We must allocate the symbol in our .dynbss section, which will |
940 | | become part of the .bss section of the executable. There will be |
941 | | an entry for this symbol in the .dynsym section. The dynamic |
942 | | object will contain position independent code, so all references |
943 | | from the dynamic object to this symbol will go through the global |
944 | | offset table. The dynamic linker will use the .dynsym entry to |
945 | | determine the address it must put in the global offset table, so |
946 | | both the dynamic object and the regular object will refer to the |
947 | | same memory location for the variable. */ |
948 | | |
949 | 0 | s = bfd_get_linker_section (dynobj, ".dynbss"); |
950 | 0 | BFD_ASSERT (s != NULL); |
951 | | |
952 | | /* We must generate a R_VAX_COPY reloc to tell the dynamic linker to |
953 | | copy the initial value out of the dynamic object and into the |
954 | | runtime process image. We need to remember the offset into the |
955 | | .rela.bss section we are going to use. */ |
956 | 0 | if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) |
957 | 0 | { |
958 | 0 | asection *srel; |
959 | |
|
960 | 0 | srel = bfd_get_linker_section (dynobj, ".rela.bss"); |
961 | 0 | BFD_ASSERT (srel != NULL); |
962 | 0 | srel->size += sizeof (Elf32_External_Rela); |
963 | 0 | h->needs_copy = 1; |
964 | 0 | } |
965 | |
|
966 | 0 | return _bfd_elf_adjust_dynamic_copy (info, h, s); |
967 | 0 | } |
968 | | |
969 | | /* This function is called via elf_link_hash_traverse. It resets GOT |
970 | | and PLT (.GOT) reference counts back to -1 so normal PC32 relocation |
971 | | will be done. */ |
972 | | |
973 | | static bool |
974 | | elf_vax_discard_got_entries (struct elf_link_hash_entry *h, |
975 | | void *infoptr ATTRIBUTE_UNUSED) |
976 | 0 | { |
977 | 0 | h->got.refcount = -1; |
978 | 0 | h->plt.refcount = -1; |
979 | |
|
980 | 0 | return true; |
981 | 0 | } |
982 | | |
983 | | /* Discard unused dynamic data if this is a static link. */ |
984 | | |
985 | | static bool |
986 | | elf_vax_early_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, |
987 | | struct bfd_link_info *info) |
988 | 0 | { |
989 | 0 | bfd *dynobj; |
990 | 0 | asection *s; |
991 | |
|
992 | 0 | dynobj = elf_hash_table (info)->dynobj; |
993 | |
|
994 | 0 | if (dynobj && !elf_hash_table (info)->dynamic_sections_created) |
995 | 0 | { |
996 | | /* We may have created entries in the .rela.got and .got sections. |
997 | | However, if we are not creating the dynamic sections, we will |
998 | | not actually use these entries. Reset the size of .rela.got |
999 | | and .got, which will cause them to get stripped from the output |
1000 | | file below. */ |
1001 | 0 | s = elf_hash_table (info)->srelgot; |
1002 | 0 | if (s != NULL) |
1003 | 0 | s->size = 0; |
1004 | 0 | s = elf_hash_table (info)->sgotplt; |
1005 | 0 | if (s != NULL) |
1006 | 0 | s->size = 0; |
1007 | 0 | s = elf_hash_table (info)->sgot; |
1008 | 0 | if (s != NULL) |
1009 | 0 | s->size = 0; |
1010 | 0 | } |
1011 | | |
1012 | | /* If this is a static link, we need to discard all the got entries we've |
1013 | | recorded. */ |
1014 | 0 | if (!dynobj || !elf_hash_table (info)->dynamic_sections_created) |
1015 | 0 | elf_link_hash_traverse (elf_hash_table (info), |
1016 | 0 | elf_vax_discard_got_entries, |
1017 | 0 | info); |
1018 | |
|
1019 | 0 | return true; |
1020 | 0 | } |
1021 | | |
1022 | | /* Set the sizes of the dynamic sections. */ |
1023 | | |
1024 | | static bool |
1025 | | elf_vax_late_size_sections (bfd *output_bfd, struct bfd_link_info *info) |
1026 | 0 | { |
1027 | 0 | bfd *dynobj; |
1028 | 0 | asection *s; |
1029 | 0 | bool relocs; |
1030 | |
|
1031 | 0 | dynobj = elf_hash_table (info)->dynobj; |
1032 | 0 | if (dynobj == NULL) |
1033 | 0 | return true; |
1034 | | |
1035 | 0 | if (elf_hash_table (info)->dynamic_sections_created) |
1036 | 0 | { |
1037 | | /* Set the contents of the .interp section to the interpreter. */ |
1038 | 0 | if (bfd_link_executable (info) && !info->nointerp) |
1039 | 0 | { |
1040 | 0 | s = bfd_get_linker_section (dynobj, ".interp"); |
1041 | 0 | BFD_ASSERT (s != NULL); |
1042 | 0 | s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
1043 | 0 | s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
1044 | 0 | s->alloced = 1; |
1045 | 0 | } |
1046 | 0 | } |
1047 | | |
1048 | | /* If this is a -Bsymbolic shared link, then we need to discard all PC |
1049 | | relative relocs against symbols defined in a regular object. We |
1050 | | allocated space for them in the check_relocs routine, but we will not |
1051 | | fill them in in the relocate_section routine. */ |
1052 | 0 | if (bfd_link_pic (info) && info->symbolic) |
1053 | 0 | elf_vax_link_hash_traverse (elf_hash_table (info), |
1054 | 0 | elf_vax_discard_copies, |
1055 | 0 | NULL); |
1056 | | |
1057 | | /* If this is a -Bsymbolic shared link, we need to discard all the got |
1058 | | entries we've recorded. Otherwise, we need to instantiate (allocate |
1059 | | space for them). */ |
1060 | 0 | elf_link_hash_traverse (elf_hash_table (info), |
1061 | 0 | elf_vax_instantiate_got_entries, |
1062 | 0 | info); |
1063 | | |
1064 | | /* The check_relocs and adjust_dynamic_symbol entry points have |
1065 | | determined the sizes of the various dynamic sections. Allocate |
1066 | | memory for them. */ |
1067 | 0 | relocs = false; |
1068 | 0 | for (s = dynobj->sections; s != NULL; s = s->next) |
1069 | 0 | { |
1070 | 0 | const char *name; |
1071 | |
|
1072 | 0 | if ((s->flags & SEC_LINKER_CREATED) == 0) |
1073 | 0 | continue; |
1074 | | |
1075 | | /* It's OK to base decisions on the section name, because none |
1076 | | of the dynobj section names depend upon the input files. */ |
1077 | 0 | name = bfd_section_name (s); |
1078 | |
|
1079 | 0 | if (strcmp (name, ".plt") == 0) |
1080 | 0 | { |
1081 | | /* Remember whether there is a PLT. */ |
1082 | 0 | ; |
1083 | 0 | } |
1084 | 0 | else if (startswith (name, ".rela")) |
1085 | 0 | { |
1086 | 0 | if (s->size != 0) |
1087 | 0 | { |
1088 | 0 | if (strcmp (name, ".rela.plt") != 0) |
1089 | 0 | relocs = true; |
1090 | | |
1091 | | /* We use the reloc_count field as a counter if we need |
1092 | | to copy relocs into the output file. */ |
1093 | 0 | s->reloc_count = 0; |
1094 | 0 | } |
1095 | 0 | } |
1096 | 0 | else if (! startswith (name, ".got") |
1097 | 0 | && strcmp (name, ".dynbss") != 0) |
1098 | 0 | { |
1099 | | /* It's not one of our sections, so don't allocate space. */ |
1100 | 0 | continue; |
1101 | 0 | } |
1102 | | |
1103 | 0 | if (s->size == 0) |
1104 | 0 | { |
1105 | | /* If we don't need this section, strip it from the |
1106 | | output file. This is mostly to handle .rela.bss and |
1107 | | .rela.plt. We must create both sections in |
1108 | | create_dynamic_sections, because they must be created |
1109 | | before the linker maps input sections to output |
1110 | | sections. The linker does that before |
1111 | | adjust_dynamic_symbol is called, and it is that |
1112 | | function which decides whether anything needs to go |
1113 | | into these sections. */ |
1114 | 0 | s->flags |= SEC_EXCLUDE; |
1115 | 0 | continue; |
1116 | 0 | } |
1117 | | |
1118 | 0 | if ((s->flags & SEC_HAS_CONTENTS) == 0) |
1119 | 0 | continue; |
1120 | | |
1121 | | /* Allocate memory for the section contents. */ |
1122 | 0 | s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); |
1123 | 0 | if (s->contents == NULL) |
1124 | 0 | return false; |
1125 | 0 | s->alloced = 1; |
1126 | 0 | } |
1127 | | |
1128 | 0 | return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); |
1129 | 0 | } |
1130 | | |
1131 | | /* This function is called via elf_vax_link_hash_traverse if we are |
1132 | | creating a shared object with -Bsymbolic. It discards the space |
1133 | | allocated to copy PC relative relocs against symbols which are defined |
1134 | | in regular objects. We allocated space for them in the check_relocs |
1135 | | routine, but we won't fill them in in the relocate_section routine. */ |
1136 | | |
1137 | | static bool |
1138 | | elf_vax_discard_copies (struct elf_vax_link_hash_entry *h, |
1139 | | void * ignore ATTRIBUTE_UNUSED) |
1140 | 0 | { |
1141 | 0 | struct elf_vax_pcrel_relocs_copied *s; |
1142 | | |
1143 | | /* We only discard relocs for symbols defined in a regular object. */ |
1144 | 0 | if (!h->root.def_regular) |
1145 | 0 | return true; |
1146 | | |
1147 | 0 | for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) |
1148 | 0 | s->section->size -= s->count * sizeof (Elf32_External_Rela); |
1149 | |
|
1150 | 0 | return true; |
1151 | 0 | } |
1152 | | |
1153 | | /* This function is called via elf_link_hash_traverse. It looks for |
1154 | | entries that have GOT or PLT (.GOT) references. If creating a shared |
1155 | | object with -Bsymbolic, or the symbol has been forced local, then it |
1156 | | resets the reference count back to -1 so normal PC32 relocation will |
1157 | | be done. Otherwise space in the .got and .rela.got will be reserved |
1158 | | for the symbol. */ |
1159 | | |
1160 | | static bool |
1161 | | elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr) |
1162 | 0 | { |
1163 | 0 | struct bfd_link_info *info = (struct bfd_link_info *) infoptr; |
1164 | 0 | bfd *dynobj; |
1165 | 0 | asection *sgot; |
1166 | 0 | asection *srelgot; |
1167 | | |
1168 | | /* We don't care about non-GOT (and non-PLT) entries. */ |
1169 | 0 | if (h->got.refcount <= 0 && h->plt.refcount <= 0) |
1170 | 0 | return true; |
1171 | | |
1172 | 0 | dynobj = elf_hash_table (info)->dynobj; |
1173 | 0 | BFD_ASSERT (dynobj != NULL); |
1174 | |
|
1175 | 0 | sgot = elf_hash_table (info)->sgot; |
1176 | 0 | srelgot = elf_hash_table (info)->srelgot; |
1177 | |
|
1178 | 0 | if (SYMBOL_REFERENCES_LOCAL (info, h)) |
1179 | 0 | { |
1180 | 0 | h->got.refcount = -1; |
1181 | 0 | h->plt.refcount = -1; |
1182 | 0 | } |
1183 | 0 | else if (h->got.refcount > 0) |
1184 | 0 | { |
1185 | | /* Make sure this symbol is output as a dynamic symbol. */ |
1186 | 0 | if (h->dynindx == -1) |
1187 | 0 | { |
1188 | 0 | if (!bfd_elf_link_record_dynamic_symbol (info, h)) |
1189 | 0 | return false; |
1190 | 0 | } |
1191 | | |
1192 | | /* Allocate space in the .got and .rela.got sections. */ |
1193 | 0 | sgot->size += 4; |
1194 | 0 | srelgot->size += sizeof (Elf32_External_Rela); |
1195 | 0 | } |
1196 | | |
1197 | 0 | return true; |
1198 | 0 | } |
1199 | | |
1200 | | /* Relocate an VAX ELF section. */ |
1201 | | |
1202 | | static int |
1203 | | elf_vax_relocate_section (bfd *output_bfd, |
1204 | | struct bfd_link_info *info, |
1205 | | bfd *input_bfd, |
1206 | | asection *input_section, |
1207 | | bfd_byte *contents, |
1208 | | Elf_Internal_Rela *relocs, |
1209 | | Elf_Internal_Sym *local_syms, |
1210 | | asection **local_sections) |
1211 | 0 | { |
1212 | 0 | Elf_Internal_Shdr *symtab_hdr; |
1213 | 0 | struct elf_link_hash_entry **sym_hashes; |
1214 | 0 | bfd_vma plt_index; |
1215 | 0 | bfd_vma got_offset; |
1216 | 0 | asection *sgot; |
1217 | 0 | asection *splt; |
1218 | 0 | asection *sgotplt; |
1219 | 0 | asection *sreloc; |
1220 | 0 | Elf_Internal_Rela *rel; |
1221 | 0 | Elf_Internal_Rela *relend; |
1222 | |
|
1223 | 0 | symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
1224 | 0 | sym_hashes = elf_sym_hashes (input_bfd); |
1225 | |
|
1226 | 0 | sgot = NULL; |
1227 | 0 | splt = NULL; |
1228 | 0 | sgotplt = NULL; |
1229 | 0 | sreloc = NULL; |
1230 | |
|
1231 | 0 | rel = relocs; |
1232 | 0 | relend = relocs + input_section->reloc_count; |
1233 | 0 | for (; rel < relend; rel++) |
1234 | 0 | { |
1235 | 0 | int r_type; |
1236 | 0 | reloc_howto_type *howto; |
1237 | 0 | unsigned long r_symndx; |
1238 | 0 | struct elf_link_hash_entry *h; |
1239 | 0 | Elf_Internal_Sym *sym; |
1240 | 0 | asection *sec; |
1241 | 0 | bfd_vma relocation; |
1242 | 0 | bfd_reloc_status_type r; |
1243 | |
|
1244 | 0 | r_type = ELF32_R_TYPE (rel->r_info); |
1245 | 0 | if (r_type < 0 || r_type >= (int) R_VAX_max) |
1246 | 0 | { |
1247 | 0 | bfd_set_error (bfd_error_bad_value); |
1248 | 0 | return false; |
1249 | 0 | } |
1250 | 0 | howto = howto_table + r_type; |
1251 | |
|
1252 | 0 | r_symndx = ELF32_R_SYM (rel->r_info); |
1253 | 0 | h = NULL; |
1254 | 0 | sym = NULL; |
1255 | 0 | sec = NULL; |
1256 | 0 | if (r_symndx < symtab_hdr->sh_info) |
1257 | 0 | { |
1258 | 0 | sym = local_syms + r_symndx; |
1259 | 0 | sec = local_sections[r_symndx]; |
1260 | 0 | relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
1261 | 0 | } |
1262 | 0 | else |
1263 | 0 | { |
1264 | 0 | bool unresolved_reloc; |
1265 | 0 | bool warned, ignored; |
1266 | |
|
1267 | 0 | RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
1268 | 0 | r_symndx, symtab_hdr, sym_hashes, |
1269 | 0 | h, sec, relocation, |
1270 | 0 | unresolved_reloc, warned, ignored); |
1271 | | |
1272 | 0 | if ((h->root.type == bfd_link_hash_defined |
1273 | 0 | || h->root.type == bfd_link_hash_defweak) |
1274 | 0 | && ((r_type == R_VAX_PLT32 |
1275 | 0 | && h->plt.offset != (bfd_vma) -1 |
1276 | 0 | && !h->forced_local |
1277 | 0 | && elf_hash_table (info)->dynamic_sections_created) |
1278 | 0 | || (r_type == R_VAX_GOT32 |
1279 | 0 | && h->got.offset != (bfd_vma) -1 |
1280 | 0 | && !h->forced_local |
1281 | 0 | && elf_hash_table (info)->dynamic_sections_created |
1282 | 0 | && (! bfd_link_pic (info) |
1283 | 0 | || (! info->symbolic && h->dynindx != -1) |
1284 | 0 | || !h->def_regular)) |
1285 | 0 | || (bfd_link_pic (info) |
1286 | 0 | && ((! info->symbolic && h->dynindx != -1) |
1287 | 0 | || !h->def_regular) |
1288 | 0 | && ((input_section->flags & SEC_ALLOC) != 0 |
1289 | | /* DWARF will emit R_VAX_32 relocations in its |
1290 | | sections against symbols defined externally |
1291 | | in shared libraries. We can't do anything |
1292 | | with them here. */ |
1293 | |
|
1294 | 0 | || ((input_section->flags & SEC_DEBUGGING) != 0 |
1295 | 0 | && h->def_dynamic)) |
1296 | 0 | && (r_type == R_VAX_8 |
1297 | 0 | || r_type == R_VAX_16 |
1298 | 0 | || r_type == R_VAX_32)))) |
1299 | | /* In these cases, we don't need the relocation |
1300 | | value. We check specially because in some |
1301 | | obscure cases sec->output_section will be NULL. */ |
1302 | 0 | relocation = 0; |
1303 | 0 | } |
1304 | | |
1305 | 0 | if (sec != NULL && discarded_section (sec)) |
1306 | 0 | RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
1307 | 0 | rel, 1, relend, howto, 0, contents); |
1308 | |
|
1309 | 0 | if (bfd_link_relocatable (info)) |
1310 | 0 | continue; |
1311 | | |
1312 | 0 | switch (r_type) |
1313 | 0 | { |
1314 | 0 | case R_VAX_GOT32: |
1315 | | /* Relocation is to the address of the entry for this symbol |
1316 | | in the global offset table. */ |
1317 | | |
1318 | | /* Resolve a GOTxx reloc against a local symbol directly, |
1319 | | without using the global offset table. */ |
1320 | 0 | if (h == NULL |
1321 | 0 | || h->got.offset == (bfd_vma) -1) |
1322 | 0 | break; |
1323 | | |
1324 | 0 | { |
1325 | 0 | bfd_vma off; |
1326 | |
|
1327 | 0 | sgot = elf_hash_table (info)->sgot; |
1328 | 0 | BFD_ASSERT (sgot != NULL); |
1329 | |
|
1330 | 0 | off = h->got.offset; |
1331 | 0 | BFD_ASSERT (off < sgot->size); |
1332 | |
|
1333 | 0 | bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off); |
1334 | |
|
1335 | 0 | relocation = sgot->output_offset + off; |
1336 | | /* The GOT relocation uses the addend. */ |
1337 | 0 | rel->r_addend = 0; |
1338 | | |
1339 | | /* Change the reference to be indirect. */ |
1340 | 0 | contents[rel->r_offset - 1] |= 0x10; |
1341 | 0 | relocation += sgot->output_section->vma; |
1342 | 0 | } |
1343 | 0 | break; |
1344 | | |
1345 | 0 | case R_VAX_PC32: |
1346 | | /* If we are creating an executable and the function this |
1347 | | reloc refers to is in a shared lib, then we made a PLT |
1348 | | entry for this symbol and need to handle the reloc like |
1349 | | a PLT reloc. */ |
1350 | 0 | if (bfd_link_pic (info)) |
1351 | 0 | goto r_vax_pc32_shared; |
1352 | | /* Fall through. */ |
1353 | 0 | case R_VAX_PLT32: |
1354 | | /* Relocation is to the entry for this symbol in the |
1355 | | procedure linkage table. */ |
1356 | | |
1357 | | /* Resolve a PLTxx reloc against a local symbol directly, |
1358 | | without using the procedure linkage table. */ |
1359 | 0 | if (h == NULL |
1360 | 0 | || h->plt.offset == (bfd_vma) -1) |
1361 | 0 | break; |
1362 | | |
1363 | 0 | splt = elf_hash_table (info)->splt; |
1364 | 0 | BFD_ASSERT (splt != NULL); |
1365 | |
|
1366 | 0 | sgotplt = elf_hash_table (info)->sgotplt; |
1367 | 0 | BFD_ASSERT (sgotplt != NULL); |
1368 | |
|
1369 | 0 | plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; |
1370 | | |
1371 | | /* Get the offset into the .got table of the entry that |
1372 | | corresponds to this function. Each .got entry is 4 bytes. |
1373 | | The first two are reserved. */ |
1374 | 0 | got_offset = (plt_index + 3) * 4; |
1375 | | |
1376 | | /* We want the relocation to point into the .got.plt instead |
1377 | | of the plt itself. */ |
1378 | 0 | relocation = (sgotplt->output_section->vma |
1379 | 0 | + sgotplt->output_offset |
1380 | 0 | + got_offset); |
1381 | 0 | contents[rel->r_offset-1] |= 0x10; /* make indirect */ |
1382 | 0 | if (rel->r_addend == 2) |
1383 | 0 | { |
1384 | 0 | h->plt.offset |= 1; |
1385 | 0 | } |
1386 | 0 | else if (rel->r_addend != 0) |
1387 | 0 | _bfd_error_handler |
1388 | | /* xgettext:c-format */ |
1389 | 0 | (_("%pB: warning: PLT addend of %" PRId64 " to `%s'" |
1390 | 0 | " from %pA section ignored"), |
1391 | 0 | input_bfd, (int64_t) rel->r_addend, h->root.root.string, |
1392 | 0 | input_section); |
1393 | 0 | rel->r_addend = 0; |
1394 | |
|
1395 | 0 | break; |
1396 | | |
1397 | 0 | case R_VAX_PC8: |
1398 | 0 | case R_VAX_PC16: |
1399 | 0 | r_vax_pc32_shared: |
1400 | 0 | if (h == NULL |
1401 | 0 | || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
1402 | 0 | || h->forced_local) |
1403 | 0 | break; |
1404 | | /* Fall through. */ |
1405 | 0 | case R_VAX_8: |
1406 | 0 | case R_VAX_16: |
1407 | 0 | case R_VAX_32: |
1408 | 0 | if (bfd_link_pic (info) |
1409 | 0 | && r_symndx != STN_UNDEF |
1410 | 0 | && (input_section->flags & SEC_ALLOC) != 0 |
1411 | 0 | && ((r_type != R_VAX_PC8 |
1412 | 0 | && r_type != R_VAX_PC16 |
1413 | 0 | && r_type != R_VAX_PC32) |
1414 | 0 | || ((input_section->flags & SEC_CODE) |
1415 | 0 | && (!info->symbolic |
1416 | 0 | || (!h->def_regular && h->type != STT_SECTION))))) |
1417 | 0 | { |
1418 | 0 | Elf_Internal_Rela outrel; |
1419 | 0 | bfd_byte *loc; |
1420 | 0 | bool skip, relocate; |
1421 | | |
1422 | | /* When generating a shared object, these relocations |
1423 | | are copied into the output file to be resolved at run |
1424 | | time. */ |
1425 | 0 | if (sreloc == NULL) |
1426 | 0 | { |
1427 | 0 | sreloc = _bfd_elf_get_dynamic_reloc_section |
1428 | 0 | (input_bfd, input_section, /*rela?*/ true); |
1429 | 0 | if (sreloc == NULL) |
1430 | 0 | return false; |
1431 | 0 | } |
1432 | | |
1433 | 0 | skip = false; |
1434 | 0 | relocate = false; |
1435 | |
|
1436 | 0 | outrel.r_offset = |
1437 | 0 | _bfd_elf_section_offset (output_bfd, info, input_section, |
1438 | 0 | rel->r_offset); |
1439 | 0 | if (outrel.r_offset == (bfd_vma) -1) |
1440 | 0 | skip = true; |
1441 | 0 | if (outrel.r_offset == (bfd_vma) -2) |
1442 | 0 | skip = true, relocate = true; |
1443 | 0 | outrel.r_offset += (input_section->output_section->vma |
1444 | 0 | + input_section->output_offset); |
1445 | |
|
1446 | 0 | if (skip) |
1447 | 0 | memset (&outrel, 0, sizeof outrel); |
1448 | | /* h->dynindx may be -1 if the symbol was marked to |
1449 | | become local. */ |
1450 | 0 | else if (h != NULL |
1451 | 0 | && ((! info->symbolic && h->dynindx != -1) |
1452 | 0 | || !h->def_regular)) |
1453 | 0 | { |
1454 | 0 | BFD_ASSERT (h->dynindx != -1); |
1455 | 0 | outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
1456 | 0 | outrel.r_addend = relocation + rel->r_addend; |
1457 | 0 | } |
1458 | 0 | else |
1459 | 0 | { |
1460 | 0 | if (r_type == R_VAX_32) |
1461 | 0 | { |
1462 | 0 | relocate = true; |
1463 | 0 | outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); |
1464 | 0 | BFD_ASSERT (bfd_get_signed_32 (input_bfd, |
1465 | 0 | &contents[rel->r_offset]) == 0); |
1466 | 0 | outrel.r_addend = relocation + rel->r_addend; |
1467 | 0 | } |
1468 | 0 | else |
1469 | 0 | { |
1470 | 0 | long indx; |
1471 | |
|
1472 | 0 | if (bfd_is_abs_section (sec)) |
1473 | 0 | indx = 0; |
1474 | 0 | else if (sec == NULL || sec->owner == NULL) |
1475 | 0 | { |
1476 | 0 | bfd_set_error (bfd_error_bad_value); |
1477 | 0 | return false; |
1478 | 0 | } |
1479 | 0 | else |
1480 | 0 | { |
1481 | 0 | asection *osec; |
1482 | | |
1483 | | /* We are turning this relocation into one |
1484 | | against a section symbol. It would be |
1485 | | proper to subtract the symbol's value, |
1486 | | osec->vma, from the emitted reloc addend, |
1487 | | but ld.so expects buggy relocs. */ |
1488 | 0 | osec = sec->output_section; |
1489 | 0 | indx = elf_section_data (osec)->dynindx; |
1490 | 0 | if (indx == 0) |
1491 | 0 | { |
1492 | 0 | struct elf_link_hash_table *htab; |
1493 | 0 | htab = elf_hash_table (info); |
1494 | 0 | osec = htab->text_index_section; |
1495 | 0 | indx = elf_section_data (osec)->dynindx; |
1496 | 0 | } |
1497 | 0 | BFD_ASSERT (indx != 0); |
1498 | 0 | } |
1499 | | |
1500 | 0 | outrel.r_info = ELF32_R_INFO (indx, r_type); |
1501 | 0 | outrel.r_addend = relocation + rel->r_addend; |
1502 | 0 | } |
1503 | 0 | } |
1504 | | |
1505 | 0 | if ((input_section->flags & SEC_CODE) != 0 |
1506 | 0 | || (ELF32_R_TYPE (outrel.r_info) != R_VAX_32 |
1507 | 0 | && ELF32_R_TYPE (outrel.r_info) != R_VAX_RELATIVE |
1508 | 0 | && ELF32_R_TYPE (outrel.r_info) != R_VAX_COPY |
1509 | 0 | && ELF32_R_TYPE (outrel.r_info) != R_VAX_JMP_SLOT |
1510 | 0 | && ELF32_R_TYPE (outrel.r_info) != R_VAX_GLOB_DAT)) |
1511 | 0 | { |
1512 | 0 | if (h != NULL) |
1513 | 0 | _bfd_error_handler |
1514 | | /* xgettext:c-format */ |
1515 | 0 | (_("%pB: warning: %s relocation against symbol `%s'" |
1516 | 0 | " from %pA section"), |
1517 | 0 | input_bfd, howto->name, h->root.root.string, |
1518 | 0 | input_section); |
1519 | 0 | else |
1520 | 0 | _bfd_error_handler |
1521 | | /* xgettext:c-format */ |
1522 | 0 | (_("%pB: warning: %s relocation to %#" PRIx64 |
1523 | 0 | " from %pA section"), |
1524 | 0 | input_bfd, howto->name, (uint64_t) outrel.r_addend, |
1525 | 0 | input_section); |
1526 | 0 | } |
1527 | 0 | loc = sreloc->contents; |
1528 | 0 | loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
1529 | 0 | bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
1530 | | |
1531 | | /* This reloc will be computed at runtime, so there's no |
1532 | | need to do anything now, except for R_VAX_32 |
1533 | | relocations that have been turned into |
1534 | | R_VAX_RELATIVE. */ |
1535 | 0 | if (!relocate) |
1536 | 0 | continue; |
1537 | 0 | } |
1538 | | |
1539 | 0 | break; |
1540 | | |
1541 | 0 | case R_VAX_GNU_VTINHERIT: |
1542 | 0 | case R_VAX_GNU_VTENTRY: |
1543 | | /* These are no-ops in the end. */ |
1544 | 0 | continue; |
1545 | | |
1546 | 0 | default: |
1547 | 0 | break; |
1548 | 0 | } |
1549 | | |
1550 | | /* VAX PCREL relocations are from the end of relocation, not the start. |
1551 | | So subtract the difference from the relocation amount since we can't |
1552 | | add it to the offset. */ |
1553 | 0 | if (howto->pc_relative && howto->pcrel_offset) |
1554 | 0 | relocation -= bfd_get_reloc_size(howto); |
1555 | |
|
1556 | 0 | r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
1557 | 0 | contents, rel->r_offset, |
1558 | 0 | relocation, rel->r_addend); |
1559 | |
|
1560 | 0 | if (r != bfd_reloc_ok) |
1561 | 0 | { |
1562 | 0 | switch (r) |
1563 | 0 | { |
1564 | 0 | default: |
1565 | 0 | case bfd_reloc_outofrange: |
1566 | 0 | abort (); |
1567 | 0 | case bfd_reloc_overflow: |
1568 | 0 | { |
1569 | 0 | const char *name; |
1570 | |
|
1571 | 0 | if (h != NULL) |
1572 | 0 | name = NULL; |
1573 | 0 | else |
1574 | 0 | { |
1575 | 0 | name = bfd_elf_string_from_elf_section (input_bfd, |
1576 | 0 | symtab_hdr->sh_link, |
1577 | 0 | sym->st_name); |
1578 | 0 | if (name == NULL) |
1579 | 0 | return false; |
1580 | 0 | if (*name == '\0') |
1581 | 0 | name = bfd_section_name (sec); |
1582 | 0 | } |
1583 | 0 | info->callbacks->reloc_overflow |
1584 | 0 | (info, (h ? &h->root : NULL), name, howto->name, |
1585 | 0 | (bfd_vma) 0, input_bfd, input_section, rel->r_offset); |
1586 | 0 | } |
1587 | 0 | break; |
1588 | 0 | } |
1589 | 0 | } |
1590 | 0 | } |
1591 | | |
1592 | 0 | return true; |
1593 | 0 | } |
1594 | | |
1595 | | /* Finish up dynamic symbol handling. We set the contents of various |
1596 | | dynamic sections here. */ |
1597 | | |
1598 | | static bool |
1599 | | elf_vax_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, |
1600 | | struct elf_link_hash_entry *h, |
1601 | | Elf_Internal_Sym *sym) |
1602 | 0 | { |
1603 | 0 | bfd *dynobj; |
1604 | |
|
1605 | 0 | dynobj = elf_hash_table (info)->dynobj; |
1606 | |
|
1607 | 0 | if (h->plt.offset != (bfd_vma) -1) |
1608 | 0 | { |
1609 | 0 | asection *splt; |
1610 | 0 | asection *sgot; |
1611 | 0 | asection *srela; |
1612 | 0 | bfd_vma plt_index; |
1613 | 0 | bfd_vma got_offset; |
1614 | 0 | bfd_vma addend; |
1615 | 0 | Elf_Internal_Rela rela; |
1616 | 0 | bfd_byte *loc; |
1617 | | |
1618 | | /* This symbol has an entry in the procedure linkage table. Set |
1619 | | it up. */ |
1620 | 0 | BFD_ASSERT (h->dynindx != -1); |
1621 | |
|
1622 | 0 | splt = elf_hash_table (info)->splt; |
1623 | 0 | sgot = elf_hash_table (info)->sgotplt; |
1624 | 0 | srela = elf_hash_table (info)->srelplt; |
1625 | 0 | BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); |
1626 | |
|
1627 | 0 | addend = 2 * (h->plt.offset & 1); |
1628 | 0 | h->plt.offset &= ~1; |
1629 | | |
1630 | | /* Get the index in the procedure linkage table which |
1631 | | corresponds to this symbol. This is the index of this symbol |
1632 | | in all the symbols for which we are making plt entries. The |
1633 | | first entry in the procedure linkage table is reserved. */ |
1634 | 0 | plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; |
1635 | | |
1636 | | /* Get the offset into the .got table of the entry that |
1637 | | corresponds to this function. Each .got entry is 4 bytes. |
1638 | | The first two are reserved. */ |
1639 | 0 | got_offset = (plt_index + 3) * 4; |
1640 | | |
1641 | | /* Fill in the entry in the procedure linkage table. */ |
1642 | 0 | memcpy (splt->contents + h->plt.offset, elf_vax_plt_entry, |
1643 | 0 | PLT_ENTRY_SIZE); |
1644 | | |
1645 | | /* The offset is relative to the first extension word. */ |
1646 | 0 | bfd_put_32 (output_bfd, |
1647 | 0 | -(h->plt.offset + 8), |
1648 | 0 | splt->contents + h->plt.offset + 4); |
1649 | |
|
1650 | 0 | bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), |
1651 | 0 | splt->contents + h->plt.offset + 8); |
1652 | | |
1653 | | /* Fill in the entry in the global offset table. */ |
1654 | 0 | bfd_put_32 (output_bfd, |
1655 | 0 | (splt->output_section->vma |
1656 | 0 | + splt->output_offset |
1657 | 0 | + h->plt.offset) + addend, |
1658 | 0 | sgot->contents + got_offset); |
1659 | | |
1660 | | /* Fill in the entry in the .rela.plt section. */ |
1661 | 0 | rela.r_offset = (sgot->output_section->vma |
1662 | 0 | + sgot->output_offset |
1663 | 0 | + got_offset); |
1664 | 0 | rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT); |
1665 | 0 | rela.r_addend = addend; |
1666 | 0 | loc = srela->contents + plt_index * sizeof (Elf32_External_Rela); |
1667 | 0 | bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
1668 | |
|
1669 | 0 | if (!h->def_regular) |
1670 | 0 | { |
1671 | | /* Mark the symbol as undefined, rather than as defined in |
1672 | | the .plt section. Leave the value alone. */ |
1673 | 0 | sym->st_shndx = SHN_UNDEF; |
1674 | 0 | } |
1675 | 0 | } |
1676 | |
|
1677 | 0 | if (h->got.offset != (bfd_vma) -1) |
1678 | 0 | { |
1679 | 0 | asection *sgot; |
1680 | 0 | asection *srela; |
1681 | 0 | Elf_Internal_Rela rela; |
1682 | 0 | bfd_byte *loc; |
1683 | | |
1684 | | /* This symbol has an entry in the global offset table. Set it |
1685 | | up. */ |
1686 | 0 | sgot = elf_hash_table (info)->sgot; |
1687 | 0 | srela = elf_hash_table (info)->srelgot; |
1688 | 0 | BFD_ASSERT (sgot != NULL && srela != NULL); |
1689 | |
|
1690 | 0 | rela.r_offset = (sgot->output_section->vma |
1691 | 0 | + sgot->output_offset |
1692 | 0 | + h->got.offset); |
1693 | 0 | rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT); |
1694 | 0 | rela.r_addend = bfd_get_signed_32 (output_bfd, |
1695 | 0 | sgot->contents + h->got.offset); |
1696 | |
|
1697 | 0 | loc = srela->contents; |
1698 | 0 | loc += srela->reloc_count++ * sizeof (Elf32_External_Rela); |
1699 | 0 | bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
1700 | 0 | } |
1701 | |
|
1702 | 0 | if (h->needs_copy) |
1703 | 0 | { |
1704 | 0 | asection *s; |
1705 | 0 | Elf_Internal_Rela rela; |
1706 | 0 | bfd_byte *loc; |
1707 | | |
1708 | | /* This symbol needs a copy reloc. Set it up. */ |
1709 | 0 | BFD_ASSERT (h->dynindx != -1 |
1710 | 0 | && (h->root.type == bfd_link_hash_defined |
1711 | 0 | || h->root.type == bfd_link_hash_defweak)); |
1712 | |
|
1713 | 0 | s = bfd_get_linker_section (dynobj, ".rela.bss"); |
1714 | 0 | BFD_ASSERT (s != NULL); |
1715 | |
|
1716 | 0 | rela.r_offset = (h->root.u.def.value |
1717 | 0 | + h->root.u.def.section->output_section->vma |
1718 | 0 | + h->root.u.def.section->output_offset); |
1719 | 0 | rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY); |
1720 | 0 | rela.r_addend = 0; |
1721 | 0 | loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); |
1722 | 0 | bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
1723 | 0 | } |
1724 | | |
1725 | | /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ |
1726 | 0 | if (h == elf_hash_table (info)->hdynamic |
1727 | 0 | || h == elf_hash_table (info)->hgot) |
1728 | 0 | sym->st_shndx = SHN_ABS; |
1729 | |
|
1730 | 0 | return true; |
1731 | 0 | } |
1732 | | |
1733 | | /* Finish up the dynamic sections. */ |
1734 | | |
1735 | | static bool |
1736 | | elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) |
1737 | 0 | { |
1738 | 0 | bfd *dynobj; |
1739 | 0 | asection *sgot; |
1740 | 0 | asection *sdyn; |
1741 | |
|
1742 | 0 | dynobj = elf_hash_table (info)->dynobj; |
1743 | |
|
1744 | 0 | sgot = elf_hash_table (info)->sgotplt; |
1745 | 0 | BFD_ASSERT (sgot != NULL); |
1746 | 0 | sdyn = bfd_get_linker_section (dynobj, ".dynamic"); |
1747 | |
|
1748 | 0 | if (elf_hash_table (info)->dynamic_sections_created) |
1749 | 0 | { |
1750 | 0 | asection *splt; |
1751 | 0 | Elf32_External_Dyn *dyncon, *dynconend; |
1752 | |
|
1753 | 0 | splt = elf_hash_table (info)->splt; |
1754 | 0 | BFD_ASSERT (splt != NULL && sdyn != NULL); |
1755 | |
|
1756 | 0 | dyncon = (Elf32_External_Dyn *) sdyn->contents; |
1757 | 0 | dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); |
1758 | 0 | for (; dyncon < dynconend; dyncon++) |
1759 | 0 | { |
1760 | 0 | Elf_Internal_Dyn dyn; |
1761 | 0 | asection *s; |
1762 | |
|
1763 | 0 | bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); |
1764 | |
|
1765 | 0 | switch (dyn.d_tag) |
1766 | 0 | { |
1767 | 0 | default: |
1768 | 0 | break; |
1769 | | |
1770 | 0 | case DT_PLTGOT: |
1771 | 0 | s = elf_hash_table (info)->sgotplt; |
1772 | 0 | goto get_vma; |
1773 | 0 | case DT_JMPREL: |
1774 | 0 | s = elf_hash_table (info)->srelplt; |
1775 | 0 | get_vma: |
1776 | 0 | dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; |
1777 | 0 | bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
1778 | 0 | break; |
1779 | | |
1780 | 0 | case DT_PLTRELSZ: |
1781 | 0 | s = elf_hash_table (info)->srelplt; |
1782 | 0 | dyn.d_un.d_val = s->size; |
1783 | 0 | bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
1784 | 0 | break; |
1785 | 0 | } |
1786 | 0 | } |
1787 | | |
1788 | | /* Fill in the first entry in the procedure linkage table. */ |
1789 | 0 | if (splt->size > 0) |
1790 | 0 | { |
1791 | 0 | memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE); |
1792 | 0 | bfd_put_32 (output_bfd, |
1793 | 0 | (sgot->output_section->vma |
1794 | 0 | + sgot->output_offset + 4 |
1795 | 0 | - (splt->output_section->vma + 6)), |
1796 | 0 | splt->contents + 2); |
1797 | 0 | bfd_put_32 (output_bfd, |
1798 | 0 | (sgot->output_section->vma |
1799 | 0 | + sgot->output_offset + 8 |
1800 | 0 | - (splt->output_section->vma + 12)), |
1801 | 0 | splt->contents + 8); |
1802 | 0 | elf_section_data (splt->output_section)->this_hdr.sh_entsize |
1803 | 0 | = PLT_ENTRY_SIZE; |
1804 | 0 | } |
1805 | 0 | } |
1806 | | |
1807 | | /* Fill in the first three entries in the global offset table. */ |
1808 | 0 | if (sgot->size > 0) |
1809 | 0 | { |
1810 | 0 | if (sdyn == NULL) |
1811 | 0 | bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); |
1812 | 0 | else |
1813 | 0 | bfd_put_32 (output_bfd, |
1814 | 0 | sdyn->output_section->vma + sdyn->output_offset, |
1815 | 0 | sgot->contents); |
1816 | 0 | bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); |
1817 | 0 | bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); |
1818 | 0 | } |
1819 | |
|
1820 | 0 | if (elf_section_data (sgot->output_section) != NULL) |
1821 | 0 | elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; |
1822 | |
|
1823 | 0 | return true; |
1824 | 0 | } |
1825 | | |
1826 | | static enum elf_reloc_type_class |
1827 | | elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, |
1828 | | const asection *rel_sec ATTRIBUTE_UNUSED, |
1829 | | const Elf_Internal_Rela *rela) |
1830 | 0 | { |
1831 | 0 | switch ((int) ELF32_R_TYPE (rela->r_info)) |
1832 | 0 | { |
1833 | 0 | case R_VAX_RELATIVE: |
1834 | 0 | return reloc_class_relative; |
1835 | 0 | case R_VAX_JMP_SLOT: |
1836 | 0 | return reloc_class_plt; |
1837 | 0 | case R_VAX_COPY: |
1838 | 0 | return reloc_class_copy; |
1839 | 0 | default: |
1840 | 0 | return reloc_class_normal; |
1841 | 0 | } |
1842 | 0 | } |
1843 | | |
1844 | | static bfd_vma |
1845 | | elf_vax_plt_sym_val (bfd_vma i, const asection *plt, |
1846 | | const arelent *rel ATTRIBUTE_UNUSED) |
1847 | 0 | { |
1848 | 0 | return plt->vma + (i + 1) * PLT_ENTRY_SIZE; |
1849 | 0 | } |
1850 | | |
1851 | | #define TARGET_LITTLE_SYM vax_elf32_vec |
1852 | | #define TARGET_LITTLE_NAME "elf32-vax" |
1853 | | #define ELF_TARGET_ID VAX_ELF_DATA |
1854 | | #define ELF_MACHINE_CODE EM_VAX |
1855 | | #define ELF_MAXPAGESIZE 0x1000 |
1856 | | |
1857 | | #define elf_backend_create_dynamic_sections \ |
1858 | | _bfd_elf_create_dynamic_sections |
1859 | | #define bfd_elf32_bfd_link_hash_table_create \ |
1860 | | elf_vax_link_hash_table_create |
1861 | | #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link |
1862 | | |
1863 | | #define elf_backend_check_relocs elf_vax_check_relocs |
1864 | | #define elf_backend_adjust_dynamic_symbol \ |
1865 | | elf_vax_adjust_dynamic_symbol |
1866 | | #define elf_backend_early_size_sections elf_vax_early_size_sections |
1867 | | #define elf_backend_late_size_sections elf_vax_late_size_sections |
1868 | | #define elf_backend_init_index_section _bfd_elf_init_1_index_section |
1869 | | #define elf_backend_relocate_section elf_vax_relocate_section |
1870 | | #define elf_backend_finish_dynamic_symbol \ |
1871 | | elf_vax_finish_dynamic_symbol |
1872 | | #define elf_backend_finish_dynamic_sections \ |
1873 | | elf_vax_finish_dynamic_sections |
1874 | | #define elf_backend_reloc_type_class elf_vax_reloc_type_class |
1875 | | #define elf_backend_gc_mark_hook elf_vax_gc_mark_hook |
1876 | | #define elf_backend_plt_sym_val elf_vax_plt_sym_val |
1877 | | #define bfd_elf32_bfd_merge_private_bfd_data \ |
1878 | | elf32_vax_merge_private_bfd_data |
1879 | | #define bfd_elf32_bfd_set_private_flags \ |
1880 | | elf32_vax_set_private_flags |
1881 | | #define bfd_elf32_bfd_print_private_bfd_data \ |
1882 | | elf32_vax_print_private_bfd_data |
1883 | | |
1884 | | #define elf_backend_can_gc_sections 1 |
1885 | | #define elf_backend_want_got_plt 1 |
1886 | | #define elf_backend_plt_readonly 1 |
1887 | | #define elf_backend_want_plt_sym 0 |
1888 | | #define elf_backend_got_header_size 16 |
1889 | | #define elf_backend_rela_normal 1 |
1890 | | #define elf_backend_dtrel_excludes_plt 1 |
1891 | | |
1892 | | #include "elf32-target.h" |